Archived
1
0
This repository has been archived on 2026-04-22. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
FoxTube/FoxTube/Controls/Player/VideoPlayer.xaml.cs
T
Michael Gordeev 853a219456 Added ad to player
2019-04-13 16:23:54 +03:00

242 lines
8.6 KiB
C#

using System;
using System.Linq;
using Windows.UI.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Google.Apis.YouTube.v3.Data;
using Windows.UI.Xaml.Media.Imaging;
using Windows.Media;
using Windows.Storage.Streams;
using YoutubeExplode.Models.MediaStreams;
using YoutubeExplode;
using System.Diagnostics;
namespace FoxTube
{
public sealed partial class VideoPlayer : UserControl
{
public Video item;
public string avatar;
public event Event NextClicked;
public event ObjectEventHandler MiniMode;
public PlayerControls Controls => videoSource.TransportControls as PlayerControls;
public TimeSpan Position => videoSource.Position;
bool audioLoaded = false;
bool videoLoaded = false;
bool isMuxed = false;
DispatcherTimer muxedTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(100) };
TimeSpan timecodeBackup;
bool needUpdateTimecode = false;
SystemMediaTransportControls systemControls;
public VideoPlayer()
{
InitializeComponent();
}
public async void Initialize(Video meta, string channelAvatar, bool privateMode = false)
{
item = meta;
avatar = channelAvatar;
videoSource.PosterSource = new BitmapImage((meta.Snippet.Thumbnails.Maxres ?? meta.Snippet.Thumbnails.Medium).Url.ToUri());
Controls.SetMeta(meta.Snippet.Title, meta.Snippet.ChannelTitle);
if (item.Snippet.LiveBroadcastContent == "none")
{
InitializeContols();
if (Methods.GetDuration(item.ContentDetails.Duration).TotalMinutes > 5)
videoSource.Markers.Add(new Windows.UI.Xaml.Media.TimelineMarker { Time = Methods.GetDuration(item.ContentDetails.Duration) - TimeSpan.FromMinutes(1) });
Controls.SetQualities(await new YoutubeClient().GetVideoMediaStreamInfosAsync(item.Id));
Controls.SetCaptions(await new YoutubeClient().GetVideoClosedCaptionTrackInfosAsync(item.Id));
}
else if (item.Snippet.LiveBroadcastContent == "live")
{
InitializeContols();
Controls.IsSkipBackwardButtonVisible = false;
Controls.IsSkipForwardButtonVisible = false;
Controls.LiveRequested += Controls_LiveRequested;
Controls.SetStream((await new YoutubeClient().GetVideoMediaStreamInfosAsync(item.Id)).HlsLiveStreamUrl);
}
else
videoSource.AreTransportControlsEnabled = false;
if (!privateMode)
Debug.WriteLine("TODO: history entry creation");
// TODO: Create history entry
Visibility = Visibility.Visible;
}
private void Controls_LiveRequested(object sender, RoutedEventArgs e)
{
videoSource.Position = videoSource.NaturalDuration.TimeSpan;
}
public void InitializeContols()
{
videoSource.Volume = SettingsStorage.Volume;
muxedTimer.Tick += (s, e) =>
{
if (!Enumerable.Range(-100, 100).Contains((int)(videoSource.Position - audioSource.Position).TotalMilliseconds))
audioSource.Position = videoSource.Position;
};
Controls.CloseRequested += Controls_CloseRequested;
Controls.NextRequested += (s, e) => NextClicked?.Invoke();
Controls.QualityChanged += Controls_QualityChanged;
Controls.MiniModeChanged += Controls_MiniModeChanged;
Controls.Player = videoSource;
#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
}
public void Controls_MiniModeChanged(object sender, bool e)
{
videoSource.IsFullWindow = false;
MiniMode?.Invoke(this, e);
}
public void Minimize()
{
Controls.Minimize();
}
private void Controls_QualityChanged(object sender, MediaStreamInfo requestedQuality, MediaStreamInfoSet list)
{
videoSource.Pause();
timecodeBackup = videoSource.Position;
needUpdateTimecode = true;
audioLoaded = false;
videoLoaded = false;
muxedTimer.Stop();
videoSource.Source = requestedQuality.Url.ToUri();
if(requestedQuality is MuxedStreamInfo)
{
isMuxed = true;
audioSource.Source = null;
}
else
audioSource.Source = list.Audio.First().Url.ToUri();
}
public void Controls_CloseRequested(object sender, RoutedEventArgs e)
{
if(systemControls != null)
systemControls.IsEnabled = false;
videoSource.Stop();
audioSource.Stop();
Methods.MainPage.CloseVideo();
}
private async void SystemControls_Engaged(SystemMediaTransportControls sender, SystemMediaTransportControlsButtonPressedEventArgs args)
{
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
if (args.Button == SystemMediaTransportControlsButton.Next)
NextClicked?.Invoke();
switch (args.Button)
{
case SystemMediaTransportControlsButton.Play:
videoSource.Play();
break;
case SystemMediaTransportControlsButton.Pause:
videoSource.Pause();
break;
case SystemMediaTransportControlsButton.Next:
NextClicked.Invoke();
break;
}
});
}
public void Pause()
{
videoSource.Pause();
}
private void VideoSource_CurrentStateChanged(object sender, RoutedEventArgs e)
{
switch(videoSource.CurrentState)
{
case Windows.UI.Xaml.Media.MediaElementState.Buffering:
case Windows.UI.Xaml.Media.MediaElementState.Paused:
systemControls.PlaybackStatus = MediaPlaybackStatus.Paused;
// TODO: Create history entry
audioSource?.Pause();
break;
case Windows.UI.Xaml.Media.MediaElementState.Playing:
systemControls.PlaybackStatus = MediaPlaybackStatus.Playing;
audioSource?.Play();
break;
}
}
private void AudioSource_CurrentStateChanged(object sender, RoutedEventArgs e)
{
if(audioSource.CurrentState == Windows.UI.Xaml.Media.MediaElementState.Playing)
muxedTimer.Start();
else
muxedTimer.Stop();
}
private void VideoSource_MediaOpened(object sender, RoutedEventArgs e)
{
videoLoaded = true;
if (needUpdateTimecode)
{
videoSource.Position = timecodeBackup;
needUpdateTimecode = false;
}
if (audioLoaded || isMuxed)
videoSource.Play();
}
private void AudioSource_MediaOpened(object sender, RoutedEventArgs e)
{
audioLoaded = true;
if (needUpdateTimecode)
audioSource.Position = timecodeBackup;
if (videoLoaded)
videoSource.Play();
}
private void VideoSource_VolumeChanged(object sender, RoutedEventArgs e)
{
audioSource.Volume = videoSource.Volume;
SettingsStorage.Volume = videoSource.Volume;
}
private void VideoSource_MarkerReached(object sender, Windows.UI.Xaml.Media.TimelineMarkerRoutedEventArgs e)
{
Controls.Advert.PushAdvert();
}
}
}