Archived
1
0
This commit is contained in:
Michael Gordeev
2018-12-16 00:04:08 +03:00
parent 0dd6513257
commit da99cca0c4
6 changed files with 198 additions and 168 deletions
+1 -10
View File
@@ -1,6 +1,4 @@
using Google.Apis.YouTube.v3; using Google.Apis.YouTube.v3.Data;
using Google.Apis.YouTube.v3.Data;
using Newtonsoft.Json;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
@@ -9,13 +7,11 @@ using System.Linq;
using Windows.ApplicationModel; using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation; using Windows.ApplicationModel.Activation;
using Windows.ApplicationModel.Background; using Windows.ApplicationModel.Background;
using Windows.ApplicationModel.Core;
using Windows.Globalization; using Windows.Globalization;
using Windows.Storage; using Windows.Storage;
using Windows.System; using Windows.System;
using Windows.System.Power; using Windows.System.Power;
using Windows.UI.Notifications; using Windows.UI.Notifications;
using Windows.UI.Popups;
using Windows.UI.Xaml; using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation; using Windows.UI.Xaml.Navigation;
@@ -81,11 +77,6 @@ namespace FoxTube
rootFrame.NavigationFailed += OnNavigationFailed; rootFrame.NavigationFailed += OnNavigationFailed;
if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
//TODO: Load state from previously suspended application
}
// Place the frame in the current Window // Place the frame in the current Window
Window.Current.Content = rootFrame; Window.Current.Content = rootFrame;
} }
+1 -1
View File
@@ -44,7 +44,7 @@
</Button> </Button>
</StackPanel> </StackPanel>
<StackPanel Name="progressPanel" Grid.Column="4" Margin="10"> <StackPanel Name="progressPanel" Grid.Column="4" Margin="10">
<TextBlock Name="status" Text="Initializing..." HorizontalAlignment="Left"/> <TextBlock Name="status" Text="Downloading..." HorizontalAlignment="Left"/>
<ProgressBar Name="progressBar" Width="200" Maximum="1" IsIndeterminate="True" Foreground="Red"/> <ProgressBar Name="progressBar" Width="200" Maximum="1" IsIndeterminate="True" Foreground="Red"/>
<TextBlock Name="perc" Text="--%"/> <TextBlock Name="perc" Text="--%"/>
<Button Content="Cancel" Name="cancel" Click="CancelPrompt" HorizontalAlignment="Right"/> <Button Content="Cancel" Name="cancel" Click="CancelPrompt" HorizontalAlignment="Right"/>
+58 -49
View File
@@ -33,6 +33,9 @@ namespace FoxTube.Controls
Progress<double> progress = new Progress<double>(); Progress<double> progress = new Progress<double>();
NotificationData data = new NotificationData(); NotificationData data = new NotificationData();
DispatcherTimer timer = new DispatcherTimer() { Interval = TimeSpan.FromSeconds(1) };
double percentage;
public DownloadItem(MediaStreamInfo info, Video meta, string q) public DownloadItem(MediaStreamInfo info, Video meta, string q)
{ {
this.InitializeComponent(); this.InitializeComponent();
@@ -71,24 +74,27 @@ namespace FoxTube.Controls
donePanel.Visibility = Visibility.Visible; donePanel.Visibility = Visibility.Visible;
} }
async Task Download(MediaStreamInfo info, Video meta, string q) async void Download(MediaStreamInfo info, Video meta, string q)
{ {
InProgress = true; try
Container = new DownloadItemContainer();
token = cts.Token;
progress.ProgressChanged += UpdateInfo;
file = await DownloadAgent.Downloads.CreateFileAsync($"{meta.Snippet.Title.ReplaceInvalidChars('_')}.{info.Container.GetFileExtension()}", CreationCollisionOption.GenerateUniqueName);
Container.Name = file.Name;
ToastContent toastContent = new ToastContent()
{ {
Visual = new ToastVisual() InProgress = true;
Container = new DownloadItemContainer();
token = cts.Token;
progress.ProgressChanged += (s, e) => percentage = e;
timer.Tick += (s, e) => UpdateInfo(percentage);
file = await DownloadAgent.Downloads.CreateFileAsync($"{meta.Snippet.Title.ReplaceInvalidChars('_')}.{info.Container.GetFileExtension()}", CreationCollisionOption.GenerateUniqueName);
Container.Name = file.Name;
ToastContent toastContent = new ToastContent()
{ {
BindingGeneric = new ToastBindingGeneric() Visual = new ToastVisual()
{ {
Children = BindingGeneric = new ToastBindingGeneric()
{
Children =
{ {
new AdaptiveText() { Text = "Downloading a video" }, new AdaptiveText() { Text = "Downloading a video" },
new AdaptiveProgressBar() new AdaptiveProgressBar()
@@ -98,59 +104,62 @@ namespace FoxTube.Controls
Value = new BindableProgressBarValue("value") Value = new BindableProgressBarValue("value")
} }
} }
} }
}, },
Actions = new ToastActionsCustom() Actions = new ToastActionsCustom()
{ {
Buttons = Buttons =
{ {
new ToastButton("Cancel", $"dcancel|{Container.Id}") new ToastButton("Cancel", $"dcancel|{Container.Id}")
{ {
ActivationType = ToastActivationType.Background ActivationType = ToastActivationType.Background
} }
} }
}, },
Launch = "download", Launch = "download",
ActivationType = ToastActivationType.Foreground ActivationType = ToastActivationType.Foreground
}; };
data.Values["value"] = "0"; data.Values["value"] = "0";
ToastNotificationManager.CreateToastNotifier().Show(new ToastNotification(toastContent.GetXml()) { Tag = $"download|{meta.Id}", Data = data }); ToastNotificationManager.CreateToastNotifier().Show(new ToastNotification(toastContent.GetXml()) { Tag = $"download|{meta.Id}", Data = data });
Container.Channel = meta.Snippet.ChannelTitle; Container.Channel = meta.Snippet.ChannelTitle;
Container.Duration = XmlConvert.ToTimeSpan(meta.ContentDetails.Duration); Container.Duration = XmlConvert.ToTimeSpan(meta.ContentDetails.Duration);
Container.Id = meta.Id; Container.Id = meta.Id;
Container.Quality = q; Container.Quality = q;
Container.Thumbnail = meta.Snippet.Thumbnails.Medium.Url.ToUri(); Container.Thumbnail = meta.Snippet.Thumbnails.Medium.Url.ToUri();
Container.Title = meta.Snippet.Title; Container.Title = meta.Snippet.Title;
Container.Extension = info.Container.GetFileExtension(); Container.Extension = info.Container.GetFileExtension();
thumbnail.Source = new BitmapImage(new Uri(meta.Snippet.Thumbnails.Medium.Url)); thumbnail.Source = new BitmapImage(new Uri(meta.Snippet.Thumbnails.Medium.Url));
title.Text = meta.Snippet.Title; title.Text = meta.Snippet.Title;
ext.Text = $"Extension: {info.Container.GetFileExtension()}"; ext.Text = $"Extension: {info.Container.GetFileExtension()}";
quality.Text = $"Quality: {q}"; quality.Text = $"Quality: {q}";
duration.Text = $"Duration: {XmlConvert.ToTimeSpan(meta.ContentDetails.Duration)}"; duration.Text = $"Duration: {XmlConvert.ToTimeSpan(meta.ContentDetails.Duration)}";
channel.Text = $"Author: {meta.Snippet.ChannelTitle}"; channel.Text = $"Author: {meta.Snippet.ChannelTitle}";
path.Text = file.Name; path.Text = file.Name;
progressPanel.Visibility = Visibility.Visible; progressPanel.Visibility = Visibility.Visible;
donePanel.Visibility = Visibility.Collapsed; donePanel.Visibility = Visibility.Collapsed;
await client.DownloadMediaStreamAsync(info, await file.OpenStreamForWriteAsync(), progress, token); timer.Start();
progressPanel.Visibility = Visibility.Collapsed; await client.DownloadMediaStreamAsync(info, await file.OpenStreamForWriteAsync(), progress, token);
donePanel.Visibility = Visibility.Visible;
InProgress = false; progressPanel.Visibility = Visibility.Collapsed;
donePanel.Visibility = Visibility.Visible;
if(!cts.IsCancellationRequested) InProgress = false;
DownloadCompleted();
if (!cts.IsCancellationRequested)
DownloadCompleted();
}
catch (TaskCanceledException) { }
} }
private void UpdateInfo(object sender, double e) private void UpdateInfo(double e)
{ {
status.Text = "Downloading";
progressBar.Value = e; progressBar.Value = e;
perc.Text = $"{(int)e * 100}%"; perc.Text = $"{(int)e * 100}%";
+8
View File
@@ -168,5 +168,13 @@
<Button Name="signin" Click="signin_Click" Content="Sign in now" Foreground="White" Background="Gray" HorizontalAlignment="Right" Grid.Column="1" Margin="0,0,10,0"/> <Button Name="signin" Click="signin_Click" Content="Sign in now" Foreground="White" Background="Gray" HorizontalAlignment="Right" Grid.Column="1" Margin="0,0,10,0"/>
</Grid> </Grid>
</Grid> </Grid>
<Grid Background="#E5000000" Visibility="Collapsed">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Name="errorPlate">
<TextBlock Text="Something went wrong..." HorizontalAlignment="Center" FontSize="20"/>
<TextBlock Text="Video ID: " HorizontalAlignment="Center" IsTextSelectionEnabled="True" FontSize="20"/>
<TextBlock Text="Error type: " HorizontalAlignment="Center" IsTextSelectionEnabled="True" FontSize="20"/>
<TextBlock Text="Message: " HorizontalAlignment="Center" IsTextSelectionEnabled="True" FontSize="20"/>
</StackPanel>
</Grid>
</Grid> </Grid>
</UserControl> </UserControl>
+105 -90
View File
@@ -113,101 +113,116 @@ namespace FoxTube
public async void Initialize(Video meta, string channelAvatar) public async void Initialize(Video meta, string channelAvatar)
{ {
item = meta; try
avatar = channelAvatar;
videoId = item.Id;
#region Retrieving info for CC and Media streams
//Loading streams
streamInfo = await new YoutubeClient().GetVideoMediaStreamInfosAsync(videoId);
streamInfo.Audio.ToList().ForEach(x => Debug.WriteLine($"{x.AudioEncoding} {x.Bitrate}"));
List<VideoQuality> q = streamInfo.GetAllVideoQualities().ToList();
q.Sort();
q.Reverse();
foreach (VideoQuality i in q)
quality.Items.Add(new ComboBoxItem() { Content = i.GetVideoQualityLabel() });
string s;
if ((string)settings.Values["quality"] == "remember")
s = (string)settings.Values["rememberedQuality"];
else
s = (string)settings.Values["quality"];
if (quality.Items.ToList().Exists(x => (x as ComboBoxItem).Content as string == s))
quality.SelectedItem = quality.Items.First(x => (x as ComboBoxItem).Content as string == s);
else
quality.SelectedItem = quality.Items.First();
//Loading captions
ccInfo = await new YoutubeClient().GetVideoClosedCaptionTrackInfosAsync(item.Id);
foreach (ClosedCaptionTrackInfo cc in ccInfo)
{ {
subsLang.Items.Add(new ComboBoxItem() item = meta;
{ avatar = channelAvatar;
Content = string.Format("{0}{1}", CultureInfo.GetCultureInfo(cc.Language.Code).DisplayName, cc.IsAutoGenerated ? " (Auto-generated)" : ""), videoId = item.Id;
Tag = cc
});
}
if(ccInfo.Count > 0)
subsLang.SelectedIndex = 0;
else
captionsBtn.Visibility = Visibility.Collapsed;
#endregion
if (item.ContentDetails.ContentRating != null) #region Retrieving info for CC and Media streams
//Loading streams
streamInfo = await new YoutubeClient().GetVideoMediaStreamInfosAsync(videoId);
streamInfo.Audio.ToList().ForEach(x => Debug.WriteLine($"{x.AudioEncoding} {x.Bitrate}"));
List<VideoQuality> q = streamInfo.GetAllVideoQualities().ToList();
q.Sort();
q.Reverse();
foreach (VideoQuality i in q)
quality.Items.Add(new ComboBoxItem() { Content = i.GetVideoQualityLabel() });
string s;
if ((string)settings.Values["quality"] == "remember")
s = (string)settings.Values["rememberedQuality"];
else
s = (string)settings.Values["quality"];
if (quality.Items.ToList().Exists(x => (x as ComboBoxItem).Content as string == s))
quality.SelectedItem = quality.Items.First(x => (x as ComboBoxItem).Content as string == s);
else
quality.SelectedItem = quality.Items.First();
//Loading captions
ccInfo = await new YoutubeClient().GetVideoClosedCaptionTrackInfosAsync(item.Id);
foreach (ClosedCaptionTrackInfo cc in ccInfo)
{
subsLang.Items.Add(new ComboBoxItem()
{
Content = string.Format("{0}{1}", CultureInfo.GetCultureInfo(cc.Language.Code).DisplayName, cc.IsAutoGenerated ? " (Auto-generated)" : ""),
Tag = cc
});
}
if (ccInfo.Count > 0)
subsLang.SelectedIndex = 0;
else
captionsBtn.Visibility = Visibility.Collapsed;
#endregion
if (item.ContentDetails.ContentRating != null)
{
if (SecretsVault.IsAuthorized && settings.Values["showMature"] != null)
{
Visibility = Visibility.Visible;
proceedMature.Visibility = Visibility.Visible;
matureBlock.Visibility = Visibility.Visible;
return;
}
else if (!SecretsVault.IsAuthorized)
{
Visibility = Visibility.Visible;
signReq.Visibility = Visibility.Visible;
matureBlock.Visibility = Visibility.Visible;
return;
}
}
try { videoSource.PosterSource = new BitmapImage(new Uri(item.Snippet.Thumbnails.Maxres.Url)); }
catch { }
title.Text = item.Snippet.Title;
channelName.Text = item.Snippet.ChannelTitle;
quality_SelectionChanged(this, null);
total = XmlConvert.ToTimeSpan(item.ContentDetails.Duration);
seek.Maximum = total.TotalSeconds;
seekIndicator.Maximum = total.TotalSeconds;
elapsed = TimeSpan.FromSeconds(seek.Value);
remaining = total.Subtract(elapsed);
elapsedTime.Text = elapsed.Hours > 0 ? $"{elapsed.Hours}:00:" : "" + $"{elapsed:mm\\:ss}";
remainingTime.Text = remaining.Hours > 0 ? $"{remaining.Hours}:00:" : "" + $"{remaining:mm\\:ss}";
systemControls.IsNextEnabled = true;
systemControls.IsPauseEnabled = true;
systemControls.IsPlayEnabled = true;
systemControls.DisplayUpdater.Type = MediaPlaybackType.Video;
systemControls.DisplayUpdater.VideoProperties.Title = item.Snippet.Title;
systemControls.DisplayUpdater.VideoProperties.Subtitle = item.Snippet.ChannelTitle;
systemControls.DisplayUpdater.Thumbnail = RandomAccessStreamReference.CreateFromUri(new Uri(channelAvatar));
systemControls.DisplayUpdater.Update();
systemControls.ButtonPressed += SystemControls_Engaged;
systemControls.IsEnabled = true;
//SecretsVault.HistoryAdd(videoId, elapsed, total);
t.Start();
Visibility = Visibility.Visible;
}
catch (Exception e)
{ {
if(SecretsVault.IsAuthorized && settings.Values["showMature"] != null) RaiseError(e);
{
Visibility = Visibility.Visible;
proceedMature.Visibility = Visibility.Visible;
matureBlock.Visibility = Visibility.Visible;
return;
}
else if(!SecretsVault.IsAuthorized)
{
Visibility = Visibility.Visible;
signReq.Visibility = Visibility.Visible;
matureBlock.Visibility = Visibility.Visible;
return;
}
} }
}
try { videoSource.PosterSource = new BitmapImage(new Uri(item.Snippet.Thumbnails.Maxres.Url)); } public void RaiseError(Exception e)
catch { } {
title.Text = item.Snippet.Title; ((TextBlock)errorPlate.Children[1]).Text = $"Video ID: {videoId}";
channelName.Text = item.Snippet.ChannelTitle; ((TextBlock)errorPlate.Children[2]).Text = $"Error type: {e.GetType()}";
((TextBlock)errorPlate.Children[3]).Text = $"Message: {e.Message}";
quality_SelectionChanged(this, null); ((Grid)errorPlate.Parent).Visibility = Visibility.Visible;
total = XmlConvert.ToTimeSpan(item.ContentDetails.Duration);
seek.Maximum = total.TotalSeconds;
seekIndicator.Maximum = total.TotalSeconds;
elapsed = TimeSpan.FromSeconds(seek.Value);
remaining = total.Subtract(elapsed);
elapsedTime.Text = elapsed.Hours > 0 ? $"{elapsed.Hours}:00:" : "" + $"{elapsed:mm\\:ss}";
remainingTime.Text = remaining.Hours > 0 ? $"{remaining.Hours}:00:" : "" + $"{remaining:mm\\:ss}";
systemControls.IsNextEnabled = true;
systemControls.IsPauseEnabled = true;
systemControls.IsPlayEnabled = true;
systemControls.DisplayUpdater.Type = MediaPlaybackType.Video;
systemControls.DisplayUpdater.VideoProperties.Title = item.Snippet.Title;
systemControls.DisplayUpdater.VideoProperties.Subtitle = item.Snippet.ChannelTitle;
systemControls.DisplayUpdater.Thumbnail = RandomAccessStreamReference.CreateFromUri(new Uri(channelAvatar));
systemControls.DisplayUpdater.Update();
systemControls.ButtonPressed += SystemControls_Engaged;
systemControls.IsEnabled = true;
//SecretsVault.HistoryAdd(videoId, elapsed, total);
t.Start();
Visibility = Visibility.Visible;
} }
private async void SystemControls_Engaged(SystemMediaTransportControls sender, SystemMediaTransportControlsButtonPressedEventArgs args) private async void SystemControls_Engaged(SystemMediaTransportControls sender, SystemMediaTransportControlsButtonPressedEventArgs args)
+22 -15
View File
@@ -243,25 +243,32 @@ namespace FoxTube.Pages
async void LoadDownloads() async void LoadDownloads()
{ {
MediaStreamInfoSet infoSet = await new YoutubeClient().GetVideoMediaStreamInfosAsync(videoId); try
foreach(MuxedStreamInfo i in infoSet.Muxed)
{ {
MenuFlyoutItem menuItem = new MenuFlyoutItem() MediaStreamInfoSet infoSet = await new YoutubeClient().GetVideoMediaStreamInfosAsync(videoId);
foreach (MuxedStreamInfo i in infoSet.Muxed)
{ {
Text = i.VideoQualityLabel, MenuFlyoutItem menuItem = new MenuFlyoutItem()
Tag = new object[] { i, i.VideoQualityLabel } {
}; Text = i.VideoQualityLabel,
menuItem.Click += downloadItemSelected; Tag = new object[] { i, i.VideoQualityLabel }
downloadSelector.Items.Add(menuItem); };
} menuItem.Click += downloadItemSelected;
downloadSelector.Items.Add(menuItem);
}
MenuFlyoutItem audioItem = new MenuFlyoutItem() MenuFlyoutItem audioItem = new MenuFlyoutItem()
{
Text = "Audio track",
Tag = new object[] { infoSet.Audio[0], "Audio only" }
};
audioItem.Click += downloadItemSelected;
downloadSelector.Items.Add(audioItem);
}
catch (Exception e)
{ {
Text = "Audio track", loading.Error(e.GetType().ToString(), e.Message);
Tag = new object[] { infoSet.Audio[0], "Audio only" } }
};
audioItem.Click += downloadItemSelected;
downloadSelector.Items.Add(audioItem);
} }
private void downloadItemSelected(object sender, RoutedEventArgs e) private void downloadItemSelected(object sender, RoutedEventArgs e)