Added functional video page & player
This commit is contained in:
@@ -305,6 +305,9 @@
|
|||||||
<PackageReference Include="Microsoft.Toolkit.Uwp.UI.Controls">
|
<PackageReference Include="Microsoft.Toolkit.Uwp.UI.Controls">
|
||||||
<Version>3.0.0</Version>
|
<Version>3.0.0</Version>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
<PackageReference Include="MyToolkit.Extended">
|
||||||
|
<Version>2.5.16</Version>
|
||||||
|
</PackageReference>
|
||||||
<PackageReference Include="runtime.win10-arm64.runtime.native.System.IO.Compression">
|
<PackageReference Include="runtime.win10-arm64.runtime.native.System.IO.Compression">
|
||||||
<Version>4.3.1</Version>
|
<Version>4.3.1</Version>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
|||||||
@@ -249,11 +249,11 @@ namespace FoxTube
|
|||||||
}
|
}
|
||||||
else if (topHamburger.SelectedIndex == 1)
|
else if (topHamburger.SelectedIndex == 1)
|
||||||
{
|
{
|
||||||
content.Navigate(typeof(Video));
|
/*content.Navigate(typeof(Video));
|
||||||
headerText.Text = "Video";
|
headerText.Text = "Video";
|
||||||
menu.DisplayMode = SplitViewDisplayMode.CompactOverlay;
|
menu.DisplayMode = SplitViewDisplayMode.CompactOverlay;
|
||||||
menu.IsPaneOpen = false;
|
menu.IsPaneOpen = false;
|
||||||
isForcedCollapsed = true;
|
isForcedCollapsed = true;*/
|
||||||
}
|
}
|
||||||
else if (bottomHaburger.SelectedIndex == 4)
|
else if (bottomHaburger.SelectedIndex == 4)
|
||||||
{
|
{
|
||||||
@@ -386,7 +386,7 @@ namespace FoxTube
|
|||||||
XmlDocument doc = new XmlDocument();
|
XmlDocument doc = new XmlDocument();
|
||||||
await Task.Run(() =>
|
await Task.Run(() =>
|
||||||
{
|
{
|
||||||
doc.Load(string.Format("http://suggestqueries.google.com/complete/search?output=toolbar&hl={0}&q={1}", (settings.Values["region"] as string)[1] + (settings.Values["region"] as string)[2], keyword));
|
doc.Load(string.Format("http://suggestqueries.google.com/complete/search?output=toolbar&hl={0}&q={1}", (settings.Values["region"] as string)[0] + (settings.Values["region"] as string)[1], keyword));
|
||||||
});
|
});
|
||||||
|
|
||||||
for (int k = 0; k < 5; k++)
|
for (int k = 0; k < 5; k++)
|
||||||
@@ -590,6 +590,17 @@ namespace FoxTube
|
|||||||
page.Initialize(id);
|
page.Initialize(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void GoToVideo(string id)
|
||||||
|
{
|
||||||
|
headerText.Text = "Video";
|
||||||
|
menu.DisplayMode = SplitViewDisplayMode.CompactOverlay;
|
||||||
|
menu.IsPaneOpen = false;
|
||||||
|
isForcedCollapsed = true;
|
||||||
|
|
||||||
|
content.Navigate(typeof(Video));
|
||||||
|
(content.Content as Video).Initialize(id);
|
||||||
|
}
|
||||||
|
|
||||||
private void Page_SizeChanged(object sender, SizeChangedEventArgs e)
|
private void Page_SizeChanged(object sender, SizeChangedEventArgs e)
|
||||||
{
|
{
|
||||||
if(isForcedCollapsed)
|
if(isForcedCollapsed)
|
||||||
|
|||||||
@@ -27,7 +27,8 @@ namespace FoxTube
|
|||||||
{
|
{
|
||||||
public sealed partial class PlaylistCardWide : UserControl
|
public sealed partial class PlaylistCardWide : UserControl
|
||||||
{
|
{
|
||||||
public string channelId;
|
public string playlistId;
|
||||||
|
Playlist item;
|
||||||
public PlaylistCardWide(string id, bool hideAuthor = false)
|
public PlaylistCardWide(string id, bool hideAuthor = false)
|
||||||
{
|
{
|
||||||
this.InitializeComponent();
|
this.InitializeComponent();
|
||||||
@@ -36,19 +37,13 @@ namespace FoxTube
|
|||||||
|
|
||||||
public async void Initialize(string id, bool hideAuthor)
|
public async void Initialize(string id, bool hideAuthor)
|
||||||
{
|
{
|
||||||
YouTubeService ytService = new YouTubeService(new BaseClientService.Initializer()
|
PlaylistsResource.ListRequest request = SecretsVault.YoutubeService.Playlists.List("snippet,contentDetails");
|
||||||
{
|
|
||||||
ApiKey = "AIzaSyBgHrCnrlzlVmk0cJKL8RqP9Y8x6XSuk_0",
|
|
||||||
ApplicationName = this.GetType().ToString()
|
|
||||||
});
|
|
||||||
|
|
||||||
PlaylistsResource.ListRequest request = ytService.Playlists.List("snippet,contentDetails");
|
|
||||||
request.Id = id;
|
request.Id = id;
|
||||||
PlaylistListResponse response = await request.ExecuteAsync();
|
PlaylistListResponse response = await request.ExecuteAsync();
|
||||||
|
|
||||||
var item = response.Items[0];
|
item = response.Items[0];
|
||||||
|
|
||||||
channelId = id;
|
playlistId = id;
|
||||||
|
|
||||||
title.Text = item.Snippet.Title;
|
title.Text = item.Snippet.Title;
|
||||||
info.Text = string.Format("{0} | {1} videos", item.Snippet.PublishedAt, item.ContentDetails.ItemCount);
|
info.Text = string.Format("{0} | {1} videos", item.Snippet.PublishedAt, item.ContentDetails.ItemCount);
|
||||||
@@ -59,7 +54,7 @@ namespace FoxTube
|
|||||||
authorData.Visibility = Visibility.Collapsed;
|
authorData.Visibility = Visibility.Collapsed;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var request1 = ytService.Channels.List("snippet,contentDetails,statistics");
|
var request1 = SecretsVault.YoutubeService.Channels.List("snippet,contentDetails,statistics");
|
||||||
request1.Id = item.Snippet.ChannelId;
|
request1.Id = item.Snippet.ChannelId;
|
||||||
ChannelListResponse response1 = await request1.ExecuteAsync();
|
ChannelListResponse response1 = await request1.ExecuteAsync();
|
||||||
|
|
||||||
@@ -74,8 +69,7 @@ namespace FoxTube
|
|||||||
|
|
||||||
private void channelLink_Click(object sender, RoutedEventArgs e)
|
private void channelLink_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
MainPage root = Window.Current.Content as MainPage;
|
((Window.Current.Content as Frame).Content as MainPage).GoToChannel(item.Snippet.ChannelId);
|
||||||
root.GoToChannel(channelId);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,10 +35,8 @@
|
|||||||
<TextBlock Text="Playback" FontSize="22"/>
|
<TextBlock Text="Playback" FontSize="22"/>
|
||||||
<ComboBox Margin="0,0,0,10" Width="250" Header="Default video playback quality" Name="quality" SelectionChanged="quality_SelectionChanged">
|
<ComboBox Margin="0,0,0,10" Width="250" Header="Default video playback quality" Name="quality" SelectionChanged="quality_SelectionChanged">
|
||||||
<ComboBoxItem Content="Auto"/>
|
<ComboBoxItem Content="Auto"/>
|
||||||
<ComboBoxItem Content="1080p60"/>
|
<ComboBoxItem Content="1080p"/>
|
||||||
<ComboBoxItem Content="1080p30"/>
|
<ComboBoxItem Content="720p"/>
|
||||||
<ComboBoxItem Content="720p60"/>
|
|
||||||
<ComboBoxItem Content="720p30"/>
|
|
||||||
<ComboBoxItem Content="480p"/>
|
<ComboBoxItem Content="480p"/>
|
||||||
<ComboBoxItem Content="360p"/>
|
<ComboBoxItem Content="360p"/>
|
||||||
<ComboBoxItem Content="240p"/>
|
<ComboBoxItem Content="240p"/>
|
||||||
|
|||||||
+20
-35
@@ -12,18 +12,13 @@
|
|||||||
<ColumnDefinition Width="3*"/>
|
<ColumnDefinition Width="3*"/>
|
||||||
<ColumnDefinition Width="*"/>
|
<ColumnDefinition Width="*"/>
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<StackPanel Orientation="Vertical">
|
|
||||||
<!--<StackPanel Height="600" Background="Black"/>-->
|
|
||||||
<local:VideoPlayer/>
|
|
||||||
<ScrollViewer>
|
<ScrollViewer>
|
||||||
|
<StackPanel Orientation="Vertical" Name="mainContent">
|
||||||
|
<!--<local:VideoPlayer Name="player"/>-->
|
||||||
<StackPanel Margin="10">
|
<StackPanel Margin="10">
|
||||||
<TextBlock Text="Video title this is very biiiiig title. It's amazingly big. OLOLOLOLOLO!!!!!!)))))). 1234567890. ABCD" FontSize="25" TextWrapping="WrapWholeWords" HorizontalTextAlignment="Start"/>
|
<TextBlock Name="title" Text="Video title this is very biiiiig title. It's amazingly big. OLOLOLOLOLO!!!!!!)))))). 1234567890. ABCD" FontSize="25" TextWrapping="WrapWholeWords" HorizontalTextAlignment="Start"/>
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.ColumnDefinitions>
|
<Button Padding="0" Background="Transparent" Margin="5" Name="gotoChannel" Click="gotoChannel_Click">
|
||||||
<ColumnDefinition/>
|
|
||||||
<ColumnDefinition/>
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
<Button Padding="0" Background="Transparent" Margin="5">
|
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<PersonPicture Name="channelAvatar" Width="90"/>
|
<PersonPicture Name="channelAvatar" Width="90"/>
|
||||||
<StackPanel Orientation="Vertical" Grid.Column="1" Padding="5" VerticalAlignment="Center">
|
<StackPanel Orientation="Vertical" Grid.Column="1" Padding="5" VerticalAlignment="Center">
|
||||||
@@ -31,44 +26,34 @@
|
|||||||
<TextBlock Name="channelName" Text="IGP" FontSize="18"/>
|
<TextBlock Name="channelName" Text="IGP" FontSize="18"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<TextBlock Name="subscribers" Text="120,452 subscribers" Foreground="Gray"/>
|
<TextBlock Name="subscribers" Text="120,452 subscribers" Foreground="Gray"/>
|
||||||
<StackPanel Orientation="Horizontal" Margin="0,5,0,0">
|
<StackPanel Name="subscribePanel" Orientation="Horizontal" Margin="0,5,0,0">
|
||||||
<ToggleButton Grid.Column="2" Height="30" Width="150" Background="Red" Foreground="White" FontSize="14" FontWeight="SemiBold" Content="Subscirbe"/>
|
<ToggleButton Grid.Column="2" Height="30" Width="150" Background="Red" Foreground="White" FontSize="14" FontWeight="SemiBold" Content="Subscirbe"/>
|
||||||
<ToggleButton Grid.Column="3" Height="30" Width="30" Padding="0" FontFamily="Segoe MDL2 Assets" FontSize="14" FontWeight="SemiBold" Content="" Foreground="White" Background="Red"/>
|
<ToggleButton Grid.Column="3" Height="30" Width="30" Padding="0" FontFamily="Segoe MDL2 Assets" FontSize="14" FontWeight="SemiBold" Content="" Foreground="White" Background="Red"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Button>
|
</Button>
|
||||||
<StackPanel HorizontalAlignment="Right" Grid.Column="1">
|
<StackPanel HorizontalAlignment="Right">
|
||||||
<StackPanel Orientation="Horizontal">
|
<TextBlock Name="views" Text="10,000,000 views" FontSize="24" Foreground="Gray"/>
|
||||||
<TextBlock Text="10,000,000" FontSize="24" Foreground="Gray"/>
|
<RelativePanel>
|
||||||
<TextBlock Text=" views" FontSize="24" Foreground="Gray"/>
|
|
||||||
</StackPanel>
|
|
||||||
<Grid>
|
|
||||||
<Line Stroke="Green" StrokeThickness="5" X1="0" X2="250" Y1="0" Y2="0"/>
|
<Line Stroke="Green" StrokeThickness="5" X1="0" X2="250" Y1="0" Y2="0"/>
|
||||||
<Line Stroke="Red" StrokeThickness="5" X1="0" X2="100" Y1="0" Y2="0"/>
|
<Line Name="dislikeLine" Stroke="Red" StrokeThickness="5" X1="0" X2="100" Y1="0" Y2="0"/>
|
||||||
</Grid>
|
</RelativePanel>
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.ColumnDefinitions>
|
<StackPanel>
|
||||||
<ColumnDefinition Width="45"/>
|
<Button Background="Transparent" Padding="0" Content="" FontFamily="Segoe MDL2 Assets" Foreground="Gray" FontSize="40" Name="dislike"/>
|
||||||
<ColumnDefinition/>
|
<TextBlock Foreground="Gray" Text="10923" Name="dislikes"/>
|
||||||
<ColumnDefinition Width="45"/>
|
</StackPanel>
|
||||||
</Grid.ColumnDefinitions>
|
<StackPanel HorizontalAlignment="Right">
|
||||||
<Button Grid.Column="0" Background="Transparent" Padding="0" Content="" FontFamily="Segoe MDL2 Assets" Foreground="Gray" FontSize="40"/>
|
<Button Background="Transparent" Padding="0" Content="" FontFamily="Segoe MDL2 Assets" Foreground="Gray" FontSize="40" Name="like"/>
|
||||||
<Button Grid.Column="2" Background="Transparent" Padding="0" Content="" FontFamily="Segoe MDL2 Assets" Foreground="Gray" FontSize="40"/>
|
<TextBlock Foreground="Gray" Text="10923" Name="likes"/>
|
||||||
</Grid>
|
</StackPanel>
|
||||||
<Grid>
|
|
||||||
<Grid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition/>
|
|
||||||
<ColumnDefinition/>
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
<TextBlock Foreground="Gray" Text="10923"/>
|
|
||||||
<TextBlock HorizontalAlignment="Right" Grid.Column="1" Foreground="Gray" Text="10923"/>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
<TextBlock TextWrapping="WrapWholeWords" Text="description"/>
|
<TextBlock Name="description" IsTextSelectionEnabled="True" TextWrapping="WrapWholeWords" Text="description"/>
|
||||||
|
</StackPanel>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
</StackPanel>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</Page>
|
</Page>
|
||||||
|
|||||||
+38
-2
@@ -13,6 +13,10 @@ using Windows.UI.Xaml.Input;
|
|||||||
using Windows.UI.Xaml.Media;
|
using Windows.UI.Xaml.Media;
|
||||||
using Windows.UI.Xaml.Navigation;
|
using Windows.UI.Xaml.Navigation;
|
||||||
|
|
||||||
|
using Google.Apis.YouTube.v3.Data;
|
||||||
|
using Google.Apis.YouTube.v3;
|
||||||
|
using Windows.UI.Xaml.Media.Imaging;
|
||||||
|
|
||||||
// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238
|
// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238
|
||||||
|
|
||||||
namespace FoxTube
|
namespace FoxTube
|
||||||
@@ -22,15 +26,47 @@ namespace FoxTube
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed partial class Video : Page
|
public sealed partial class Video : Page
|
||||||
{
|
{
|
||||||
|
string videoId;
|
||||||
|
Google.Apis.YouTube.v3.Data.Video item;
|
||||||
|
|
||||||
public Video()
|
public Video()
|
||||||
{
|
{
|
||||||
this.InitializeComponent();
|
this.InitializeComponent();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Load(string url, string title,
|
public async void Initialize(string id)
|
||||||
string author, string avatarUrl)
|
|
||||||
{
|
{
|
||||||
|
videoId = id;
|
||||||
|
VideosResource.ListRequest request = SecretsVault.YoutubeService.Videos.List("snippet,contentDetails,statistics");
|
||||||
|
request.Id = id;
|
||||||
|
|
||||||
|
VideoListResponse response = await request.ExecuteAsync();
|
||||||
|
item = response.Items[0];
|
||||||
|
|
||||||
|
title.Text = item.Snippet.Title;
|
||||||
|
views.Text = item.Statistics.ViewCount + " views";
|
||||||
|
dislikes.Text = item.Statistics.DislikeCount.ToString();
|
||||||
|
likes.Text = item.Statistics.LikeCount.ToString();
|
||||||
|
dislikeLine.X2 = (int)(item.Statistics.DislikeCount / (item.Statistics.DislikeCount + item.Statistics.LikeCount) * 250);
|
||||||
|
description.Text = item.Snippet.Description;
|
||||||
|
|
||||||
|
ChannelsResource.ListRequest request1 = SecretsVault.YoutubeService.Channels.List("snippet,contentDetails,statistics");
|
||||||
|
request1.Id = item.Snippet.ChannelId;
|
||||||
|
|
||||||
|
ChannelListResponse response1 = await request1.ExecuteAsync();
|
||||||
|
var item1 = response1.Items[0];
|
||||||
|
|
||||||
|
channelAvatar.ProfilePicture = new BitmapImage(new Uri(item1.Snippet.Thumbnails.Medium.Url));
|
||||||
|
channelName.Text = item.Snippet.ChannelTitle;
|
||||||
|
subscribers.Text = item1.Statistics.SubscriberCount + " subscribers";
|
||||||
|
|
||||||
|
mainContent.Children.Add(new VideoPlayer(id));
|
||||||
|
mainContent.Children.Reverse();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void gotoChannel_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
(Window.Current.Content as MainPage).GoToChannel(item.Snippet.ChannelId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
d:DesignHeight="290"
|
d:DesignHeight="290"
|
||||||
d:DesignWidth="384">
|
d:DesignWidth="384">
|
||||||
|
|
||||||
<Button Padding="0" Background="Transparent" VerticalAlignment="Top">
|
<Button Padding="0" Background="Transparent" VerticalAlignment="Top" Click="Button_Click">
|
||||||
<Grid Background="WhiteSmoke" BorderBrush="LightGray" BorderThickness="1">
|
<Grid Background="WhiteSmoke" BorderBrush="LightGray" BorderThickness="1">
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="*"/>
|
<RowDefinition Height="*"/>
|
||||||
|
|||||||
@@ -26,7 +26,8 @@ namespace FoxTube
|
|||||||
{
|
{
|
||||||
public sealed partial class VideoCard : UserControl
|
public sealed partial class VideoCard : UserControl
|
||||||
{
|
{
|
||||||
public string channeId;
|
public string videoId;
|
||||||
|
Google.Apis.YouTube.v3.Data.Video item;
|
||||||
public VideoCard(string id)
|
public VideoCard(string id)
|
||||||
{
|
{
|
||||||
this.InitializeComponent();
|
this.InitializeComponent();
|
||||||
@@ -46,16 +47,16 @@ namespace FoxTube
|
|||||||
request.Id = id;
|
request.Id = id;
|
||||||
VideoListResponse response = await request.ExecuteAsync();
|
VideoListResponse response = await request.ExecuteAsync();
|
||||||
|
|
||||||
var item = response.Items[0];
|
item = response.Items[0];
|
||||||
|
|
||||||
channeId = id;
|
videoId = id;
|
||||||
|
|
||||||
title.Text = item.Snippet.Title;
|
title.Text = item.Snippet.Title;
|
||||||
views.Text = string.Format("{0} views", item.Statistics.ViewCount);
|
views.Text = string.Format("{0} views", item.Statistics.ViewCount);
|
||||||
|
|
||||||
TimeSpan duration = XmlConvert.ToTimeSpan(item.ContentDetails.Duration);
|
TimeSpan duration = XmlConvert.ToTimeSpan(item.ContentDetails.Duration);
|
||||||
|
|
||||||
info.Text = string.Format("{0}:{1}:{2} | {3}", duration.Hours, duration.Minutes, duration.Seconds, item.Snippet.PublishedAt);
|
info.Text = string.Format("{0}{1:00}:{2:00} | {3}", duration.Hours == 0? "" : duration.Hours + ":", duration.Minutes, duration.Seconds, item.Snippet.PublishedAt);
|
||||||
thumbnail.Source = new BitmapImage(new Uri(item.Snippet.Thumbnails.Medium.Url));
|
thumbnail.Source = new BitmapImage(new Uri(item.Snippet.Thumbnails.Medium.Url));
|
||||||
if (item.Snippet.LiveBroadcastContent == "live")
|
if (item.Snippet.LiveBroadcastContent == "live")
|
||||||
liveTag.Visibility = Visibility.Visible;
|
liveTag.Visibility = Visibility.Visible;
|
||||||
@@ -69,5 +70,10 @@ namespace FoxTube
|
|||||||
avatar.ProfilePicture = new BitmapImage(new Uri(item1.Snippet.Thumbnails.Medium.Url));
|
avatar.ProfilePicture = new BitmapImage(new Uri(item1.Snippet.Thumbnails.Medium.Url));
|
||||||
channelName.Text = item1.Snippet.Title;
|
channelName.Text = item1.Snippet.Title;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void Button_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
((Window.Current.Content as Frame).Content as MainPage).GoToVideo(videoId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
Height="175">
|
Height="175">
|
||||||
|
|
||||||
<Button Padding="0" Background="WhiteSmoke" HorizontalAlignment="Stretch" HorizontalContentAlignment="Left" Margin="2">
|
<Button Padding="0" Background="WhiteSmoke" HorizontalAlignment="Stretch" HorizontalContentAlignment="Left" Margin="2" Click="Button_Click">
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<Image Name="thumbnail" Source="Assets/videoThumbSample.png"/>
|
<Image Name="thumbnail" Source="Assets/videoThumbSample.png"/>
|
||||||
<Grid Margin="10" HorizontalAlignment="Stretch">
|
<Grid Margin="10" HorizontalAlignment="Stretch">
|
||||||
|
|||||||
@@ -28,7 +28,8 @@ namespace FoxTube
|
|||||||
{
|
{
|
||||||
public sealed partial class VideoCardWide : UserControl
|
public sealed partial class VideoCardWide : UserControl
|
||||||
{
|
{
|
||||||
public string channeId;
|
public string videoId;
|
||||||
|
Google.Apis.YouTube.v3.Data.Video item;
|
||||||
public VideoCardWide(string id)
|
public VideoCardWide(string id)
|
||||||
{
|
{
|
||||||
this.InitializeComponent();
|
this.InitializeComponent();
|
||||||
@@ -43,15 +44,15 @@ namespace FoxTube
|
|||||||
request.Id = id;
|
request.Id = id;
|
||||||
VideoListResponse response = await request.ExecuteAsync();
|
VideoListResponse response = await request.ExecuteAsync();
|
||||||
|
|
||||||
var item = response.Items[0];
|
item = response.Items[0];
|
||||||
|
|
||||||
channeId = id;
|
videoId = id;
|
||||||
|
|
||||||
title.Text = item.Snippet.Title;
|
title.Text = item.Snippet.Title;
|
||||||
|
|
||||||
TimeSpan duration = XmlConvert.ToTimeSpan(item.ContentDetails.Duration);
|
TimeSpan duration = XmlConvert.ToTimeSpan(item.ContentDetails.Duration);
|
||||||
|
|
||||||
info.Text = string.Format("{0}:{1}:{2} | {3} | {4} views", duration.Hours, duration.Minutes, duration.Seconds, item.ContentDetails.Duration, item.Snippet.PublishedAt, item.Statistics.ViewCount);
|
info.Text = string.Format("{0}{1:00}:{2:00} | {3} | {4} views", duration.Hours == 0 ? "" : duration.Hours + ":", duration.Minutes, duration.Seconds, item.Snippet.PublishedAt, item.Statistics.ViewCount);
|
||||||
thumbnail.Source = new BitmapImage(new Uri(item.Snippet.Thumbnails.Medium.Url));
|
thumbnail.Source = new BitmapImage(new Uri(item.Snippet.Thumbnails.Medium.Url));
|
||||||
if (item.Snippet.LiveBroadcastContent == "live")
|
if (item.Snippet.LiveBroadcastContent == "live")
|
||||||
liveTag.Visibility = Visibility.Visible;
|
liveTag.Visibility = Visibility.Visible;
|
||||||
@@ -69,8 +70,12 @@ namespace FoxTube
|
|||||||
|
|
||||||
private void channelLink_Click(object sender, RoutedEventArgs e)
|
private void channelLink_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
MainPage root = Window.Current.Content as MainPage;
|
((Window.Current.Content as Frame).Content as MainPage).GoToChannel(item.Snippet.ChannelId);
|
||||||
root.GoToChannel(channeId);
|
}
|
||||||
|
|
||||||
|
private void Button_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
((Window.Current.Content as Frame).Content as MainPage).GoToVideo(videoId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-19
@@ -13,7 +13,7 @@
|
|||||||
PointerMoved="UserControl_PointerMoved">
|
PointerMoved="UserControl_PointerMoved">
|
||||||
|
|
||||||
<Grid Background="White">
|
<Grid Background="White">
|
||||||
<MediaElement AutoPlay="False" Name="videoSource" AreTransportControlsEnabled="False" PosterSource="ms-appx:///Assets/videoThumbSample.png"/>
|
<MediaElement CurrentStateChanged="videoSource_CurrentStateChanged" AutoPlay="False" Name="videoSource" AreTransportControlsEnabled="False" PosterSource="ms-appx:///Assets/videoThumbSample.png"/>
|
||||||
<TextBox Name="subtitleCapture" Visibility="Collapsed" Text="This is subtitle capture" Background="#99000000" VerticalAlignment="Bottom" HorizontalAlignment="Center" Foreground="White" FontSize="24" Padding="10" Margin="0,0,0,100"/>
|
<TextBox Name="subtitleCapture" Visibility="Collapsed" Text="This is subtitle capture" Background="#99000000" VerticalAlignment="Bottom" HorizontalAlignment="Center" Foreground="White" FontSize="24" Padding="10" Margin="0,0,0,100"/>
|
||||||
<Grid Name="controls" Visibility="Visible">
|
<Grid Name="controls" Visibility="Visible">
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
@@ -57,6 +57,7 @@
|
|||||||
<RowDefinition/>
|
<RowDefinition/>
|
||||||
<RowDefinition/>
|
<RowDefinition/>
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
|
<ProgressBar Name="bufferingBar" VerticalAlignment="Bottom" IsIndeterminate="True" Visibility="Collapsed"/>
|
||||||
<Grid Grid.Row="1">
|
<Grid Grid.Row="1">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="150"/>
|
<ColumnDefinition Width="150"/>
|
||||||
@@ -64,8 +65,8 @@
|
|||||||
<ColumnDefinition Width="252"/>
|
<ColumnDefinition Width="252"/>
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<Button Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="" Foreground="White" Width="50" Height="50" FontSize="25" ToolTipService.ToolTip="Play"/>
|
<Button Click="play_Click" Name="play" Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="" Foreground="White" Width="50" Height="50" FontSize="25" ToolTipService.ToolTip="Play"/>
|
||||||
<Button Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="" Foreground="White" Width="50" Height="50" FontSize="25" ToolTipService.ToolTip="Next video"/>
|
<Button Name="next" Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="" Foreground="White" Width="50" Height="50" FontSize="25" ToolTipService.ToolTip="Next video"/>
|
||||||
<Button Name="openVolume" Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="" Foreground="White" Width="50" Height="50" FontSize="25" ToolTipService.ToolTip="Volume" Click="openVolume_Click"/>
|
<Button Name="openVolume" Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="" Foreground="White" Width="50" Height="50" FontSize="25" ToolTipService.ToolTip="Volume" Click="openVolume_Click"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<Popup Grid.Column="0" Margin="100,-200,50,0" IsOpen="False" IsLightDismissEnabled="True" Name="volumePane">
|
<Popup Grid.Column="0" Margin="100,-200,50,0" IsOpen="False" IsLightDismissEnabled="True" Name="volumePane">
|
||||||
@@ -75,25 +76,25 @@
|
|||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Popup>
|
</Popup>
|
||||||
|
|
||||||
<TextBlock Foreground="White" Text="18:28" VerticalAlignment="Bottom" Grid.Column="1" HorizontalAlignment="Left" Margin="10,0,10,0" ToolTipService.ToolTip="Time elapsed"/>
|
<TextBlock Name="elapsedTime" Foreground="White" Text="18:28" VerticalAlignment="Bottom" Grid.Column="1" HorizontalAlignment="Left" Margin="10,0,10,0" ToolTipService.ToolTip="Time elapsed"/>
|
||||||
<TextBlock Foreground="White" Text="18:28" VerticalAlignment="Bottom" Grid.Column="1" HorizontalAlignment="Right" Margin="10,0,10,0" ToolTipService.ToolTip="Time remaining"/>
|
<TextBlock Name="remainingTime" Foreground="White" Text="18:28" VerticalAlignment="Bottom" Grid.Column="1" HorizontalAlignment="Right" Margin="10,0,10,0" ToolTipService.ToolTip="Time remaining"/>
|
||||||
<Slider Grid.Column="1" VerticalAlignment="Top" Margin="10,0,10,0" ToolTipService.ToolTip="Seek" IsThumbToolTipEnabled="False"/>
|
<Slider Name="seek" Grid.Column="1" VerticalAlignment="Top" Margin="10,0,10,0" ToolTipService.ToolTip="Seek" IsThumbToolTipEnabled="False"/>
|
||||||
|
|
||||||
<StackPanel Grid.Column="2" Orientation="Horizontal">
|
<StackPanel Grid.Column="2" Orientation="Horizontal">
|
||||||
<Button Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="" Foreground="White" Width="50" Height="50" FontSize="25" ToolTipService.ToolTip="Skip back for 10 seconds"/>
|
<Button Name="back10" Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="" Foreground="White" Width="50" Height="50" FontSize="25" ToolTipService.ToolTip="Skip back for 10 seconds"/>
|
||||||
<Button Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="" Foreground="White" Width="50" Height="50" FontSize="25" ToolTipService.ToolTip="Skip forward for 30 seconds"/>
|
<Button Name="fwd30" Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="" Foreground="White" Width="50" Height="50" FontSize="25" ToolTipService.ToolTip="Skip forward for 30 seconds"/>
|
||||||
|
|
||||||
<Line Stroke="White" StrokeThickness="2" Y1="5" Y2="45"/>
|
<Line Stroke="White" StrokeThickness="2" Y1="5" Y2="45"/>
|
||||||
|
|
||||||
<Button Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="" Foreground="White" Width="50" Height="50" FontSize="25" ToolTipService.ToolTip="Subtitles" Name="openSubs" Click="openSubs_Click"/>
|
<Button Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="" Foreground="White" Width="50" Height="50" FontSize="25" ToolTipService.ToolTip="Subtitles" Name="openSubs" Click="openSubs_Click"/>
|
||||||
<Button Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="" Foreground="White" Width="50" Height="50" FontSize="25" ToolTipService.ToolTip="Video quality" Name="openSets" Click="openSets_Click"/>
|
<Button Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="" Foreground="White" Width="50" Height="50" FontSize="25" ToolTipService.ToolTip="Video quality" Name="openSets" Click="openSets_Click"/>
|
||||||
<Button Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="" Foreground="White" Width="50" Height="50" FontSize="25" ToolTipService.ToolTip="Full screen"/>
|
<Button Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="" Foreground="White" Width="50" Height="50" FontSize="25" ToolTipService.ToolTip="Full screen" Name="fullscreen" Click="fullscreen_Click"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<Popup Grid.Column="2" Margin="0,-100,50,0" IsOpen="False" IsLightDismissEnabled="True" Name="subsPane">
|
<Popup Grid.Column="2" Margin="0,-100,50,0" IsOpen="False" IsLightDismissEnabled="True" Name="subsPane">
|
||||||
<StackPanel Background="#7F000000" Width="252" Height="100" Padding="10">
|
<StackPanel Background="#7F000000" Width="252" Height="100" Padding="10">
|
||||||
<ToggleSwitch Name="subsSwitch" Foreground="White" OffContent="Show subtitles" OnContent="Show subtitles"/>
|
<ToggleSwitch Name="subsSwitch" Toggled="subsSwitch_Toggled" Foreground="White" OffContent="Show subtitles" OnContent="Show subtitles"/>
|
||||||
<ComboBox Width="232" PlaceholderText="No subtitles are available"/>
|
<ComboBox Name="subsLang" Width="232" PlaceholderText="No subtitles are available"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Popup>
|
</Popup>
|
||||||
|
|
||||||
@@ -101,15 +102,11 @@
|
|||||||
<StackPanel Background="#7F000000" Width="252" Padding="10">
|
<StackPanel Background="#7F000000" Width="252" Padding="10">
|
||||||
<TextBlock Text="Quality" Foreground="White"/>
|
<TextBlock Text="Quality" Foreground="White"/>
|
||||||
<Line X1="0" X2="232" Stroke="White" StrokeThickness="2"/>
|
<Line X1="0" X2="232" Stroke="White" StrokeThickness="2"/>
|
||||||
<ComboBox Width="232">
|
<ComboBox Width="232" Name="quality" SelectionChanged="quality_SelectionChanged">
|
||||||
<ComboBoxItem Content="Auto"/>
|
<ComboBoxItem Content="Auto"/>
|
||||||
<ComboBoxItem Content="4320p"/>
|
<ComboBoxItem Content="2160P"/>
|
||||||
<ComboBoxItem Content="2160p"/>
|
<ComboBoxItem Content="1080p"/>
|
||||||
<ComboBoxItem Content="1440p"/>
|
<ComboBoxItem Content="720p"/>
|
||||||
<ComboBoxItem Content="1080p60"/>
|
|
||||||
<ComboBoxItem Content="1080p30"/>
|
|
||||||
<ComboBoxItem Content="720p60"/>
|
|
||||||
<ComboBoxItem Content="720p30"/>
|
|
||||||
<ComboBoxItem Content="480p"/>
|
<ComboBoxItem Content="480p"/>
|
||||||
<ComboBoxItem Content="360p"/>
|
<ComboBoxItem Content="360p"/>
|
||||||
<ComboBoxItem Content="240p"/>
|
<ComboBoxItem Content="240p"/>
|
||||||
|
|||||||
+109
-3
@@ -20,6 +20,7 @@ using Microsoft.Toolkit.Uwp.UI.Animations;
|
|||||||
using Google.Apis.YouTube.v3.Data;
|
using Google.Apis.YouTube.v3.Data;
|
||||||
using Google.Apis.YouTube.v3;
|
using Google.Apis.YouTube.v3;
|
||||||
using Windows.UI.Xaml.Media.Imaging;
|
using Windows.UI.Xaml.Media.Imaging;
|
||||||
|
using MyToolkit.Multimedia;
|
||||||
|
|
||||||
// The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236
|
// The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236
|
||||||
|
|
||||||
@@ -28,6 +29,9 @@ namespace FoxTube
|
|||||||
public sealed partial class VideoPlayer : UserControl
|
public sealed partial class VideoPlayer : UserControl
|
||||||
{
|
{
|
||||||
public string videoId;
|
public string videoId;
|
||||||
|
|
||||||
|
YouTubeQuality videoQuality;
|
||||||
|
|
||||||
ApplicationDataContainer settings = ApplicationData.Current.LocalSettings;
|
ApplicationDataContainer settings = ApplicationData.Current.LocalSettings;
|
||||||
Timer t = new Timer()
|
Timer t = new Timer()
|
||||||
{
|
{
|
||||||
@@ -35,12 +39,17 @@ namespace FoxTube
|
|||||||
Enabled = true
|
Enabled = true
|
||||||
};
|
};
|
||||||
|
|
||||||
public VideoPlayer()
|
public VideoPlayer(string id)
|
||||||
{
|
{
|
||||||
this.InitializeComponent();
|
this.InitializeComponent();
|
||||||
|
|
||||||
volume.Value = Convert.ToDouble(settings.Values["volume"]);
|
volume.Value = Convert.ToDouble(settings.Values["volume"]);
|
||||||
|
|
||||||
|
quality.SelectedIndex = (int)settings.Values["quality"] +
|
||||||
|
(int)settings.Values["quality"] > 0? 1 : 0;
|
||||||
|
|
||||||
t.Elapsed += T_Elapsed;
|
t.Elapsed += T_Elapsed;
|
||||||
|
Initialize(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async void Initialize(string id)
|
public async void Initialize(string id)
|
||||||
@@ -54,7 +63,9 @@ namespace FoxTube
|
|||||||
var item = response.Items[0];
|
var item = response.Items[0];
|
||||||
|
|
||||||
videoSource.PosterSource = new BitmapImage(new Uri(item.Snippet.Thumbnails.Maxres.Url));
|
videoSource.PosterSource = new BitmapImage(new Uri(item.Snippet.Thumbnails.Maxres.Url));
|
||||||
//videoSource.Source = new Uri(item.FileDetails.)
|
|
||||||
|
YouTubeUri url = await YouTube.GetVideoUriAsync(item.Id, videoQuality);
|
||||||
|
videoSource.Source = url.Uri;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void T_Elapsed(object sender, ElapsedEventArgs e)
|
private async void T_Elapsed(object sender, ElapsedEventArgs e)
|
||||||
@@ -99,6 +110,8 @@ namespace FoxTube
|
|||||||
muteBtn.Content = openVolume.Content = "";
|
muteBtn.Content = openVolume.Content = "";
|
||||||
|
|
||||||
settings.Values["volume"] = volume.Value;
|
settings.Values["volume"] = volume.Value;
|
||||||
|
|
||||||
|
videoSource.Volume = volume.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void openSets_Click(object sender, RoutedEventArgs e)
|
private void openSets_Click(object sender, RoutedEventArgs e)
|
||||||
@@ -133,7 +146,6 @@ namespace FoxTube
|
|||||||
|
|
||||||
private void UserControl_PointerMoved(object sender, PointerRoutedEventArgs e)
|
private void UserControl_PointerMoved(object sender, PointerRoutedEventArgs e)
|
||||||
{
|
{
|
||||||
if(!volumePane.IsOpen && !qualityPane.IsOpen)
|
|
||||||
ShowControls();
|
ShowControls();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,5 +159,99 @@ namespace FoxTube
|
|||||||
t.Stop();
|
t.Stop();
|
||||||
t.Start();
|
t.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async void quality_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||||
|
{
|
||||||
|
switch(quality.SelectedIndex)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
videoQuality = YouTubeQuality.QualityHigh;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
videoQuality = YouTubeQuality.Quality2160P;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
videoQuality = YouTubeQuality.Quality1080P;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
videoQuality = YouTubeQuality.Quality270P;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
videoQuality = YouTubeQuality.Quality480P;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 5:
|
||||||
|
videoQuality = YouTubeQuality.Quality360P;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 6:
|
||||||
|
videoQuality = YouTubeQuality.Quality240P;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 7:
|
||||||
|
videoQuality = YouTubeQuality.Quality144P;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(videoId != null)
|
||||||
|
{
|
||||||
|
videoSource.Pause();
|
||||||
|
TimeSpan timecode = videoSource.Position;
|
||||||
|
|
||||||
|
YouTubeUri url = await YouTube.GetVideoUriAsync(videoId, videoQuality);
|
||||||
|
videoSource.Source = url.Uri;
|
||||||
|
|
||||||
|
videoSource.Position = timecode;
|
||||||
|
videoSource.Play();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void subsSwitch_Toggled(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fullscreen_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void play_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (videoSource.CurrentState == MediaElementState.Playing)
|
||||||
|
videoSource.Pause();
|
||||||
|
else if (videoSource.CurrentState == MediaElementState.Paused)
|
||||||
|
videoSource.Play();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void videoSource_CurrentStateChanged(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
switch(videoSource.CurrentState)
|
||||||
|
{
|
||||||
|
case MediaElementState.Buffering:
|
||||||
|
bufferingBar.Visibility = Visibility.Visible;
|
||||||
|
seek.IsEnabled = false;
|
||||||
|
play.IsEnabled = false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MediaElementState.Paused:
|
||||||
|
bufferingBar.Visibility = Visibility.Collapsed;
|
||||||
|
play.Content = "";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MediaElementState.Playing:
|
||||||
|
bufferingBar.Visibility = Visibility.Collapsed;
|
||||||
|
play.Content = "";
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
bufferingBar.Visibility = Visibility.Collapsed;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user