Archived
1
0

Video player except of captions, fullscreen and rotation management

This commit is contained in:
Michael Gordeev
2018-08-04 00:24:41 +03:00
parent c996da2bfb
commit 9edd432ae8
7 changed files with 255 additions and 333 deletions
+1 -1
View File
@@ -117,7 +117,7 @@ namespace FoxTube
if (settings.Values["authorized"] == null) if (settings.Values["authorized"] == null)
settings.Values.Add("authorized", true); settings.Values.Add("authorized", true);
else settings.Values["authorized"] = true; else settings.Values["authorized"] = true;
IsAuthorized = true; IsAuthorized = true;
var request = Service.Channels.List("snippet,contentDetails"); var request = Service.Channels.List("snippet,contentDetails");
request.Mine = true; request.Mine = true;
+1
View File
@@ -72,6 +72,7 @@ namespace FoxTube.Controls
{ {
var request = SecretsVault.Service.Comments.List("snippet"); var request = SecretsVault.Service.Comments.List("snippet");
request.ParentId = item.Id; request.ParentId = item.Id;
request.TextFormat = CommentsResource.ListRequest.TextFormatEnum.PlainText;
request.MaxResults = 10; request.MaxResults = 10;
var response = await request.ExecuteAsync(); var response = await request.ExecuteAsync();
+1 -1
View File
@@ -88,7 +88,7 @@ namespace FoxTube.Controls
} }
} }
private async void Button_Click(object sender, RoutedEventArgs e) public async void Button_Click(object sender, RoutedEventArgs e)
{ {
if (embed) if (embed)
{ {
+14 -60
View File
@@ -66,19 +66,6 @@
</StackPanel> </StackPanel>
</Button> </Button>
<StackPanel Name="schedulePanel" Visibility="Collapsed" VerticalAlignment="Bottom" HorizontalAlignment="Right" Grid.Row="1" BorderBrush="Black" BorderThickness="2" Background="#7E000000" Padding="10" Margin="25" Orientation="Horizontal">
<TextBlock FontFamily="Segoe MDL2 Assets" FontSize="30" Margin="0,0,10,0" Foreground="White" Text="&#xE704;"/>
<StackPanel>
<TextBlock Foreground="White" FontWeight="Bold" Text="Stream hasn't started yet"/>
<TextBlock Name="scheduleHeader" Foreground="White" Text="Stream schedule:"/>
<TextBlock Name="scheduleStart" Foreground="White" Text="Start time: 18-Jun-18 12:12:12 AM"/>
<TextBlock Foreground="White" Name="scheduleEnd" Text="End time: 18-Jun-18 12:12:12 AM"/>
<TextBlock Name="countdownHeader" Foreground="White" FontWeight="Bold" Text="Stream will be started in:" Margin="0,10,0,0"/>
<TextBlock Foreground="White" Name="streamCountdown" FontWeight="SemiBold" FontSize="20" Text="1:10:31:48"/>
</StackPanel>
</StackPanel>
<Grid Grid.Row="2" Height="50" Name="mainControls" Background="#7F000000"> <Grid Grid.Row="2" Height="50" Name="mainControls" Background="#7F000000">
<ProgressBar Name="bufferingBar" VerticalAlignment="Top" Margin="0,-4,0,0" IsIndeterminate="True" Visibility="Visible"/> <ProgressBar Name="bufferingBar" VerticalAlignment="Top" Margin="0,-4,0,0" IsIndeterminate="True" Visibility="Visible"/>
<Grid> <Grid>
@@ -100,33 +87,18 @@
</Popup> </Popup>
<Grid Grid.Column="1"> <Grid Grid.Column="1">
<Grid.ColumnDefinitions> <TextBlock Name="elapsedTime" Foreground="White" Text="[Elapsed]" VerticalAlignment="Bottom" HorizontalAlignment="Left" ToolTipService.ToolTip="Time elapsed"/>
<ColumnDefinition Width="auto"/> <TextBlock Name="remainingTime" Foreground="White" Text="[Remaining]" VerticalAlignment="Bottom" HorizontalAlignment="Right" ToolTipService.ToolTip="Time remaining"/>
<ColumnDefinition/> <Slider PointerCaptureLost="seek_PointerCaptureLost" ValueChanged="seek_ValueChanged" Name="seek" VerticalAlignment="Top" ToolTipService.ToolTip="Seek" IsThumbToolTipEnabled="False" HorizontalAlignment="Stretch"/>
</Grid.ColumnDefinitions>
<Button Name="goLive" Visibility="Collapsed" Foreground="White" Background="Transparent">
<StackPanel Orientation="Horizontal">
<TextBlock Foreground="Red" FontSize="30" VerticalAlignment="Center" FontFamily="Segoe MDL2 Assets" Text="&#xE1F5;"/>
<TextBlock Text="LIVE" VerticalAlignment="Center"/>
</StackPanel>
</Button>
<Grid Name="seekPanel" Grid.Column="1">
<TextBlock Name="elapsedTime" Foreground="White" Text="[Elapsed]" VerticalAlignment="Bottom" HorizontalAlignment="Left" Margin="10,0,10,0" ToolTipService.ToolTip="Time elapsed"/>
<TextBlock Name="remainingTime" Foreground="White" Text="[Remaining]" VerticalAlignment="Bottom" HorizontalAlignment="Stretch" Margin="1430,0,10,0" ToolTipService.ToolTip="Time remaining"/>
<Slider PointerCaptureLost="seek_PointerCaptureLost" ValueChanged="seek_ValueChanged" Name="seek" VerticalAlignment="Top" ToolTipService.ToolTip="Seek" IsThumbToolTipEnabled="False" HorizontalAlignment="Stretch"/>
</Grid>
</Grid> </Grid>
<StackPanel Grid.Column="2" Orientation="Horizontal"> <StackPanel Grid.Column="2" Orientation="Horizontal">
<StackPanel Name="backFwdPanel" Orientation="Horizontal"> <Button Click="back10_Click" Name="back10" Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="&#xED3C;" Foreground="White" Width="50" Height="50" FontSize="25" ToolTipService.ToolTip="Skip back for 10 seconds"/>
<Button Click="back10_Click" Name="back10" Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="&#xED3C;" Foreground="White" Width="50" Height="50" FontSize="25" ToolTipService.ToolTip="Skip back for 10 seconds"/> <Button Click="fwd30_Click" Name="fwd30" Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="&#xED3D;" Foreground="White" Width="50" Height="50" FontSize="25" ToolTipService.ToolTip="Skip forward for 30 seconds"/>
<Button Click="fwd30_Click" Name="fwd30" Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="&#xED3D;" 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="&#xE190;" Foreground="White" Width="50" Height="50" FontSize="25" ToolTipService.ToolTip="Subtitles" Name="openSubs" Click="openSubs_Click"/>
</StackPanel>
<Button Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="&#xE190;" Foreground="White" Width="50" Height="50" FontSize="25" ToolTipService.ToolTip="Subtitles" Name="openSubs" Click="openSubs_Click"/>
<Button Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="&#xE713;" 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="&#xE713;" 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="&#xE740;" Foreground="White" Width="50" Height="50" FontSize="25" ToolTipService.ToolTip="Full screen" Name="fullscreen" Click="fullscreen_Click"/> <Button Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="&#xE740;" Foreground="White" Width="50" Height="50" FontSize="25" ToolTipService.ToolTip="Full screen" Name="fullscreen" Click="fullscreen_Click"/>
</StackPanel> </StackPanel>
@@ -144,13 +116,13 @@
<Line X1="0" X2="232" Stroke="White" StrokeThickness="2"/> <Line X1="0" X2="232" Stroke="White" StrokeThickness="2"/>
<ComboBox Width="232" Name="quality" SelectionChanged="quality_SelectionChanged"> <ComboBox Width="232" Name="quality" SelectionChanged="quality_SelectionChanged">
<!--<ComboBoxItem Content="Auto"/>--> <!--<ComboBoxItem Content="Auto"/>-->
<ComboBoxItem Content="2160P"/> <ComboBoxItem Content="2160P" Visibility="Collapsed"/>
<ComboBoxItem Content="1080p"/> <ComboBoxItem Content="1080p" Visibility="Collapsed"/>
<ComboBoxItem Content="720p"/> <ComboBoxItem Content="720p" Visibility="Collapsed"/>
<ComboBoxItem Content="480p"/> <ComboBoxItem Content="480p" Visibility="Collapsed"/>
<ComboBoxItem Content="360p"/> <ComboBoxItem Content="360p" Visibility="Collapsed"/>
<ComboBoxItem Content="240p"/> <ComboBoxItem Content="240p" Visibility="Collapsed"/>
<ComboBoxItem Content="144p"/> <ComboBoxItem Content="144p" Visibility="Collapsed"/>
</ComboBox> </ComboBox>
</StackPanel> </StackPanel>
</Popup> </Popup>
@@ -158,17 +130,6 @@
</Grid> </Grid>
</Grid> </Grid>
<Grid Background="Gray" Name="meteredNotification" Visibility="Collapsed">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<FontIcon FontFamily="Segoe MDL2 Assets" FontSize="72" Foreground="White" Glyph="&#xEB63;"/>
<TextBlock Text="You are on a metered connection now. Additional charges may apply." FontSize="22" Foreground="White"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<Button Content="Add to 'Watch later' playlist and go back" Margin="10" Background="Red" Foreground="White" Name="addToLater"/>
<Button Name="meteredDismiss" Click="meteredDismiss_Click" Content="Continue" Margin="10" Foreground="White"/>
</StackPanel>
</StackPanel>
</Grid>
<Grid Name="matureBlock" Visibility="Collapsed" Background="#FF333333" Padding="25"> <Grid Name="matureBlock" Visibility="Collapsed" Background="#FF333333" Padding="25">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="auto"/> <RowDefinition Height="auto"/>
@@ -203,13 +164,6 @@
</StackPanel> </StackPanel>
<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>
<StackPanel Orientation="Horizontal" BorderBrush="OrangeRed" BorderThickness="5" Visibility="Collapsed" Margin="0,10,0,0" Name="denied" Grid.Row="1" VerticalAlignment="Top">
<TextBlock FontFamily="Segoe MDL2 Assets" Text="&#xEB90;" FontSize="40" Foreground="OrangeRed" Margin="5"/>
<StackPanel>
<TextBlock Text="Access denied" Foreground="OrangeRed" FontWeight="Bold" FontSize="20"/>
<TextBlock Text="Your age is below 18. Come back later." Foreground="OrangeRed"/>
</StackPanel>
</StackPanel>
</Grid> </Grid>
</Grid> </Grid>
</UserControl> </UserControl>
+227 -270
View File
@@ -53,23 +53,13 @@ namespace FoxTube
TimeSpan remaining; TimeSpan remaining;
TimeSpan total; TimeSpan total;
Google.Apis.YouTube.v3.Data.Video item; Video item;
string avatar;
double timecodeBackup;
SystemMediaTransportControls systemControls = SystemMediaTransportControls.GetForCurrentView(); SystemMediaTransportControls systemControls = SystemMediaTransportControls.GetForCurrentView();
LoadingPage LoadingScreen = new LoadingPage();
List<YouTubeUri> qualityUris = new List<YouTubeUri>(); List<YouTubeUri> uris = new List<YouTubeUri>();
/*YouTubeQuality[] qualities = new YouTubeQuality[8]
{
YouTubeQuality.QualityHigh,
YouTubeQuality.Quality2160P,
YouTubeQuality.Quality1080P,
YouTubeQuality.Quality720P,
YouTubeQuality.Quality480P,
YouTubeQuality.Quality360P,
YouTubeQuality.Quality240P,
YouTubeQuality.Quality144P
};*/
ApplicationDataContainer settings = ApplicationData.Current.LocalSettings; ApplicationDataContainer settings = ApplicationData.Current.LocalSettings;
Timer t = new Timer() Timer t = new Timer()
@@ -83,47 +73,34 @@ namespace FoxTube
Enabled = true Enabled = true
}; };
Timer countdown;
public VideoPlayer() public VideoPlayer()
{ {
this.InitializeComponent(); this.InitializeComponent();
Visibility = Visibility.Collapsed;
if (!ApplicationView.GetForCurrentView().IsViewModeSupported(ApplicationViewMode.CompactOverlay)) if (!ApplicationView.GetForCurrentView().IsViewModeSupported(ApplicationViewMode.CompactOverlay))
miniView.Visibility = Visibility.Collapsed; miniView.Visibility = Visibility.Collapsed;;
grid.Children.Add(LoadingScreen);
volume.Value = Convert.ToDouble(settings.Values["volume"]); volume.Value = Convert.ToDouble(settings.Values["volume"]);
videoSource.AutoPlay = (bool)settings.Values["videoAutoplay"];
var connection = NetworkInformation.GetInternetConnectionProfile().GetConnectionCost();
if ((bool)settings.Values["moblieWarning"] && (connection.NetworkCostType == NetworkCostType.Fixed || connection.NetworkCostType == NetworkCostType.Variable))
meteredNotification.Visibility = Visibility.Visible;
else
videoSource.AutoPlay = (bool)settings.Values["videoAutoplay"];
t.Elapsed += T_Elapsed; t.Elapsed += T_Elapsed;
seekTimer.Elapsed += SeekTimer_Elapsed; seekTimer.Elapsed += SeekTimer_Elapsed;
} }
public async void Initialize(Google.Apis.YouTube.v3.Data.Video meta, string channelAvatar) public async void Initialize(Video meta, string channelAvatar)
{ {
LoadingScreen.Visibility = Visibility.Visible;
item = meta; item = meta;
avatar = channelAvatar;
videoId = item.Id; videoId = item.Id;
#region Checking qualities availability #region Checking qualities availability
YouTubeUri[] uris = await YouTube.GetUrisAsync(videoId); uris = new List<YouTubeUri>(await YouTube.GetUrisAsync(videoId));
List<YouTubeUri> temp = new List<YouTubeUri>();
Rect bounds = ApplicationView.GetForCurrentView().VisibleBounds; foreach (YouTubeUri i in uris.ToList())
double scaleFactor = DisplayInformation.GetForCurrentView().RawPixelsPerViewPixel; if (!i.HasAudio || !i.HasVideo)
Size size = new Size(bounds.Width * scaleFactor, bounds.Height * scaleFactor); uris.Remove(i);
foreach (YouTubeUri u in uris) foreach (YouTubeUri u in uris)
if (u.HasVideo && !u.Type.Contains("+mp4a"))
temp.Add(u);
foreach(YouTubeUri u in uris)
{ {
Debug.WriteLine("-----------------"); Debug.WriteLine("-----------------");
Debug.WriteLine("URI: " + u.Uri); Debug.WriteLine("URI: " + u.Uri);
@@ -134,120 +111,126 @@ namespace FoxTube
Debug.WriteLine("Audio quality: " + u.AudioQuality); Debug.WriteLine("Audio quality: " + u.AudioQuality);
Debug.WriteLine("-----------------"); Debug.WriteLine("-----------------");
} }
foreach (YouTubeUri u in temp) foreach(YouTubeUri i in uris)
if (u != null) switch(i.VideoQuality)
Debug.WriteLine(u.VideoQuality); {
else case YouTubeQuality.Quality2160P:
Debug.WriteLine("null"); (quality.Items[0] as ComboBoxItem).Visibility = Visibility.Visible;
break;
if (temp[0].VideoQuality != YouTubeQuality.Quality2160P) case YouTubeQuality.Quality1080P:
{ (quality.Items[1] as ComboBoxItem).Visibility = Visibility.Visible;
temp.Insert(0, null); break;
(quality.Items[0] as ComboBoxItem).Visibility = Visibility.Collapsed; case YouTubeQuality.Quality720P:
} (quality.Items[2] as ComboBoxItem).Visibility = Visibility.Visible;
if (temp[1].VideoQuality != YouTubeQuality.Quality1080P) break;
{ case YouTubeQuality.Quality480P:
temp.Insert(1, null); (quality.Items[3] as ComboBoxItem).Visibility = Visibility.Visible;
(quality.Items[1] as ComboBoxItem).Visibility = Visibility.Collapsed; break;
} case YouTubeQuality.Quality360P:
if (temp[2].VideoQuality != YouTubeQuality.Quality720P) (quality.Items[4] as ComboBoxItem).Visibility = Visibility.Visible;
{ break;
temp.Insert(2, null); case YouTubeQuality.Quality240P:
(quality.Items[2] as ComboBoxItem).Visibility = Visibility.Collapsed; (quality.Items[5] as ComboBoxItem).Visibility = Visibility.Visible;
} break;
if (temp[3].VideoQuality != YouTubeQuality.Quality480P) case YouTubeQuality.Quality144P:
{ (quality.Items[6] as ComboBoxItem).Visibility = Visibility.Visible;
temp.Insert(3, null); break;
(quality.Items[3] as ComboBoxItem).Visibility = Visibility.Collapsed; }
}
if (temp[4].VideoQuality != YouTubeQuality.Quality360P)
{
temp.Insert(4, null);
(quality.Items[4] as ComboBoxItem).Visibility = Visibility.Collapsed;
}
if (temp[5].VideoQuality != YouTubeQuality.Quality240P)
{
temp.Insert(5, null);
(quality.Items[5] as ComboBoxItem).Visibility = Visibility.Collapsed;
}
qualityUris = temp;
foreach (YouTubeUri u in qualityUris)
if (u != null)
Debug.WriteLine(u.VideoQuality);
else
Debug.WriteLine("null");
int k = (int)settings.Values["quality"]; int k = (int)settings.Values["quality"];
if (qualityUris[k] == null) switch(k)
for (int a = k - 1; a == 0; a--) {
if (qualityUris[a] != null) case 0:
{ foreach(YouTubeUri i in uris)
k = a; if(i.VideoQuality == YouTubeQuality.Quality2160P)
break; {
} quality.SelectedIndex = 0;
quality.SelectedIndex = k; break;
}
SetFirstQuality();
break;
case 1:
foreach (YouTubeUri i in uris)
if (i.VideoQuality == YouTubeQuality.Quality1080P)
{
quality.SelectedIndex = 1;
break;
}
SetFirstQuality();
break;
case 2:
foreach (YouTubeUri i in uris)
if (i.VideoQuality == YouTubeQuality.Quality720P)
{
quality.SelectedIndex = 2;
break;
}
SetFirstQuality();
break;
case 3:
foreach (YouTubeUri i in uris)
if (i.VideoQuality == YouTubeQuality.Quality480P)
{
quality.SelectedIndex = 3;
break;
}
SetFirstQuality();
break;
case 4:
foreach (YouTubeUri i in uris)
if (i.VideoQuality == YouTubeQuality.Quality360P)
{
quality.SelectedIndex = 4;
break;
}
SetFirstQuality();
break;
case 5:
foreach (YouTubeUri i in uris)
if (i.VideoQuality == YouTubeQuality.Quality240P)
{
quality.SelectedIndex = 5;
break;
}
SetFirstQuality();
break;
case 6:
foreach (YouTubeUri i in uris)
if (i.VideoQuality == YouTubeQuality.Quality144P)
{
quality.SelectedIndex = 6;
break;
}
SetFirstQuality();
break;
}
#endregion #endregion
if(item.ContentDetails.ContentRating != null && if(item.ContentDetails.ContentRating != null)
item.ContentDetails.ContentRating.YtRating == "ytAgeRestricted" &&
settings.Values["showMature"] == null)
{ {
//TO-DO: insert authentication validation if(SecretsVault.IsAuthorized && settings.Values["showMature"] != null)
matureBlock.Visibility = Visibility.Visible;
return;
}
if (item.Snippet.LiveBroadcastContent == "live")
{
goLive.Visibility = Visibility.Visible;
seekPanel.Visibility = Visibility.Collapsed;
backFwdPanel.Visibility = Visibility.Collapsed;
touchBack10.Visibility = touchFwd30.Visibility = Visibility.Collapsed;
}
else if(item.Snippet.LiveBroadcastContent == "upcoming")
{
mainControls.Visibility = Visibility.Collapsed;
touchCentral.Visibility = Visibility.Collapsed;
miniView.Visibility = Visibility.Collapsed;
controls.Visibility = Visibility.Visible;
schedulePanel.Visibility = Visibility.Visible;
if (item.LiveStreamingDetails.ScheduledStartTime != null)
{ {
scheduleStart.Text = "Start time: " + item.LiveStreamingDetails.ScheduledStartTime; Visibility = Visibility.Visible;
proceedMature.Visibility = Visibility.Visible;
countdown = new Timer() matureBlock.Visibility = Visibility.Visible;
{ return;
Interval = 1000,
Enabled = true
};
countdown.Elapsed += Countdown_Elapsed;
} }
else else if(!SecretsVault.IsAuthorized)
{ {
scheduleHeader.Visibility = Visibility.Collapsed; Visibility = Visibility.Visible;
scheduleStart.Visibility = Visibility.Collapsed; signReq.Visibility = Visibility.Visible;
matureBlock.Visibility = Visibility.Visible;
countdownHeader.Visibility = Visibility.Collapsed; return;
streamCountdown.Visibility = Visibility.Collapsed; }
}
if (item.LiveStreamingDetails.ScheduledEndTime != null)
scheduleEnd.Text = "End time: " + item.LiveStreamingDetails.ScheduledEndTime;
else scheduleEnd.Visibility = Visibility.Collapsed;
try { videoSource.PosterSource = new BitmapImage(new Uri(item.Snippet.Thumbnails.Maxres.Url)); }
catch { }
title.Text = item.Snippet.Title;
return;
} }
try { videoSource.PosterSource = new BitmapImage(new Uri(item.Snippet.Thumbnails.Maxres.Url)); } try { videoSource.PosterSource = new BitmapImage(new Uri(item.Snippet.Thumbnails.Maxres.Url)); }
catch { } catch { }
title.Text = item.Snippet.Title; title.Text = item.Snippet.Title;
channelName.Text = item.Snippet.ChannelTitle; channelName.Text = item.Snippet.ChannelTitle;
//videoSource.Source = qualityUris[quality.SelectedIndex].Uri; quality_SelectionChanged(this, null);
total = XmlConvert.ToTimeSpan(item.ContentDetails.Duration); total = XmlConvert.ToTimeSpan(item.ContentDetails.Duration);
seek.Maximum = total.TotalSeconds; seek.Maximum = total.TotalSeconds;
@@ -255,9 +238,9 @@ namespace FoxTube
elapsed = TimeSpan.FromSeconds(seek.Value); elapsed = TimeSpan.FromSeconds(seek.Value);
remaining = total.Subtract(elapsed); remaining = total.Subtract(elapsed);
elapsedTime.Text = string.Format("{0}{1:00}:{2:00}", elapsed.Hours == 0 ? "" : elapsed.Hours + ":", elapsed.Minutes, elapsed.Seconds); elapsedTime.Text = elapsed.Hours > 0 ? $"{elapsed.Hours}:00:" : "" + $"{elapsed:mm\\:ss}";
remainingTime.Text = string.Format("{0}{1:00}:{2:00}", remaining.Hours == 0 ? "" : remaining.Hours + ":", remaining.Minutes, remaining.Seconds); remainingTime.Text = remaining.Hours > 0 ? $"{remaining.Hours}:00:" : "" + $"{remaining:mm\\:ss}";
systemControls.IsNextEnabled = true; systemControls.IsNextEnabled = true;
systemControls.IsPauseEnabled = true; systemControls.IsPauseEnabled = true;
systemControls.IsPlayEnabled = true; systemControls.IsPlayEnabled = true;
@@ -271,126 +254,38 @@ namespace FoxTube
systemControls.ButtonPressed += SystemControls_Engaged; systemControls.ButtonPressed += SystemControls_Engaged;
t.Start(); t.Start();
LoadingScreen.Visibility = Visibility.Collapsed;
Visibility = Visibility.Visible;
} }
private async void Countdown_Elapsed(object sender, ElapsedEventArgs e) void SetFirstQuality()
{ {
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, CountdownElapsed); switch (uris[0].VideoQuality)
}
void CountdownElapsed()
{
TimeSpan span = (TimeSpan)(item.LiveStreamingDetails.ScheduledStartTime - DateTime.Now);
if (span.TotalMilliseconds > 0)
streamCountdown.Text = string.Format("{0}{1:00}:{2:00}:{3:00}", span.Days != 0 ? span.Days + ":" : "", span.Hours, span.Minutes, span.Seconds);
else
{ {
streamCountdown.Text = "Stream will be started shortly..."; case YouTubeQuality.Quality2160P:
countdownHeader.Visibility = Visibility.Collapsed; quality.SelectedIndex = 0;
break;
case YouTubeQuality.Quality1080P:
quality.SelectedIndex = 1;
break;
case YouTubeQuality.Quality720P:
quality.SelectedIndex = 2;
break;
case YouTubeQuality.Quality480P:
quality.SelectedIndex = 3;
break;
case YouTubeQuality.Quality360P:
quality.SelectedIndex = 4;
break;
case YouTubeQuality.Quality240P:
quality.SelectedIndex = 5;
break;
case YouTubeQuality.Quality144P:
quality.SelectedIndex = 6;
break;
} }
} }
async void CheckQualityAvailability(string id)
{
YouTubeUri[] uris = await YouTube.GetUrisAsync(id);
List<YouTubeUri> temp = new List<YouTubeUri>();
Rect bounds = ApplicationView.GetForCurrentView().VisibleBounds;
double scaleFactor = DisplayInformation.GetForCurrentView().RawPixelsPerViewPixel;
Size size = new Size(bounds.Width * scaleFactor, bounds.Height * scaleFactor);
foreach (YouTubeUri u in uris)
if(u.HasVideo && !u.Type.Contains("+mp4a"))
temp.Add(u);
if(temp[0].VideoQuality != YouTubeQuality.Quality2160P && size.Height >= 2160)
{
temp.Insert(0, null);
(quality.Items[0] as ComboBoxItem).Visibility = Visibility.Collapsed;
}
if(temp[1].VideoQuality != YouTubeQuality.Quality1080P && size.Height >= 1080)
{
temp.Insert(1, null);
(quality.Items[1] as ComboBoxItem).Visibility = Visibility.Collapsed;
}
if (temp[2].VideoQuality != YouTubeQuality.Quality720P && size.Height >= 720)
{
temp.Insert(2, null);
(quality.Items[2] as ComboBoxItem).Visibility = Visibility.Collapsed;
}
if (temp[3].VideoQuality != YouTubeQuality.Quality480P && size.Height >= 480)
{
temp.Insert(3, null);
(quality.Items[3] as ComboBoxItem).Visibility = Visibility.Collapsed;
}
if (temp[4].VideoQuality != YouTubeQuality.Quality360P && size.Height >= 360)
{
temp.Insert(4, null);
(quality.Items[4] as ComboBoxItem).Visibility = Visibility.Collapsed;
}
if (temp[5].VideoQuality != YouTubeQuality.Quality240P)
{
temp.Insert(5, null);
(quality.Items[5] as ComboBoxItem).Visibility = Visibility.Collapsed;
}
qualityUris = temp;
foreach (YouTubeUri u in qualityUris)
Debug.WriteLine(u.VideoQuality);
int k = (int)settings.Values["quality"];
if(qualityUris[k] == null)
for(int a = k - 1; a == 0; a--)
if (qualityUris[a] != null)
{
k = a;
break;
}
quality.SelectedIndex = k;
/*YouTubeUri[] ytu = await YouTube.GetUrisAsync(id);
foreach (YouTubeUri uri in ytu)
{
Debug.WriteLine("URI: " + uri.Uri);
Debug.WriteLine("Has video: " + uri.HasVideo);
Debug.WriteLine("Type: " + uri.Type);
Debug.WriteLine("Video quality: " + uri.VideoQuality);
Debug.WriteLine("------------------------------------");
}
throw new Exception();
List<YouTubeUri> uris = new List<YouTubeUri>();
for (int i = 0; i < uris.Count; i++)
if (!uris[i].HasAudio)
uris.RemoveAt(i);
for (int i = 0; i < 8; i++)
try
{
YouTubeUri uri = await YouTube.GetVideoUriAsync(id, qualities[i]);
Debug.WriteLine(qualities[i].ToString() + ": Checked");
Debug.WriteLine("Result URI: " + uri.Uri);
}
catch
{
(quality.Items[i] as ComboBoxItem).Visibility = Visibility.Collapsed;
Debug.WriteLine(qualities[i].ToString() + ": Error");
}
int k = (int)settings.Values["quality"];
if ((quality.Items[k] as ComboBoxItem).Visibility == Visibility.Collapsed)
for (int i = 7; i >= 0; i--)
{
if ((quality.Items[i] as ComboBoxItem).Visibility == Visibility.Visible)
{
quality.SelectedIndex = i;
break;
}
}
else quality.SelectedIndex = k;*/
}
private void SystemControls_Engaged(SystemMediaTransportControls sender, SystemMediaTransportControlsButtonPressedEventArgs args) private void SystemControls_Engaged(SystemMediaTransportControls sender, SystemMediaTransportControlsButtonPressedEventArgs args)
{ {
switch (args.Button) switch (args.Button)
@@ -425,11 +320,8 @@ namespace FoxTube
void Elapsed() void Elapsed()
{ {
if(!volumePane.IsOpen && !qualityPane.IsOpen && item.Snippet.LiveBroadcastContent != "upcoming") if(!volumePane.IsOpen && !qualityPane.IsOpen && !subsPane.IsOpen)
{ {
//await controls.Fade().StartAsync();
volumePane.IsOpen = false;
qualityPane.IsOpen = false;
controls.Visibility = Visibility.Collapsed; controls.Visibility = Visibility.Collapsed;
if(!miniViewed) if(!miniViewed)
touchCentral.Visibility = Visibility.Collapsed; touchCentral.Visibility = Visibility.Collapsed;
@@ -443,10 +335,10 @@ namespace FoxTube
{ {
if(miniViewed) if(miniViewed)
{ {
Height = Window.Current.Bounds.Height; Height = Width * (videoSource.NaturalVideoHeight / videoSource.NaturalVideoWidth);
ApplicationView.GetForCurrentView().TryResizeView(new Size(Width, Height));
Debug.WriteLine("Video player aspect ratio has been corrected."); Debug.WriteLine("Video player aspect ratio has been corrected.");
} }
//Height = e.NewSize.Width / 16 * 9;
} }
private void openVolume_Click(object sender, RoutedEventArgs e) private void openVolume_Click(object sender, RoutedEventArgs e)
@@ -518,7 +410,6 @@ namespace FoxTube
if(controls.Visibility == Visibility.Collapsed) if(controls.Visibility == Visibility.Collapsed)
{ {
controls.Visibility = Visibility.Visible; controls.Visibility = Visibility.Visible;
//await controls.Fade(value: 1).StartAsync();
} }
if (pointerCaptured) if (pointerCaptured)
Window.Current.CoreWindow.PointerCursor = cursorBackup; Window.Current.CoreWindow.PointerCursor = cursorBackup;
@@ -528,18 +419,88 @@ namespace FoxTube
private void quality_SelectionChanged(object sender, SelectionChangedEventArgs e) private void quality_SelectionChanged(object sender, SelectionChangedEventArgs e)
{ {
if(videoSource.Source != null) if(uris.Count > 0)
{ {
videoSource.Pause(); videoSource.Pause();
TimeSpan timecode = videoSource.Position; timecodeBackup = videoSource.Position.TotalSeconds;
videoSource.Source = qualityUris[quality.SelectedIndex].Uri; switch(quality.SelectedIndex)
{
case 0:
foreach (YouTubeUri i in uris)
if (i.VideoQuality == YouTubeQuality.Quality2160P)
{
videoSource.Source = i.Uri;
break;
}
break;
case 1:
foreach (YouTubeUri i in uris)
if (i.VideoQuality == YouTubeQuality.Quality1080P)
{
videoSource.Source = i.Uri;
break;
}
break;
case 2:
foreach (YouTubeUri i in uris)
if (i.VideoQuality == YouTubeQuality.Quality720P)
{
videoSource.Source = i.Uri;
break;
}
break;
case 3:
foreach (YouTubeUri i in uris)
if (i.VideoQuality == YouTubeQuality.Quality480P)
{
videoSource.Source = i.Uri;
break;
}
break;
case 4:
foreach (YouTubeUri i in uris)
if (i.VideoQuality == YouTubeQuality.Quality360P)
{
videoSource.Source = i.Uri;
break;
}
break;
case 5:
foreach (YouTubeUri i in uris)
if (i.VideoQuality == YouTubeQuality.Quality240P)
{
videoSource.Source = i.Uri;
break;
}
break;
case 6:
foreach (YouTubeUri i in uris)
if (i.VideoQuality == YouTubeQuality.Quality144P)
{
videoSource.Source = i.Uri;
break;
}
break;
}
videoSource.Position = timecode;
videoSource.Play(); videoSource.Play();
Timer timer = new Timer(1000);
timer.Elapsed += Timer_Elapsed;
timer.Start();
} }
} }
private async void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
(sender as Timer).Stop();
videoSource.Position = TimeSpan.FromSeconds(timecodeBackup);
});
}
private void subsSwitch_Toggled(object sender, RoutedEventArgs e) private void subsSwitch_Toggled(object sender, RoutedEventArgs e)
{ {
@@ -620,11 +581,6 @@ namespace FoxTube
} }
} }
private void meteredDismiss_Click(object sender, RoutedEventArgs e)
{
meteredNotification.Visibility = Visibility.Collapsed;
}
private async void miniView_Click(object sender, RoutedEventArgs e) private async void miniView_Click(object sender, RoutedEventArgs e)
{ {
ApplicationViewTitleBar titleBar = ApplicationView.GetForCurrentView().TitleBar; ApplicationViewTitleBar titleBar = ApplicationView.GetForCurrentView().TitleBar;
@@ -687,8 +643,8 @@ namespace FoxTube
elapsed = TimeSpan.FromSeconds(seek.Value); elapsed = TimeSpan.FromSeconds(seek.Value);
remaining = total.Subtract(elapsed); remaining = total.Subtract(elapsed);
elapsedTime.Text = string.Format("{0}{1:00}:{2:00}", elapsed.Hours == 0 ? "" : elapsed.Hours + ":", elapsed.Minutes, elapsed.Seconds); elapsedTime.Text = elapsed.Hours > 0 ? $"{elapsed.Hours}:00:" : "" + $"{elapsed:mm\\:ss}";
remainingTime.Text = string.Format("{0}{1:00}:{2:00}", remaining.Hours == 0 ? "" : remaining.Hours + ":", remaining.Minutes, remaining.Seconds); remainingTime.Text = remaining.Hours > 0 ? $"{remaining.Hours}:00:" : "" + $"{remaining:mm\\:ss}";
} }
private void seek_PointerCaptureLost(object sender, PointerRoutedEventArgs e) private void seek_PointerCaptureLost(object sender, PointerRoutedEventArgs e)
@@ -731,6 +687,7 @@ namespace FoxTube
if ((bool)matureDisable.IsChecked) if ((bool)matureDisable.IsChecked)
settings.Values.Add("showMature", false); settings.Values.Add("showMature", false);
matureBlock.Visibility = Visibility.Collapsed; matureBlock.Visibility = Visibility.Collapsed;
Initialize(item, avatar);
} }
private void signin_Click(object sender, RoutedEventArgs e) private void signin_Click(object sender, RoutedEventArgs e)
+4
View File
@@ -186,6 +186,9 @@ namespace FoxTube
content.CacheSize = 0; content.CacheSize = 0;
content.Navigate(typeof(Home)); content.Navigate(typeof(Home));
if (videoPlaceholder.Content != null)
(videoPlaceholder.Content as VideoPage).refresh_Click(this, null);
} }
protected override void OnNavigatedTo(NavigationEventArgs e) protected override void OnNavigatedTo(NavigationEventArgs e)
@@ -504,6 +507,7 @@ namespace FoxTube
{ {
(videoPlaceholder.Content as VideoPage).player.minimize_Click(this, null); (videoPlaceholder.Content as VideoPage).player.minimize_Click(this, null);
} }
catch { }
} }
public void MinimizeVideo() public void MinimizeVideo()
+7 -1
View File
@@ -67,6 +67,7 @@ namespace FoxTube.Pages
loading.RefreshPage += refresh_Click; loading.RefreshPage += refresh_Click;
player = mainContent.Children[0] as VideoPlayer; player = mainContent.Children[0] as VideoPlayer;
player.SetFullSize += Player_SetFullSize; player.SetFullSize += Player_SetFullSize;
player.NextClicked += Player_NextClicked;
comments = commentsPlaceholder.Content as CommentsPage; comments = commentsPlaceholder.Content as CommentsPage;
DataTransferManager.GetForCurrentView().DataRequested += new TypedEventHandler<DataTransferManager, DataRequestedEventArgs>(Share); DataTransferManager.GetForCurrentView().DataRequested += new TypedEventHandler<DataTransferManager, DataRequestedEventArgs>(Share);
@@ -91,6 +92,11 @@ namespace FoxTube.Pages
} }
} }
private void Player_NextClicked(object sender, EventArgs e)
{
(relatedVideos.Children[0] as VideoCard).Button_Click(this, null);
}
protected override void OnNavigatedTo(NavigationEventArgs e) protected override void OnNavigatedTo(NavigationEventArgs e)
{ {
base.OnNavigatedTo(e); base.OnNavigatedTo(e);
@@ -271,7 +277,7 @@ namespace FoxTube.Pages
await Launcher.LaunchUriAsync(new Uri($"https://www.youtube.com/watch?v={videoId}{timecode}")); await Launcher.LaunchUriAsync(new Uri($"https://www.youtube.com/watch?v={videoId}{timecode}"));
} }
private void refresh_Click(object sender, RoutedEventArgs e) public void refresh_Click(object sender, RoutedEventArgs e)
{ {
player = new VideoPlayer(); player = new VideoPlayer();
Initialize(videoId); Initialize(videoId);