Player refactoring
This commit is contained in:
@@ -7,6 +7,8 @@ using Windows.Storage;
|
|||||||
|
|
||||||
namespace FoxTube
|
namespace FoxTube
|
||||||
{
|
{
|
||||||
|
public enum MatureState { Blocked, Allowed, AllowedOnce }
|
||||||
|
|
||||||
public static class SettingsStorage
|
public static class SettingsStorage
|
||||||
{
|
{
|
||||||
public static string VideoQuality
|
public static string VideoQuality
|
||||||
@@ -139,6 +141,22 @@ namespace FoxTube
|
|||||||
storage.Values["version"] = value;
|
storage.Values["version"] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public static MatureState Mature
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (storage.Values["mature"] == null)
|
||||||
|
{
|
||||||
|
storage.Values["mature"] = MatureState.Blocked;
|
||||||
|
return MatureState.Blocked;
|
||||||
|
}
|
||||||
|
else return (MatureState)storage.Values["mature"];
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
storage.Values["mature"] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//Settings storage
|
//Settings storage
|
||||||
private static readonly ApplicationDataContainer storage = ApplicationData.Current.LocalSettings;
|
private static readonly ApplicationDataContainer storage = ApplicationData.Current.LocalSettings;
|
||||||
|
|||||||
@@ -14,7 +14,6 @@
|
|||||||
PointerEntered="UserControl_PointerEntered">
|
PointerEntered="UserControl_PointerEntered">
|
||||||
|
|
||||||
<Grid Background="White" Name="grid" Tapped="UserControl_Tapped">
|
<Grid Background="White" Name="grid" Tapped="UserControl_Tapped">
|
||||||
<MediaElement Width="0" Height="0" VerticalAlignment="Top" HorizontalAlignment="Right" Name="audioSource" MediaOpened="videoSource_Opened" BufferingProgressChanged="videoSource_BufferingProgressChanged"/>
|
|
||||||
<MediaElement IsDoubleTapEnabled="False" CurrentStateChanged="videoSource_CurrentStateChanged" AutoPlay="False" MediaOpened="videoSource_Opened" BufferingProgressChanged="videoSource_BufferingProgressChanged" Volume="0" Name="videoSource" AreTransportControlsEnabled="False" PosterSource="ms-appx:///Assets/videoThumbSample.png"/>
|
<MediaElement IsDoubleTapEnabled="False" CurrentStateChanged="videoSource_CurrentStateChanged" AutoPlay="False" MediaOpened="videoSource_Opened" BufferingProgressChanged="videoSource_BufferingProgressChanged" Volume="0" Name="videoSource" AreTransportControlsEnabled="False" PosterSource="ms-appx:///Assets/videoThumbSample.png"/>
|
||||||
|
|
||||||
<controls1:LiveCaptions Player="{x:Bind videoSource}" Visibility="Collapsed"/>
|
<controls1:LiveCaptions Player="{x:Bind videoSource}" Visibility="Collapsed"/>
|
||||||
@@ -63,12 +62,18 @@
|
|||||||
<ProgressBar VerticalAlignment="Bottom" Foreground="Red" Name="seekIndicator" Visibility="Collapsed"/>
|
<ProgressBar VerticalAlignment="Bottom" Foreground="Red" Name="seekIndicator" Visibility="Collapsed"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<Button Name="skipAd" Visibility="Collapsed" Margin="0,0,0,25" Grid.Row="1" HorizontalAlignment="Right" Foreground="White" VerticalAlignment="Bottom" Padding="10" BorderBrush="Black" BorderThickness="2" Background="#7E000000">
|
<StackPanel Name="schedulePanel" Visibility="Collapsed" VerticalAlignment="Bottom" HorizontalAlignment="Right" Grid.Row="1" BorderBrush="Black" BorderThickness="2" Background="#7E000000" Padding="10" Margin="0,25" Orientation="Horizontal">
|
||||||
<StackPanel Orientation="Horizontal">
|
<FontIcon Glyph="" FontSize="30" Margin="0,0,10,0" VerticalAlignment="Top"/>
|
||||||
<TextBlock FontFamily="Segoe MDL2 Assets" FontSize="30" Margin="0,0,10,0" Text="" VerticalAlignment="Center"/>
|
<StackPanel>
|
||||||
<TextBlock Text="Skip ad" FontSize="30" TextWrapping="WrapWholeWords" MaxWidth="250"/>
|
<TextBlock FontWeight="Bold" Text="Stream hasn't started yet"/>
|
||||||
|
<TextBlock Name="scheduleHeader" Visibility="Collapsed" Text="Stream schedule:"/>
|
||||||
|
<TextBlock Name="scheduleStart" Visibility="Collapsed" Text="Start time: "/>
|
||||||
|
<TextBlock Name="scheduleEnd" Visibility="Collapsed" Text="End time:"/>
|
||||||
|
|
||||||
|
<TextBlock Name="countdownHeader" Visibility="Collapsed" FontWeight="Bold" Text="Stream will be started in:" Margin="0,10,0,0"/>
|
||||||
|
<TextBlock Name="countdown" Visibility="Collapsed" FontWeight="SemiBold" FontSize="20" Text="1:00:00:00"/>
|
||||||
|
</StackPanel>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Button>
|
|
||||||
|
|
||||||
<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"/>
|
||||||
@@ -91,9 +96,15 @@
|
|||||||
</Flyout>
|
</Flyout>
|
||||||
</Button.Flyout>
|
</Button.Flyout>
|
||||||
</Button>
|
</Button>
|
||||||
|
<Button Name="gotoLive" Visibility="Collapsed" Click="GotoLive_Click" Background="Transparent" Foreground="White" Height="50" FontSize="25" ToolTipService.ToolTip="Go to live broadcast">
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<FontIcon Glyph="" Foreground="Red"/>
|
||||||
|
<TextBlock Text="Live" Margin="5,0,0,5"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Button>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<Grid Grid.Column="1">
|
<Grid Grid.Column="1" Name="seekPanel">
|
||||||
<TextBlock Name="elapsedTime" Foreground="White" Text="[Elapsed]" VerticalAlignment="Bottom" HorizontalAlignment="Left" ToolTipService.ToolTip="Time elapsed"/>
|
<TextBlock Name="elapsedTime" Foreground="White" Text="[Elapsed]" VerticalAlignment="Bottom" HorizontalAlignment="Left" ToolTipService.ToolTip="Time elapsed"/>
|
||||||
<TextBlock Name="remainingTime" Foreground="White" Text="[Remaining]" VerticalAlignment="Bottom" HorizontalAlignment="Right" ToolTipService.ToolTip="Time remaining"/>
|
<TextBlock Name="remainingTime" Foreground="White" Text="[Remaining]" VerticalAlignment="Bottom" HorizontalAlignment="Right" ToolTipService.ToolTip="Time remaining"/>
|
||||||
<Grid VerticalAlignment="Top" Margin="0,15,0,0" Height="2">
|
<Grid VerticalAlignment="Top" Margin="0,15,0,0" Height="2">
|
||||||
@@ -103,8 +114,11 @@
|
|||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<StackPanel Grid.Column="2" Orientation="Horizontal">
|
<StackPanel Grid.Column="2" Orientation="Horizontal">
|
||||||
|
<TextBlock Text="1:12:32" Name="liveElapsed" Visibility="Collapsed" FontSize="20" VerticalAlignment="Center" ToolTipService.ToolTip="Elapsed time since stream start"/>
|
||||||
|
<StackPanel Orientation="Horizontal" Name="rewindPanel">
|
||||||
<Button Click="back10_Click" 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 Click="back10_Click" 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 Click="fwd30_Click" Name="fwd30" Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="" 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="" Foreground="White" Width="50" Height="50" FontSize="25" ToolTipService.ToolTip="Skip forward for 30 seconds"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
<Line Stroke="White" StrokeThickness="2" Y1="5" Y2="45"/>
|
<Line Stroke="White" StrokeThickness="2" Y1="5" Y2="45"/>
|
||||||
|
|
||||||
@@ -166,6 +180,7 @@
|
|||||||
<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">
|
<Grid Background="#E5000000" Visibility="Collapsed">
|
||||||
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Name="errorPlate">
|
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Name="errorPlate">
|
||||||
<TextBlock Text="Something went wrong..." HorizontalAlignment="Center" FontSize="20"/>
|
<TextBlock Text="Something went wrong..." HorizontalAlignment="Center" FontSize="20"/>
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Timers;
|
using System.Timers;
|
||||||
using Windows.Foundation;
|
using Windows.Foundation;
|
||||||
using Windows.Storage;
|
|
||||||
using Windows.UI.Core;
|
using Windows.UI.Core;
|
||||||
using Windows.UI.Xaml;
|
using Windows.UI.Xaml;
|
||||||
using Windows.UI.Xaml.Controls;
|
using Windows.UI.Xaml.Controls;
|
||||||
@@ -29,9 +28,12 @@ using Windows.System;
|
|||||||
|
|
||||||
namespace FoxTube
|
namespace FoxTube
|
||||||
{
|
{
|
||||||
|
public enum PlayerLayout { Normal, Fullscreen, Minimized }
|
||||||
|
|
||||||
public sealed partial class VideoPlayer : UserControl
|
public sealed partial class VideoPlayer : UserControl
|
||||||
{
|
{
|
||||||
public string videoId;
|
public string videoId;
|
||||||
|
Video item;
|
||||||
|
|
||||||
private bool miniview = false;
|
private bool miniview = false;
|
||||||
public bool MiniView
|
public bool MiniView
|
||||||
@@ -64,18 +66,16 @@ namespace FoxTube
|
|||||||
TimeSpan remaining;
|
TimeSpan remaining;
|
||||||
TimeSpan total;
|
TimeSpan total;
|
||||||
|
|
||||||
Video item;
|
|
||||||
string avatar;
|
string avatar;
|
||||||
double timecodeBackup = 0;
|
double timecodeBackup = 0;
|
||||||
bool needUpdateTimecode = false;
|
bool needUpdateTimecode = false;
|
||||||
|
|
||||||
SystemMediaTransportControls systemControls = SystemMediaTransportControls.GetForCurrentView();
|
SystemMediaTransportControls systemControls;
|
||||||
LiveCaptions captions;
|
LiveCaptions captions;
|
||||||
|
|
||||||
IReadOnlyList<ClosedCaptionTrackInfo> ccInfo;
|
IReadOnlyList<ClosedCaptionTrackInfo> ccInfo;
|
||||||
MediaStreamInfoSet streamInfo;
|
MediaStreamInfoSet streamInfo;
|
||||||
|
|
||||||
ApplicationDataContainer settings = ApplicationData.Current.LocalSettings;
|
|
||||||
Timer t = new Timer()
|
Timer t = new Timer()
|
||||||
{
|
{
|
||||||
Interval = 5000,
|
Interval = 5000,
|
||||||
@@ -87,37 +87,57 @@ namespace FoxTube
|
|||||||
Enabled = true
|
Enabled = true
|
||||||
};
|
};
|
||||||
|
|
||||||
|
DispatcherTimer timer = new DispatcherTimer()
|
||||||
|
{
|
||||||
|
Interval = TimeSpan.FromSeconds(1)
|
||||||
|
};
|
||||||
|
DispatcherTimer ctrlsFadeTimer;
|
||||||
|
|
||||||
public VideoPlayer()
|
public VideoPlayer()
|
||||||
{
|
{
|
||||||
this.InitializeComponent();
|
InitializeComponent();
|
||||||
Visibility = Visibility.Collapsed;
|
|
||||||
if (!ApplicationView.GetForCurrentView().IsViewModeSupported(ApplicationViewMode.CompactOverlay))
|
|
||||||
miniViewBtn.Visibility = Visibility.Collapsed;
|
|
||||||
|
|
||||||
captions = grid.Children[2] as LiveCaptions;
|
|
||||||
|
|
||||||
volume.Value = Convert.ToDouble(settings.Values["volume"]);
|
|
||||||
videoSource.AutoPlay = (bool)settings.Values["videoAutoplay"];
|
|
||||||
|
|
||||||
videoSource.MediaEnded += (s, arg) =>
|
|
||||||
{
|
|
||||||
seek.Value = seek.Maximum;
|
|
||||||
seekIndicator.Value = seekIndicator.Maximum;
|
|
||||||
seekTimer.Stop();
|
|
||||||
};
|
|
||||||
audioSource.CurrentStateChanged += AudioSource_CurrentStateChanged;
|
|
||||||
t.Elapsed += T_Elapsed;
|
|
||||||
seekTimer.Elapsed += SeekTimer_Elapsed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async void Initialize(Video meta, string channelAvatar)
|
public async void Initialize(Video meta, string channelAvatar)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
Visibility = Visibility.Collapsed;
|
||||||
|
|
||||||
item = meta;
|
item = meta;
|
||||||
avatar = channelAvatar;
|
avatar = channelAvatar;
|
||||||
videoId = item.Id;
|
videoId = item.Id;
|
||||||
|
|
||||||
|
if (item.ContentDetails.ContentRating != null)
|
||||||
|
{
|
||||||
|
if(SecretsVault.IsAuthorized)
|
||||||
|
{
|
||||||
|
if (SettingsStorage.Mature == MatureState.AllowedOnce)
|
||||||
|
SettingsStorage.Mature = MatureState.Blocked;
|
||||||
|
else if(SettingsStorage.Mature == MatureState.Blocked)
|
||||||
|
{
|
||||||
|
Visibility = Visibility.Visible;
|
||||||
|
proceedMature.Visibility = Visibility.Visible;
|
||||||
|
matureBlock.Visibility = Visibility.Visible;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Visibility = Visibility.Visible;
|
||||||
|
signReq.Visibility = Visibility.Visible;
|
||||||
|
matureBlock.Visibility = Visibility.Visible;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.Snippet.LiveBroadcastContent == "none")
|
||||||
|
LoadVideo();
|
||||||
|
else if (item.Snippet.LiveBroadcastContent == "live")
|
||||||
|
LoadStream();
|
||||||
|
else
|
||||||
|
LoadUpcoming();
|
||||||
|
|
||||||
#region Retrieving info for CC and Media streams
|
#region Retrieving info for CC and Media streams
|
||||||
//Loading streams
|
//Loading streams
|
||||||
streamInfo = await new YoutubeClient().GetVideoMediaStreamInfosAsync(videoId);
|
streamInfo = await new YoutubeClient().GetVideoMediaStreamInfosAsync(videoId);
|
||||||
@@ -156,30 +176,98 @@ namespace FoxTube
|
|||||||
captionsBtn.Visibility = Visibility.Collapsed;
|
captionsBtn.Visibility = Visibility.Collapsed;
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
if (item.ContentDetails.ContentRating != null)
|
quality_SelectionChanged(this, null);
|
||||||
{
|
|
||||||
if (SecretsVault.IsAuthorized && settings.Values["showMature"] != null)
|
|
||||||
{
|
|
||||||
Visibility = Visibility.Visible;
|
Visibility = Visibility.Visible;
|
||||||
proceedMature.Visibility = Visibility.Visible;
|
|
||||||
matureBlock.Visibility = Visibility.Visible;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
else if (!SecretsVault.IsAuthorized)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Visibility = Visibility.Visible;
|
RaiseError(e);
|
||||||
signReq.Visibility = Visibility.Visible;
|
|
||||||
matureBlock.Visibility = Visibility.Visible;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try { videoSource.PosterSource = new BitmapImage(new Uri(item.Snippet.Thumbnails.Maxres.Url)); }
|
public void InitializeContols()
|
||||||
catch { }
|
{
|
||||||
|
volume.Value = SettingsStorage.Volume;
|
||||||
|
videoSource.AutoPlay = SettingsStorage.Autoplay;
|
||||||
|
|
||||||
|
if (!ApplicationView.GetForCurrentView().IsViewModeSupported(ApplicationViewMode.CompactOverlay))
|
||||||
|
miniViewBtn.Visibility = Visibility.Collapsed;
|
||||||
|
|
||||||
|
videoSource.MediaEnded += (s, arg) =>
|
||||||
|
{
|
||||||
|
seek.Value = seek.Maximum;
|
||||||
|
seekIndicator.Value = seekIndicator.Maximum;
|
||||||
|
timer.Stop();
|
||||||
|
};
|
||||||
|
|
||||||
|
#region System Media Transport Controls
|
||||||
|
systemControls = SystemMediaTransportControls.GetForCurrentView();
|
||||||
|
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(avatar.ToUri());
|
||||||
|
systemControls.DisplayUpdater.Update();
|
||||||
|
|
||||||
|
systemControls.ButtonPressed += SystemControls_Engaged;
|
||||||
|
systemControls.IsEnabled = true;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
videoSource.PosterSource = new BitmapImage(item.Snippet.Thumbnails.Maxres.Url.ToUri());
|
||||||
title.Text = item.Snippet.Title;
|
title.Text = item.Snippet.Title;
|
||||||
channelName.Text = item.Snippet.ChannelTitle;
|
channelName.Text = item.Snippet.ChannelTitle;
|
||||||
|
|
||||||
quality_SelectionChanged(this, null);
|
ctrlsFadeTimer.Interval = TimeSpan.FromSeconds(5);
|
||||||
|
ctrlsFadeTimer.Tick += Elapsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LoadUpcoming()
|
||||||
|
{
|
||||||
|
schedulePanel.Visibility = Visibility.Visible;
|
||||||
|
if (item.LiveStreamingDetails.ScheduledStartTime.HasValue)
|
||||||
|
{
|
||||||
|
scheduleHeader.Visibility = Visibility.Visible;
|
||||||
|
scheduleStart.Visibility = Visibility.Visible;
|
||||||
|
countdownHeader.Visibility = Visibility.Visible;
|
||||||
|
countdown.Visibility = Visibility.Visible;
|
||||||
|
|
||||||
|
scheduleStart.Text = $"Start time: {item.LiveStreamingDetails.ScheduledStartTime.Value}";
|
||||||
|
timer.Tick += UpdateCountdown;
|
||||||
|
timer.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.LiveStreamingDetails.ScheduledEndTime.HasValue)
|
||||||
|
{
|
||||||
|
scheduleHeader.Visibility = Visibility.Visible;
|
||||||
|
scheduleEnd.Visibility = Visibility.Visible;
|
||||||
|
|
||||||
|
scheduleEnd.Text = $"End time: {item.LiveStreamingDetails.ScheduledEndTime.Value}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LoadStream()
|
||||||
|
{
|
||||||
|
InitializeContols();
|
||||||
|
seekPanel.Visibility = Visibility.Collapsed;
|
||||||
|
rewindPanel.Visibility = Visibility.Collapsed;
|
||||||
|
captions.Visibility = Visibility.Collapsed;
|
||||||
|
gotoLive.Visibility = Visibility.Visible;
|
||||||
|
liveElapsed.Visibility = Visibility.Visible;
|
||||||
|
|
||||||
|
timer.Tick += UpdateLive;
|
||||||
|
|
||||||
|
//TODO: Set up a stream
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LoadVideo()
|
||||||
|
{
|
||||||
|
InitializeContols();
|
||||||
|
captions = grid.Children[2] as LiveCaptions;
|
||||||
|
timer.Tick += UpdateSeek;
|
||||||
|
|
||||||
total = XmlConvert.ToTimeSpan(item.ContentDetails.Duration);
|
total = XmlConvert.ToTimeSpan(item.ContentDetails.Duration);
|
||||||
seek.Maximum = total.TotalSeconds;
|
seek.Maximum = total.TotalSeconds;
|
||||||
@@ -190,30 +278,22 @@ namespace FoxTube
|
|||||||
|
|
||||||
elapsedTime.Text = elapsed.Hours > 0 ? $"{elapsed.Hours}:00:" : "" + $"{elapsed:mm\\:ss}";
|
elapsedTime.Text = elapsed.Hours > 0 ? $"{elapsed.Hours}:00:" : "" + $"{elapsed:mm\\:ss}";
|
||||||
remainingTime.Text = remaining.Hours > 0 ? $"{remaining.Hours}:00:" : "" + $"{remaining: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)
|
|
||||||
|
public void UpdateCountdown(object sender, object e)
|
||||||
{
|
{
|
||||||
RaiseError(e);
|
countdown.Text = $"{item.LiveStreamingDetails.ScheduledStartTime.Value - DateTime.Now:hh\\:mm\\:ss}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void UpdateLive(object sender, object e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateSeek(object sender, object e)
|
||||||
|
{
|
||||||
|
seek.Value = videoSource.Position.TotalSeconds;
|
||||||
|
seekIndicator.Value = seek.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RaiseError(Exception e)
|
public void RaiseError(Exception e)
|
||||||
@@ -245,48 +325,21 @@ namespace FoxTube
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void SeekTimer_Elapsed(object sender, ElapsedEventArgs e)
|
void Elapsed(object sender, object e)
|
||||||
{
|
|
||||||
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, SeekElapsed);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async void T_Elapsed(object sender, ElapsedEventArgs e)
|
|
||||||
{
|
|
||||||
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, Elapsed);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SeekElapsed()
|
|
||||||
{
|
|
||||||
seek.Value = videoSource.Position.TotalSeconds;
|
|
||||||
seekIndicator.Value = seek.Value;
|
|
||||||
/*if (Math.Round(videoSource.Position.TotalSeconds, 1) != Math.Round(audioSource.Position.TotalSeconds, 1))
|
|
||||||
{
|
|
||||||
Debug.WriteLine($"Correcting tracks synchronization (Video track position: {videoSource.Position}; Audio track position: {audioSource.Position})");
|
|
||||||
audioSource.Position = videoSource.Position;
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
|
|
||||||
void Elapsed()
|
|
||||||
{
|
{
|
||||||
controls.Visibility = Visibility.Collapsed;
|
controls.Visibility = Visibility.Collapsed;
|
||||||
if (!MiniView)
|
if (!MiniView)
|
||||||
touchCentral.Visibility = Visibility.Collapsed;
|
touchCentral.Visibility = Visibility.Collapsed;
|
||||||
if (pointerCaptured)
|
if (pointerCaptured)
|
||||||
{
|
|
||||||
cursorPositionBackup = Window.Current.CoreWindow.PointerPosition;
|
|
||||||
Window.Current.CoreWindow.PointerCursor = null;
|
Window.Current.CoreWindow.PointerCursor = null;
|
||||||
}
|
|
||||||
seekIndicator.Visibility = Visibility.Collapsed;
|
seekIndicator.Visibility = Visibility.Collapsed;
|
||||||
t.Stop();
|
ctrlsFadeTimer.Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateSize()
|
public void UpdateSize()
|
||||||
{
|
{
|
||||||
if(MiniView)
|
if(MiniView)
|
||||||
{
|
|
||||||
Height = Window.Current.Bounds.Height;
|
Height = Window.Current.Bounds.Height;
|
||||||
Debug.WriteLine("Video player aspect ratio has been corrected.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void volume_ValueChanged(object sender, RangeBaseValueChangedEventArgs e)
|
private void volume_ValueChanged(object sender, RangeBaseValueChangedEventArgs e)
|
||||||
@@ -303,20 +356,20 @@ namespace FoxTube
|
|||||||
else if (v > 75)
|
else if (v > 75)
|
||||||
muteBtn.Content = openVolume.Content = "\xE995";
|
muteBtn.Content = openVolume.Content = "\xE995";
|
||||||
|
|
||||||
settings.Values["volume"] = volume.Value;
|
SettingsStorage.Volume = (int) volume.Value;
|
||||||
|
|
||||||
audioSource.Volume = videoSource.Volume = volume.Value * 0.01;
|
videoSource.Volume = volume.Value * 0.01;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void muteBtn_Click(object sender, RoutedEventArgs e)
|
private void muteBtn_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
if(volume.Value != 0)
|
if (volume.Value != 0)
|
||||||
{
|
{
|
||||||
double v = (double)settings.Values["volume"];
|
int v = SettingsStorage.Volume;
|
||||||
volume.Value = 0;
|
volume.Value = 0;
|
||||||
settings.Values["volume"] = v;
|
SettingsStorage.Volume = v;
|
||||||
}
|
}
|
||||||
else volume.Value = (double)settings.Values["volume"];
|
else volume.Value = SettingsStorage.Volume;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UserControl_Tapped(object sender, TappedRoutedEventArgs e)
|
private void UserControl_Tapped(object sender, TappedRoutedEventArgs e)
|
||||||
@@ -324,8 +377,8 @@ namespace FoxTube
|
|||||||
if (e.PointerDeviceType == Windows.Devices.Input.PointerDeviceType.Touch)
|
if (e.PointerDeviceType == Windows.Devices.Input.PointerDeviceType.Touch)
|
||||||
{
|
{
|
||||||
touchCentral.Visibility = Visibility.Visible;
|
touchCentral.Visibility = Visibility.Visible;
|
||||||
if (t.Enabled)
|
if (ctrlsFadeTimer.IsEnabled)
|
||||||
Elapsed();
|
Elapsed(this, null);
|
||||||
else
|
else
|
||||||
ShowControls();
|
ShowControls();
|
||||||
}
|
}
|
||||||
@@ -340,15 +393,29 @@ namespace FoxTube
|
|||||||
ShowControls();
|
ShowControls();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void UserControl_PointerExited(object sender, PointerRoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (t.Enabled && e.Pointer.PointerDeviceType == Windows.Devices.Input.PointerDeviceType.Mouse)
|
||||||
|
{
|
||||||
|
pointerCaptured = false;
|
||||||
|
Elapsed(this, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UserControl_PointerEntered(object sender, PointerRoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.Pointer.PointerDeviceType == Windows.Devices.Input.PointerDeviceType.Mouse)
|
||||||
|
pointerCaptured = true;
|
||||||
|
}
|
||||||
|
|
||||||
void ShowControls()
|
void ShowControls()
|
||||||
{
|
{
|
||||||
controls.Visibility = Visibility.Visible;
|
controls.Visibility = Visibility.Visible;
|
||||||
if (MiniView)
|
if (MiniView)
|
||||||
seekIndicator.Visibility = Visibility.Visible;
|
seekIndicator.Visibility = Visibility.Visible;
|
||||||
if (pointerCaptured)
|
Window.Current.CoreWindow.PointerCursor = new CoreCursor(CoreCursorType.Arrow, 0);
|
||||||
Window.Current.CoreWindow.PointerCursor = cursorBackup;
|
ctrlsFadeTimer.Stop();
|
||||||
t.Stop();
|
ctrlsFadeTimer.Start();
|
||||||
t.Start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void quality_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
private void quality_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||||
@@ -529,42 +596,11 @@ namespace FoxTube
|
|||||||
videoSource.Play();
|
videoSource.Play();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AudioSource_CurrentStateChanged(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
switch (audioSource.CurrentState)
|
|
||||||
{
|
|
||||||
case MediaElementState.Buffering:
|
|
||||||
if(videoSource.CurrentState != MediaElementState.Buffering)
|
|
||||||
videoSource.Pause();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MediaElementState.Playing:
|
|
||||||
if (videoSource.CurrentState == MediaElementState.Paused)
|
|
||||||
videoSource.Play();
|
|
||||||
else if (videoSource.CurrentState == MediaElementState.Buffering)
|
|
||||||
audioSource.Pause();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void videoSource_Opened(object sender, RoutedEventArgs arg)
|
private void videoSource_Opened(object sender, RoutedEventArgs arg)
|
||||||
{
|
{
|
||||||
if(!isMuxed)
|
if (SettingsStorage.Autoplay)
|
||||||
{
|
|
||||||
if(sender == videoSource)
|
|
||||||
{
|
|
||||||
videoReady = true;
|
|
||||||
if (audioReady && ((timecodeBackup == 0 && (bool)settings.Values["videoAutoplay"]) || timecodeBackup > 0))
|
|
||||||
play_Click(this, null);
|
play_Click(this, null);
|
||||||
}
|
}
|
||||||
else if(sender == audioSource)
|
|
||||||
{
|
|
||||||
audioReady = true;
|
|
||||||
if (videoReady && ((timecodeBackup == 0 && (bool)settings.Values["videoAutoplay"]) || timecodeBackup > 0))
|
|
||||||
play_Click(this, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void videoSource_CurrentStateChanged(object sender, RoutedEventArgs e)
|
private void videoSource_CurrentStateChanged(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
@@ -708,21 +744,6 @@ namespace FoxTube
|
|||||||
videoSource.Position = elapsed.Subtract(TimeSpan.FromSeconds(10));
|
videoSource.Position = elapsed.Subtract(TimeSpan.FromSeconds(10));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UserControl_PointerExited(object sender, PointerRoutedEventArgs e)
|
|
||||||
{
|
|
||||||
if (t.Enabled && e.Pointer.PointerDeviceType == Windows.Devices.Input.PointerDeviceType.Mouse)
|
|
||||||
{
|
|
||||||
pointerCaptured = false;
|
|
||||||
Elapsed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UserControl_PointerEntered(object sender, PointerRoutedEventArgs e)
|
|
||||||
{
|
|
||||||
if (e.Pointer.PointerDeviceType == Windows.Devices.Input.PointerDeviceType.Mouse)
|
|
||||||
pointerCaptured = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void next_Click(object sender, RoutedEventArgs e)
|
private void next_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
NextClicked.Invoke(this, null);
|
NextClicked.Invoke(this, null);
|
||||||
@@ -874,5 +895,10 @@ namespace FoxTube
|
|||||||
{
|
{
|
||||||
bufferingLevel.Value = (audioSource.Source != null && videoSource.BufferingProgress > audioSource.BufferingProgress ? audioSource.BufferingProgress : videoSource.BufferingProgress) * 100;
|
bufferingLevel.Value = (audioSource.Source != null && videoSource.BufferingProgress > audioSource.BufferingProgress ? audioSource.BufferingProgress : videoSource.BufferingProgress) * 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void GotoLive_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -269,6 +269,7 @@ namespace FoxTube.Pages
|
|||||||
|
|
||||||
commentsPlaceholder.Header = "Chat";
|
commentsPlaceholder.Header = "Chat";
|
||||||
//TODO: Initialize chat
|
//TODO: Initialize chat
|
||||||
|
//TODO: Initialize player
|
||||||
download.Visibility = Visibility.Collapsed;
|
download.Visibility = Visibility.Collapsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user