diff --git a/FoxTube/FoxTube.csproj b/FoxTube/FoxTube.csproj
index 6dfeecd..0cb2d89 100644
--- a/FoxTube/FoxTube.csproj
+++ b/FoxTube/FoxTube.csproj
@@ -305,6 +305,9 @@
3.0.0
+
+ 2.5.16
+
4.3.1
diff --git a/FoxTube/MainPage.xaml.cs b/FoxTube/MainPage.xaml.cs
index 3bc7d6c..329d4c6 100644
--- a/FoxTube/MainPage.xaml.cs
+++ b/FoxTube/MainPage.xaml.cs
@@ -249,11 +249,11 @@ namespace FoxTube
}
else if (topHamburger.SelectedIndex == 1)
{
- content.Navigate(typeof(Video));
+ /*content.Navigate(typeof(Video));
headerText.Text = "Video";
menu.DisplayMode = SplitViewDisplayMode.CompactOverlay;
menu.IsPaneOpen = false;
- isForcedCollapsed = true;
+ isForcedCollapsed = true;*/
}
else if (bottomHaburger.SelectedIndex == 4)
{
@@ -386,7 +386,7 @@ namespace FoxTube
XmlDocument doc = new XmlDocument();
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++)
@@ -590,6 +590,17 @@ namespace FoxTube
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)
{
if(isForcedCollapsed)
diff --git a/FoxTube/PlaylistCardWide.xaml.cs b/FoxTube/PlaylistCardWide.xaml.cs
index f96b800..52fd9b7 100644
--- a/FoxTube/PlaylistCardWide.xaml.cs
+++ b/FoxTube/PlaylistCardWide.xaml.cs
@@ -27,7 +27,8 @@ namespace FoxTube
{
public sealed partial class PlaylistCardWide : UserControl
{
- public string channelId;
+ public string playlistId;
+ Playlist item;
public PlaylistCardWide(string id, bool hideAuthor = false)
{
this.InitializeComponent();
@@ -36,19 +37,13 @@ namespace FoxTube
public async void Initialize(string id, bool hideAuthor)
{
- YouTubeService ytService = new YouTubeService(new BaseClientService.Initializer()
- {
- ApiKey = "AIzaSyBgHrCnrlzlVmk0cJKL8RqP9Y8x6XSuk_0",
- ApplicationName = this.GetType().ToString()
- });
-
- PlaylistsResource.ListRequest request = ytService.Playlists.List("snippet,contentDetails");
+ PlaylistsResource.ListRequest request = SecretsVault.YoutubeService.Playlists.List("snippet,contentDetails");
request.Id = id;
PlaylistListResponse response = await request.ExecuteAsync();
- var item = response.Items[0];
+ item = response.Items[0];
- channelId = id;
+ playlistId = id;
title.Text = item.Snippet.Title;
info.Text = string.Format("{0} | {1} videos", item.Snippet.PublishedAt, item.ContentDetails.ItemCount);
@@ -59,7 +54,7 @@ namespace FoxTube
authorData.Visibility = Visibility.Collapsed;
else
{
- var request1 = ytService.Channels.List("snippet,contentDetails,statistics");
+ var request1 = SecretsVault.YoutubeService.Channels.List("snippet,contentDetails,statistics");
request1.Id = item.Snippet.ChannelId;
ChannelListResponse response1 = await request1.ExecuteAsync();
@@ -74,8 +69,7 @@ namespace FoxTube
private void channelLink_Click(object sender, RoutedEventArgs e)
{
- MainPage root = Window.Current.Content as MainPage;
- root.GoToChannel(channelId);
+ ((Window.Current.Content as Frame).Content as MainPage).GoToChannel(item.Snippet.ChannelId);
}
}
}
diff --git a/FoxTube/Settings.xaml b/FoxTube/Settings.xaml
index 224ace8..3ccfe8f 100644
--- a/FoxTube/Settings.xaml
+++ b/FoxTube/Settings.xaml
@@ -35,10 +35,8 @@
-
-
-
-
+
+
diff --git a/FoxTube/Video.xaml b/FoxTube/Video.xaml
index 3ecf5c6..bf3a0e0 100644
--- a/FoxTube/Video.xaml
+++ b/FoxTube/Video.xaml
@@ -12,18 +12,13 @@
-
-
-
-
+
+
+
-
+
-
-
-
-
-
-
+
-
-
+
+
diff --git a/FoxTube/Video.xaml.cs b/FoxTube/Video.xaml.cs
index 065815c..22ddd60 100644
--- a/FoxTube/Video.xaml.cs
+++ b/FoxTube/Video.xaml.cs
@@ -13,6 +13,10 @@ using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
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
namespace FoxTube
@@ -22,15 +26,47 @@ namespace FoxTube
///
public sealed partial class Video : Page
{
+ string videoId;
+ Google.Apis.YouTube.v3.Data.Video item;
+
public Video()
{
this.InitializeComponent();
}
- public void Load(string url, string title,
- string author, string avatarUrl)
+ public async void Initialize(string id)
{
+ 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);
}
}
}
diff --git a/FoxTube/VideoCard.xaml b/FoxTube/VideoCard.xaml
index 8a52291..4dbc881 100644
--- a/FoxTube/VideoCard.xaml
+++ b/FoxTube/VideoCard.xaml
@@ -12,7 +12,7 @@
d:DesignHeight="290"
d:DesignWidth="384">
-
+
diff --git a/FoxTube/VideoCard.xaml.cs b/FoxTube/VideoCard.xaml.cs
index 99d63f4..73386f6 100644
--- a/FoxTube/VideoCard.xaml.cs
+++ b/FoxTube/VideoCard.xaml.cs
@@ -26,7 +26,8 @@ namespace FoxTube
{
public sealed partial class VideoCard : UserControl
{
- public string channeId;
+ public string videoId;
+ Google.Apis.YouTube.v3.Data.Video item;
public VideoCard(string id)
{
this.InitializeComponent();
@@ -46,16 +47,16 @@ namespace FoxTube
request.Id = id;
VideoListResponse response = await request.ExecuteAsync();
- var item = response.Items[0];
+ item = response.Items[0];
- channeId = id;
+ videoId = id;
title.Text = item.Snippet.Title;
views.Text = string.Format("{0} views", item.Statistics.ViewCount);
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));
if (item.Snippet.LiveBroadcastContent == "live")
liveTag.Visibility = Visibility.Visible;
@@ -69,5 +70,10 @@ namespace FoxTube
avatar.ProfilePicture = new BitmapImage(new Uri(item1.Snippet.Thumbnails.Medium.Url));
channelName.Text = item1.Snippet.Title;
}
+
+ private void Button_Click(object sender, RoutedEventArgs e)
+ {
+ ((Window.Current.Content as Frame).Content as MainPage).GoToVideo(videoId);
+ }
}
}
diff --git a/FoxTube/VideoCardWide.xaml b/FoxTube/VideoCardWide.xaml
index 04dea04..5a5b8dd 100644
--- a/FoxTube/VideoCardWide.xaml
+++ b/FoxTube/VideoCardWide.xaml
@@ -9,7 +9,7 @@
HorizontalAlignment="Stretch"
Height="175">
-
+
diff --git a/FoxTube/VideoCardWide.xaml.cs b/FoxTube/VideoCardWide.xaml.cs
index 1437220..8d30f6f 100644
--- a/FoxTube/VideoCardWide.xaml.cs
+++ b/FoxTube/VideoCardWide.xaml.cs
@@ -28,7 +28,8 @@ namespace FoxTube
{
public sealed partial class VideoCardWide : UserControl
{
- public string channeId;
+ public string videoId;
+ Google.Apis.YouTube.v3.Data.Video item;
public VideoCardWide(string id)
{
this.InitializeComponent();
@@ -43,15 +44,15 @@ namespace FoxTube
request.Id = id;
VideoListResponse response = await request.ExecuteAsync();
- var item = response.Items[0];
+ item = response.Items[0];
- channeId = id;
+ videoId = id;
title.Text = item.Snippet.Title;
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));
if (item.Snippet.LiveBroadcastContent == "live")
liveTag.Visibility = Visibility.Visible;
@@ -69,8 +70,12 @@ namespace FoxTube
private void channelLink_Click(object sender, RoutedEventArgs e)
{
- MainPage root = Window.Current.Content as MainPage;
- root.GoToChannel(channeId);
+ ((Window.Current.Content as Frame).Content as MainPage).GoToChannel(item.Snippet.ChannelId);
+ }
+
+ private void Button_Click(object sender, RoutedEventArgs e)
+ {
+ ((Window.Current.Content as Frame).Content as MainPage).GoToVideo(videoId);
}
}
}
diff --git a/FoxTube/VideoPlayer.xaml b/FoxTube/VideoPlayer.xaml
index 8fac4ac..6017f80 100644
--- a/FoxTube/VideoPlayer.xaml
+++ b/FoxTube/VideoPlayer.xaml
@@ -13,7 +13,7 @@
PointerMoved="UserControl_PointerMoved">
-
+
@@ -57,6 +57,7 @@
+
@@ -64,8 +65,8 @@
-
-
+
+
@@ -75,25 +76,25 @@
-
-
-
+
+
+
-
-
+
+
-
+
-
-
+
+
@@ -101,15 +102,11 @@
-
+
-
-
-
-
-
-
-
+
+
+
diff --git a/FoxTube/VideoPlayer.xaml.cs b/FoxTube/VideoPlayer.xaml.cs
index eb33ff0..9d901ae 100644
--- a/FoxTube/VideoPlayer.xaml.cs
+++ b/FoxTube/VideoPlayer.xaml.cs
@@ -20,6 +20,7 @@ using Microsoft.Toolkit.Uwp.UI.Animations;
using Google.Apis.YouTube.v3.Data;
using Google.Apis.YouTube.v3;
using Windows.UI.Xaml.Media.Imaging;
+using MyToolkit.Multimedia;
// 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 string videoId;
+
+ YouTubeQuality videoQuality;
+
ApplicationDataContainer settings = ApplicationData.Current.LocalSettings;
Timer t = new Timer()
{
@@ -35,12 +39,17 @@ namespace FoxTube
Enabled = true
};
- public VideoPlayer()
+ public VideoPlayer(string id)
{
this.InitializeComponent();
volume.Value = Convert.ToDouble(settings.Values["volume"]);
+
+ quality.SelectedIndex = (int)settings.Values["quality"] +
+ (int)settings.Values["quality"] > 0? 1 : 0;
+
t.Elapsed += T_Elapsed;
+ Initialize(id);
}
public async void Initialize(string id)
@@ -54,7 +63,9 @@ namespace FoxTube
var item = response.Items[0];
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)
@@ -99,6 +110,8 @@ namespace FoxTube
muteBtn.Content = openVolume.Content = "";
settings.Values["volume"] = volume.Value;
+
+ videoSource.Volume = volume.Value;
}
private void openSets_Click(object sender, RoutedEventArgs e)
@@ -133,8 +146,7 @@ namespace FoxTube
private void UserControl_PointerMoved(object sender, PointerRoutedEventArgs e)
{
- if(!volumePane.IsOpen && !qualityPane.IsOpen)
- ShowControls();
+ ShowControls();
}
async void ShowControls()
@@ -147,5 +159,99 @@ namespace FoxTube
t.Stop();
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;
+ }
+ }
}
}