[In progress] - Rebuilding video player mechanics to work with DASH manifest
- Fixed crashes on opening links which don't contain http(s) prefix - Fixed backward navigation with minimized video
This commit is contained in:
@@ -6,7 +6,7 @@
|
|||||||
- Fixed fails when trying to retrieve history, WL or recommended
|
- Fixed fails when trying to retrieve history, WL or recommended
|
||||||
- Fixed ads appearance
|
- Fixed ads appearance
|
||||||
- Fixed ads watermarks on video when it was opened through notification
|
- Fixed ads watermarks on video when it was opened through notification
|
||||||
- Fixed videos loading
|
- Optimized and enchanced video playback
|
||||||
- Fixed special characters appearing in toast notifications
|
- Fixed special characters appearing in toast notifications
|
||||||
- History page re-design
|
- History page re-design
|
||||||
- Added app history management (doesn't affect web site's history)
|
- Added app history management (doesn't affect web site's history)
|
||||||
@@ -17,12 +17,14 @@
|
|||||||
- Added incognito mode (available in video card context menu)
|
- Added incognito mode (available in video card context menu)
|
||||||
- Search suggestions now run smoother
|
- Search suggestions now run smoother
|
||||||
- FoxTube pro price is now displayed in menu
|
- FoxTube pro price is now displayed in menu
|
||||||
|
- Fixed crashes on opening links which don't contain http(s) prefix
|
||||||
|
- Fixed backward navigation with minimized video
|
||||||
</en-US>
|
</en-US>
|
||||||
<ru-RU>### Что нового:
|
<ru-RU>### Что нового:
|
||||||
- Исправлена проблема получения истории, "Посмотреть позже" и рекомендаций
|
- Исправлена проблема получения истории, "Посмотреть позже" и рекомендаций
|
||||||
- Исправлен внешний вид рекламы
|
- Исправлен внешний вид рекламы
|
||||||
- Исправлено появление водяных занков рекламы на видео при открытии через уведомления
|
- Исправлено появление водяных занков рекламы на видео при открытии через уведомления
|
||||||
- Исправлена загрузка видео
|
- Оптимизирован и улучшен просмотр видео
|
||||||
- Исправлено появление особых символов в уведомлениях
|
- Исправлено появление особых символов в уведомлениях
|
||||||
- Редизайн страницы истории
|
- Редизайн страницы истории
|
||||||
- Добавлено управление историей просмотра приложения (не влияет на историю просмотров на сайте)
|
- Добавлено управление историей просмотра приложения (не влияет на историю просмотров на сайте)
|
||||||
@@ -33,6 +35,8 @@
|
|||||||
- Добавлен режим инкогнито (доступен в контекстном меню видео карточки)
|
- Добавлен режим инкогнито (доступен в контекстном меню видео карточки)
|
||||||
- Подсказки при поиске работают плавнее
|
- Подсказки при поиске работают плавнее
|
||||||
- Теперь на кнопке отключения рекламы отображается текущая цена
|
- Теперь на кнопке отключения рекламы отображается текущая цена
|
||||||
|
- Исправлены вылеты при попытке открыть ссылку не содержащую http(s) префикс
|
||||||
|
- Исправлена обратная навигация при уменьшенном видео
|
||||||
</ru-RU>
|
</ru-RU>
|
||||||
</content>
|
</content>
|
||||||
</item>
|
</item>
|
||||||
|
|||||||
@@ -0,0 +1,118 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using YoutubeExplode.Models.MediaStreams;
|
||||||
|
using Windows.Storage;
|
||||||
|
using Google.Apis.YouTube.v3.Data;
|
||||||
|
using System.Xml;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace FoxTube.Controls.Player
|
||||||
|
{
|
||||||
|
public static class ManifestGenerator
|
||||||
|
{
|
||||||
|
static StorageFolder roaming = ApplicationData.Current.RoamingFolder;
|
||||||
|
public static async Task<Uri> GetManifest(Video meta, VideoStreamInfo requestedQuality, MediaStreamInfoSet list)
|
||||||
|
{
|
||||||
|
StorageFile manifest = await roaming.CreateFileAsync("manifest.mpd", CreationCollisionOption.ReplaceExisting);
|
||||||
|
|
||||||
|
XmlDocument doc = new XmlDocument();
|
||||||
|
|
||||||
|
XmlElement mpd = doc.CreateElement("MPD");
|
||||||
|
mpd.SetAttribute("mediaPresentationDuration", meta.ContentDetails.Duration);
|
||||||
|
|
||||||
|
XmlElement period = doc.CreateElement("Period");
|
||||||
|
period.SetAttribute("duration", meta.ContentDetails.Duration);
|
||||||
|
period.SetAttribute("start", "PT0S");
|
||||||
|
|
||||||
|
XmlElement videoSet = doc.CreateElement("AdaptationSet");
|
||||||
|
XmlElement videoMeta = doc.CreateElement("ContentComponent");
|
||||||
|
videoMeta.SetAttribute("contentType", "video");
|
||||||
|
videoSet.AppendChild(videoMeta);
|
||||||
|
|
||||||
|
AppendVideoSet(doc, videoSet, list.Video);
|
||||||
|
|
||||||
|
XmlElement audioSet = doc.CreateElement("AdaptationSet");
|
||||||
|
XmlElement audioMeta = doc.CreateElement("ContentComponent");
|
||||||
|
audioMeta.SetAttribute("contentType", "audio");
|
||||||
|
audioSet.AppendChild(audioMeta);
|
||||||
|
|
||||||
|
XmlElement audio = doc.CreateElement("Representation");
|
||||||
|
audio.SetAttribute("bandwidth", "100000");
|
||||||
|
audio.SetAttribute("id", (list.Video.Count + 1).ToString());
|
||||||
|
audio.SetAttribute("mimeType", $"audio/{list.Audio.First().Container.GetFileExtension()}");
|
||||||
|
|
||||||
|
XmlElement audioUrl = doc.CreateElement("BaseURL");
|
||||||
|
audioUrl.InnerText = list.Audio.First().Url;
|
||||||
|
|
||||||
|
audio.AppendChild(audioUrl);
|
||||||
|
audioSet.AppendChild(audio);
|
||||||
|
|
||||||
|
doc.AppendChild(mpd);
|
||||||
|
mpd.AppendChild(period);
|
||||||
|
period.AppendChild(videoSet);
|
||||||
|
period.AppendChild(audioSet);
|
||||||
|
|
||||||
|
doc.Save(await manifest.OpenStreamForWriteAsync());
|
||||||
|
|
||||||
|
return "ms-appdata:///roaming/manifest.mpd".ToUri();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void AppendVideoSet(XmlDocument doc, XmlElement root, IReadOnlyList<VideoStreamInfo> list)
|
||||||
|
{
|
||||||
|
for (int k = 0; k < list.Count; k++)
|
||||||
|
{
|
||||||
|
XmlElement representation = doc.CreateElement("Representation");
|
||||||
|
representation.SetAttribute("bandwidth", GetBandwidth(list[k].VideoQuality));
|
||||||
|
representation.SetAttribute("height", list[k].Resolution.Height.ToString());
|
||||||
|
representation.SetAttribute("width", list[k].Resolution.Width.ToString());
|
||||||
|
representation.SetAttribute("id", (k + 1).ToString());
|
||||||
|
representation.SetAttribute("mimeType", $"video/{list[k].Container.GetFileExtension()}");
|
||||||
|
|
||||||
|
XmlElement baseUrl = doc.CreateElement("BaseURL");
|
||||||
|
baseUrl.InnerText = list[k].Url;
|
||||||
|
representation.AppendChild(baseUrl);
|
||||||
|
|
||||||
|
XmlElement segmentBase = doc.CreateElement("SegmentBase");
|
||||||
|
representation.AppendChild(segmentBase);
|
||||||
|
|
||||||
|
XmlElement initialization = doc.CreateElement("Initialization");
|
||||||
|
initialization.SetAttribute("range", "0-1000");
|
||||||
|
segmentBase.AppendChild(initialization);
|
||||||
|
|
||||||
|
root.AppendChild(representation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetBandwidth(VideoQuality quality)
|
||||||
|
{
|
||||||
|
switch(quality)
|
||||||
|
{
|
||||||
|
case VideoQuality.High4320:
|
||||||
|
return $"16763040";
|
||||||
|
case VideoQuality.High3072:
|
||||||
|
return $"11920384";
|
||||||
|
case VideoQuality.High2880:
|
||||||
|
return $"11175360";
|
||||||
|
case VideoQuality.High2160:
|
||||||
|
return $"8381520";
|
||||||
|
case VideoQuality.High1440:
|
||||||
|
return $"5587680";
|
||||||
|
case VideoQuality.High1080:
|
||||||
|
return $"4190760";
|
||||||
|
case VideoQuality.High720:
|
||||||
|
return $"2073921";
|
||||||
|
case VideoQuality.Medium480:
|
||||||
|
return $"869460";
|
||||||
|
case VideoQuality.Medium360:
|
||||||
|
return $"686521";
|
||||||
|
case VideoQuality.Low240:
|
||||||
|
return $"264835";
|
||||||
|
case VideoQuality.Low144:
|
||||||
|
default:
|
||||||
|
return $"100000";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -214,8 +214,12 @@ namespace FoxTube
|
|||||||
{
|
{
|
||||||
if (link.IsMatch(item))
|
if (link.IsMatch(item))
|
||||||
{
|
{
|
||||||
|
string str = item;
|
||||||
|
if (!str.Contains("http"))
|
||||||
|
str = str.Insert(0, "http://");
|
||||||
|
|
||||||
Hyperlink hl = new Hyperlink();
|
Hyperlink hl = new Hyperlink();
|
||||||
hl.Click += (s, arg) => ProcessLink(item);
|
hl.Click += (s, arg) => ProcessLink(str);
|
||||||
hl.Inlines.Add(new Run { Text = item });
|
hl.Inlines.Add(new Run { Text = item });
|
||||||
block.Inlines.Add(hl);
|
block.Inlines.Add(hl);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,69 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.IO;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using YoutubeExplode.Models.MediaStreams;
|
|
||||||
using Windows.Media.Editing;
|
|
||||||
using Windows.Media.Core;
|
|
||||||
using Windows.Storage;
|
|
||||||
using Windows.UI.Xaml.Controls;
|
|
||||||
using System.Net;
|
|
||||||
using YoutubeExplode;
|
|
||||||
|
|
||||||
namespace FoxTube.Classes
|
|
||||||
{
|
|
||||||
public class VideoProcessor
|
|
||||||
{
|
|
||||||
public MediaElement Player { get; set; }
|
|
||||||
MediaComposition composition = new MediaComposition();
|
|
||||||
|
|
||||||
StorageFolder roaming = ApplicationData.Current.RoamingFolder;
|
|
||||||
StorageFile audioCache;
|
|
||||||
StorageFile videoCache;
|
|
||||||
|
|
||||||
MediaStream videoStream;
|
|
||||||
MediaStream audioStream;
|
|
||||||
|
|
||||||
YoutubeClient client = new YoutubeClient(SecretsVault.HttpClient);
|
|
||||||
|
|
||||||
public VideoProcessor()
|
|
||||||
{
|
|
||||||
//Player.CurrentStateChanged += Player_CurrentStateChanged;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<MediaStreamSource> GetStream(VideoStreamInfo video, AudioStreamInfo audio)
|
|
||||||
{
|
|
||||||
audioCache = await roaming.CreateFileAsync("audioCache.mp4", CreationCollisionOption.ReplaceExisting);
|
|
||||||
videoCache = await roaming.CreateFileAsync("videoCache.mp4", CreationCollisionOption.ReplaceExisting);
|
|
||||||
|
|
||||||
videoStream = await client.GetMediaStreamAsync(video);
|
|
||||||
audioStream = await client.GetMediaStreamAsync(audio);
|
|
||||||
|
|
||||||
/*Stream write = await videoCache.OpenStreamForWriteAsync();
|
|
||||||
write.
|
|
||||||
write.WriteAsync()*/
|
|
||||||
|
|
||||||
videoStream.BeginRead(new byte[300 * video.Bitrate], (int)((int)Player.Position.TotalSeconds * video.Bitrate), (int)((int)Player.Position.Add(TimeSpan.FromMinutes(5)).TotalSeconds * video.Bitrate - (int)Player.Position.TotalSeconds * video.Bitrate), null, null);
|
|
||||||
|
|
||||||
composition.BackgroundAudioTracks.Add(await BackgroundAudioTrack.CreateFromFileAsync(audioCache));
|
|
||||||
composition.Clips.Add(await MediaClip.CreateFromFileAsync(videoCache));
|
|
||||||
|
|
||||||
return composition.GenerateMediaStreamSource();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async void Close()
|
|
||||||
{
|
|
||||||
await audioCache.DeleteAsync(StorageDeleteOption.PermanentDelete);
|
|
||||||
await videoCache.DeleteAsync(StorageDeleteOption.PermanentDelete);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Player_CurrentStateChanged(object sender, Windows.UI.Xaml.RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using Windows.Media.Playback;
|
||||||
using Windows.UI.Xaml;
|
using Windows.UI.Xaml;
|
||||||
using Windows.UI.Xaml.Controls;
|
using Windows.UI.Xaml.Controls;
|
||||||
using YoutubeExplode.Models.ClosedCaptions;
|
using YoutubeExplode.Models.ClosedCaptions;
|
||||||
@@ -16,7 +17,7 @@ namespace FoxTube.Controls
|
|||||||
set => text.FontSize = value;
|
set => text.FontSize = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MediaElement Player { get; set; }
|
public MediaPlayer Player { get; set; }
|
||||||
|
|
||||||
DispatcherTimer timer = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(10) };
|
DispatcherTimer timer = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(10) };
|
||||||
ClosedCaption currentCaption = null;
|
ClosedCaption currentCaption = null;
|
||||||
@@ -31,7 +32,7 @@ namespace FoxTube.Controls
|
|||||||
|
|
||||||
private void UpdateCaption(object sender, object e)
|
private void UpdateCaption(object sender, object e)
|
||||||
{
|
{
|
||||||
currentCaption = track.Captions.Find(i => i.Offset <= Player.Position && i.Offset + i.Duration > Player.Position);
|
currentCaption = track.Captions.Find(i => i.Offset <= Player.PlaybackSession.Position && i.Offset + i.Duration > Player.PlaybackSession.Position);
|
||||||
|
|
||||||
if (currentCaption != null)
|
if (currentCaption != null)
|
||||||
text.Text = currentCaption.Text;
|
text.Text = currentCaption.Text;
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ using System.Collections.Generic;
|
|||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Windows.ApplicationModel.Resources;
|
using Windows.ApplicationModel.Resources;
|
||||||
|
using Windows.Media.Core;
|
||||||
|
using Windows.Media.Playback;
|
||||||
using Windows.UI.Xaml;
|
using Windows.UI.Xaml;
|
||||||
using Windows.UI.Xaml.Controls;
|
using Windows.UI.Xaml.Controls;
|
||||||
using Windows.UI.Xaml.Controls.Primitives;
|
using Windows.UI.Xaml.Controls.Primitives;
|
||||||
@@ -29,7 +31,7 @@ namespace FoxTube
|
|||||||
|
|
||||||
public event QualityChangedEventHandler QualityChanged;
|
public event QualityChangedEventHandler QualityChanged;
|
||||||
|
|
||||||
public MediaElement Player;
|
public MediaPlayer Player;
|
||||||
public PlayerAdvert Advert;
|
public PlayerAdvert Advert;
|
||||||
|
|
||||||
public IReadOnlyList<ClosedCaptionTrackInfo> ClosedCaptions { get; set; }
|
public IReadOnlyList<ClosedCaptionTrackInfo> ClosedCaptions { get; set; }
|
||||||
@@ -347,7 +349,7 @@ namespace FoxTube
|
|||||||
(GetTemplateChild("cc") as Button).Visibility = Visibility.Collapsed;
|
(GetTemplateChild("cc") as Button).Visibility = Visibility.Collapsed;
|
||||||
(GetTemplateChild("quality") as Button).Visibility = Visibility.Collapsed;
|
(GetTemplateChild("quality") as Button).Visibility = Visibility.Collapsed;
|
||||||
|
|
||||||
Player.Source = url.ToUri();
|
Player.Source = MediaSource.CreateFromUri(url.ToUri());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,13 +11,13 @@
|
|||||||
RequestedTheme="Dark">
|
RequestedTheme="Dark">
|
||||||
|
|
||||||
<Grid Background="{StaticResource SystemChromeMediumColor}">
|
<Grid Background="{StaticResource SystemChromeMediumColor}">
|
||||||
<MediaElement Name="videoSource" MarkerReached="VideoSource_MarkerReached" AreTransportControlsEnabled="True" PosterSource="ms-appx:///Assets/videoThumbSample.png" CurrentStateChanged="VideoSource_CurrentStateChanged" MediaOpened="VideoSource_MediaOpened" VolumeChanged="VideoSource_VolumeChanged">
|
<MediaPlayerElement Name="videoSource" AreTransportControlsEnabled="True" PosterSource="ms-appx:///Assets/videoThumbSample.png">
|
||||||
<MediaElement.TransportControls>
|
<MediaPlayerElement.TransportControls>
|
||||||
<foxtube:PlayerControls IsCompactOverlayButtonVisible="True" IsCompactOverlayEnabled="True"
|
<foxtube:PlayerControls IsCompactOverlayButtonVisible="True" IsCompactOverlayEnabled="True"
|
||||||
IsFullWindowButtonVisible="True" IsFullWindowEnabled="True"
|
IsFullWindowButtonVisible="True" IsFullWindowEnabled="True"
|
||||||
IsSkipBackwardButtonVisible="True" IsSkipBackwardEnabled="True"
|
IsSkipBackwardButtonVisible="True" IsSkipBackwardEnabled="True"
|
||||||
IsSkipForwardButtonVisible="True" IsSkipForwardEnabled="True"/>
|
IsSkipForwardButtonVisible="True" IsSkipForwardEnabled="True"/>
|
||||||
</MediaElement.TransportControls>
|
</MediaPlayerElement.TransportControls>
|
||||||
</MediaElement>
|
</MediaPlayerElement>
|
||||||
</Grid>
|
</Grid>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
|||||||
@@ -11,6 +11,14 @@ using YoutubeExplode;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using FoxTube.Classes;
|
using FoxTube.Classes;
|
||||||
using Windows.Media.Core;
|
using Windows.Media.Core;
|
||||||
|
using System.Linq;
|
||||||
|
using Windows.Media.Playback;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Windows.Media.Editing;
|
||||||
|
using Windows.Storage.Pickers;
|
||||||
|
using Windows.Storage;
|
||||||
|
using Windows.Media.MediaProperties;
|
||||||
|
using FoxTube.Controls.Player;
|
||||||
|
|
||||||
namespace FoxTube
|
namespace FoxTube
|
||||||
{
|
{
|
||||||
@@ -23,17 +31,17 @@ namespace FoxTube
|
|||||||
|
|
||||||
public event Event NextClicked;
|
public event Event NextClicked;
|
||||||
public event ObjectEventHandler MiniMode;
|
public event ObjectEventHandler MiniMode;
|
||||||
|
|
||||||
public PlayerControls Controls => videoSource.TransportControls as PlayerControls;
|
public PlayerControls Controls => videoSource.TransportControls as PlayerControls;
|
||||||
|
public MediaPlayer Player { get; } = new MediaPlayer();
|
||||||
public TimeSpan Position
|
public TimeSpan Position
|
||||||
{
|
{
|
||||||
get { return videoSource.Position; }
|
get { return videoSource.MediaPlayer.PlaybackSession.Position; }
|
||||||
set { videoSource.Position = value; }
|
set { videoSource.MediaPlayer.PlaybackSession.Position = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
VideoProcessor processor;
|
//TimeSpan timecodeBackup;
|
||||||
|
//bool needUpdateTimecode = false;
|
||||||
TimeSpan timecodeBackup;
|
|
||||||
bool needUpdateTimecode = false;
|
|
||||||
|
|
||||||
SystemMediaTransportControls systemControls;
|
SystemMediaTransportControls systemControls;
|
||||||
|
|
||||||
@@ -58,11 +66,12 @@ namespace FoxTube
|
|||||||
if (item.Snippet.LiveBroadcastContent == "none")
|
if (item.Snippet.LiveBroadcastContent == "none")
|
||||||
{
|
{
|
||||||
InitializeContols();
|
InitializeContols();
|
||||||
if (Methods.GetDuration(item.ContentDetails.Duration).TotalMinutes > 5)
|
// TODO: make ads live again
|
||||||
videoSource.Markers.Add(new Windows.UI.Xaml.Media.TimelineMarker { Time = Methods.GetDuration(item.ContentDetails.Duration) - TimeSpan.FromMinutes(1) });
|
/*if (Methods.GetDuration(item.ContentDetails.Duration).TotalMinutes > 5)
|
||||||
|
Player.PlaybackSession.Add(new Windows.UI.Xaml.Media.TimelineMarker { Time = Methods.GetDuration(item.ContentDetails.Duration) - TimeSpan.FromMinutes(1) });
|
||||||
if(Methods.GetDuration(item.ContentDetails.Duration).TotalMinutes >= 60)
|
if(Methods.GetDuration(item.ContentDetails.Duration).TotalMinutes >= 60)
|
||||||
for (int k = 1; k < Methods.GetDuration(item.ContentDetails.Duration).TotalMinutes / 30; k++)
|
for (int k = 1; k < Methods.GetDuration(item.ContentDetails.Duration).TotalMinutes / 30; k++)
|
||||||
videoSource.Markers.Add(new Windows.UI.Xaml.Media.TimelineMarker { Time = TimeSpan.FromMinutes(k * 30) });
|
videoSource.Markers.Add(new Windows.UI.Xaml.Media.TimelineMarker { Time = TimeSpan.FromMinutes(k * 30) });*/
|
||||||
|
|
||||||
Controls.SetQualities(await new YoutubeClient().GetVideoMediaStreamInfosAsync(item.Id));
|
Controls.SetQualities(await new YoutubeClient().GetVideoMediaStreamInfosAsync(item.Id));
|
||||||
Controls.SetCaptions(await new YoutubeClient().GetVideoClosedCaptionTrackInfosAsync(item.Id));
|
Controls.SetCaptions(await new YoutubeClient().GetVideoClosedCaptionTrackInfosAsync(item.Id));
|
||||||
@@ -87,22 +96,23 @@ namespace FoxTube
|
|||||||
|
|
||||||
private void Controls_LiveRequested(object sender, RoutedEventArgs e)
|
private void Controls_LiveRequested(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
videoSource.Position = videoSource.NaturalDuration.TimeSpan;
|
Position = Player.PlaybackSession.NaturalDuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void InitializeContols()
|
public void InitializeContols()
|
||||||
{
|
{
|
||||||
processor = new VideoProcessor
|
videoSource.SetMediaPlayer(Player);
|
||||||
{
|
Player.Volume = SettingsStorage.Volume;
|
||||||
Player = videoSource
|
|
||||||
};
|
Player.CurrentStateChanged += VideoSource_CurrentStateChanged;
|
||||||
videoSource.Volume = SettingsStorage.Volume;
|
Player.MediaOpened += VideoSource_MediaOpened;
|
||||||
|
Player.VolumeChanged += VideoSource_VolumeChanged;
|
||||||
|
|
||||||
Controls.CloseRequested += Controls_CloseRequested;
|
Controls.CloseRequested += Controls_CloseRequested;
|
||||||
Controls.NextRequested += (s, e) => NextClicked?.Invoke();
|
Controls.NextRequested += (s, e) => NextClicked?.Invoke();
|
||||||
Controls.QualityChanged += Controls_QualityChanged;
|
Controls.QualityChanged += Controls_QualityChanged;
|
||||||
Controls.MiniModeChanged += Controls_MiniModeChanged;
|
Controls.MiniModeChanged += Controls_MiniModeChanged;
|
||||||
Controls.Player = videoSource;
|
Controls.Player = Player;
|
||||||
|
|
||||||
#region System Media Transport Controls
|
#region System Media Transport Controls
|
||||||
systemControls = SystemMediaTransportControls.GetForCurrentView();
|
systemControls = SystemMediaTransportControls.GetForCurrentView();
|
||||||
@@ -135,16 +145,23 @@ namespace FoxTube
|
|||||||
|
|
||||||
private async void Controls_QualityChanged(object sender, MediaStreamInfo requestedQuality, MediaStreamInfoSet list)
|
private async void Controls_QualityChanged(object sender, MediaStreamInfo requestedQuality, MediaStreamInfoSet list)
|
||||||
{
|
{
|
||||||
videoSource.Pause();
|
Player.Pause();
|
||||||
|
|
||||||
timecodeBackup = videoSource.Position;
|
Player.Source = MediaSource.CreateFromUri(await ManifestGenerator.GetManifest(item, requestedQuality as VideoStreamInfo, list));
|
||||||
|
|
||||||
|
//await ManifestGenerator.GetManifest(item, requestedQuality as VideoStreamInfo, list);
|
||||||
|
/*FileOpenPicker picker = new FileOpenPicker();
|
||||||
|
picker.FileTypeFilter.Add(".mpd");*/
|
||||||
|
|
||||||
|
//Player.Source = MediaSource.CreateFromUri("https://foxsharp.000webhostapp.com/dash_sample.mpd".ToUri());
|
||||||
|
|
||||||
|
/*timecodeBackup = videoSource.Position;
|
||||||
needUpdateTimecode = true;
|
needUpdateTimecode = true;
|
||||||
|
|
||||||
if (requestedQuality is MuxedStreamInfo)
|
if (requestedQuality is MuxedStreamInfo)
|
||||||
videoSource.Source = requestedQuality.Url.ToUri();
|
videoSource.Source = requestedQuality.Url.ToUri();
|
||||||
else
|
else
|
||||||
videoSource.SetPlaybackSource(MediaSource.CreateFromStream((await new YoutubeClient().GetMediaStreamAsync(requestedQuality)).AsRandomAccessStream(), "video"));
|
processor.Start(requestedQuality as VideoStreamInfo, list);*/
|
||||||
//videoSource.SetMediaStreamSource(await processor.GetStream(requestedQuality as VideoStreamInfo, list.Audio.First()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Controls_CloseRequested(object sender, RoutedEventArgs e)
|
public void Controls_CloseRequested(object sender, RoutedEventArgs e)
|
||||||
@@ -154,12 +171,10 @@ namespace FoxTube
|
|||||||
|
|
||||||
if (!incognito)
|
if (!incognito)
|
||||||
{
|
{
|
||||||
history.LeftOn = videoSource.Position;
|
history.LeftOn = Player.PlaybackSession.Position;
|
||||||
HistorySet.Update(history);
|
HistorySet.Update(history);
|
||||||
}
|
}
|
||||||
|
|
||||||
videoSource.Stop();
|
|
||||||
|
|
||||||
Methods.MainPage.CloseVideo();
|
Methods.MainPage.CloseVideo();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,10 +185,10 @@ namespace FoxTube
|
|||||||
switch (args.Button)
|
switch (args.Button)
|
||||||
{
|
{
|
||||||
case SystemMediaTransportControlsButton.Play:
|
case SystemMediaTransportControlsButton.Play:
|
||||||
videoSource.Play();
|
Player.Play();
|
||||||
break;
|
break;
|
||||||
case SystemMediaTransportControlsButton.Pause:
|
case SystemMediaTransportControlsButton.Pause:
|
||||||
videoSource.Pause();
|
Player.Pause();
|
||||||
break;
|
break;
|
||||||
case SystemMediaTransportControlsButton.Next:
|
case SystemMediaTransportControlsButton.Next:
|
||||||
NextClicked?.Invoke();
|
NextClicked?.Invoke();
|
||||||
@@ -184,40 +199,42 @@ namespace FoxTube
|
|||||||
|
|
||||||
public void Pause()
|
public void Pause()
|
||||||
{
|
{
|
||||||
videoSource.Pause();
|
Player.Pause();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void VideoSource_CurrentStateChanged(object sender, RoutedEventArgs e)
|
private void VideoSource_CurrentStateChanged(MediaPlayer sender, object e)
|
||||||
{
|
{
|
||||||
switch(videoSource.CurrentState)
|
switch (Player.PlaybackSession.PlaybackState)
|
||||||
{
|
{
|
||||||
case Windows.UI.Xaml.Media.MediaElementState.Buffering:
|
case MediaPlaybackState.Buffering:
|
||||||
case Windows.UI.Xaml.Media.MediaElementState.Paused:
|
case MediaPlaybackState.None:
|
||||||
|
case MediaPlaybackState.Opening:
|
||||||
|
case MediaPlaybackState.Paused:
|
||||||
systemControls.PlaybackStatus = MediaPlaybackStatus.Paused;
|
systemControls.PlaybackStatus = MediaPlaybackStatus.Paused;
|
||||||
if (!incognito)
|
if (!incognito)
|
||||||
{
|
{
|
||||||
history.LeftOn = videoSource.Position;
|
history.LeftOn = Player.PlaybackSession.Position;
|
||||||
HistorySet.Update(history);
|
HistorySet.Update(history);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Windows.UI.Xaml.Media.MediaElementState.Playing:
|
case MediaPlaybackState.Playing:
|
||||||
systemControls.PlaybackStatus = MediaPlaybackStatus.Playing;
|
systemControls.PlaybackStatus = MediaPlaybackStatus.Playing;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void VideoSource_MediaOpened(object sender, RoutedEventArgs e)
|
private void VideoSource_MediaOpened(MediaPlayer sender, object e)
|
||||||
{
|
{
|
||||||
if (!needUpdateTimecode)
|
/*if (!needUpdateTimecode)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
videoSource.Position = timecodeBackup;
|
videoSource.Position = timecodeBackup;
|
||||||
needUpdateTimecode = false;
|
needUpdateTimecode = false;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
private void VideoSource_VolumeChanged(object sender, RoutedEventArgs e)
|
private void VideoSource_VolumeChanged(MediaPlayer sender, object e)
|
||||||
{
|
{
|
||||||
SettingsStorage.Volume = videoSource.Volume;
|
SettingsStorage.Volume = Player.Volume;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void VideoSource_MarkerReached(object sender, Windows.UI.Xaml.Media.TimelineMarkerRoutedEventArgs e)
|
private void VideoSource_MarkerReached(object sender, Windows.UI.Xaml.Media.TimelineMarkerRoutedEventArgs e)
|
||||||
|
|||||||
@@ -107,7 +107,7 @@
|
|||||||
<Compile Include="Classes\Methods.cs" />
|
<Compile Include="Classes\Methods.cs" />
|
||||||
<Compile Include="Classes\SearchPaameters.cs" />
|
<Compile Include="Classes\SearchPaameters.cs" />
|
||||||
<Compile Include="Classes\SettingsStorage.cs" />
|
<Compile Include="Classes\SettingsStorage.cs" />
|
||||||
<Compile Include="Classes\VideoProcessor.cs" />
|
<Compile Include="Classes\ManifestGenerator.cs" />
|
||||||
<Compile Include="Controls\Advert.xaml.cs">
|
<Compile Include="Controls\Advert.xaml.cs">
|
||||||
<DependentUpon>Advert.xaml</DependentUpon>
|
<DependentUpon>Advert.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
|||||||
@@ -120,47 +120,12 @@
|
|||||||
</TransitionCollection>
|
</TransitionCollection>
|
||||||
</ui:NavigationViewList.ItemContainerTransitions>
|
</ui:NavigationViewList.ItemContainerTransitions>
|
||||||
<ui:NavigationViewItem Name="openWeb" Tapped="Web_Tapped" Icon="Globe" Content="Browser" Visibility="Collapsed"/>
|
<ui:NavigationViewItem Name="openWeb" Tapped="Web_Tapped" Icon="Globe" Content="Browser" Visibility="Collapsed"/>
|
||||||
<!--<ui:NavigationViewItem x:Uid="/Main/feedback" Name="feedback" Content="Give a feedback" Tapped="Feedback_Click" Visibility="Collapsed">
|
|
||||||
<ui:NavigationViewItem.Icon>
|
|
||||||
<FontIcon Glyph=""/>
|
|
||||||
</ui:NavigationViewItem.Icon>
|
|
||||||
</ui:NavigationViewItem>-->
|
|
||||||
|
|
||||||
<ui:NavigationViewItem Content="Remove ads" Visibility="Collapsed" Tapped="RemoveAds_Tapped" Name="removeAds">
|
<ui:NavigationViewItem Content="Remove ads" Visibility="Collapsed" Tapped="RemoveAds_Tapped" Name="removeAds">
|
||||||
<ui:NavigationViewItem.Icon>
|
<ui:NavigationViewItem.Icon>
|
||||||
<FontIcon Glyph=""/>
|
<FontIcon Glyph=""/>
|
||||||
</ui:NavigationViewItem.Icon>
|
</ui:NavigationViewItem.Icon>
|
||||||
</ui:NavigationViewItem>
|
</ui:NavigationViewItem>
|
||||||
|
|
||||||
<!--<ui:NavigationViewItem Name="account" x:Uid="/Main/signIn" Content="Add account" Tapped="SignIn_Click" Visibility="Collapsed">
|
|
||||||
<ui:NavigationViewItem.Icon>
|
|
||||||
<FontIcon Glyph=""/>
|
|
||||||
</ui:NavigationViewItem.Icon>
|
|
||||||
</ui:NavigationViewItem>
|
|
||||||
|
|
||||||
<ui:NavigationViewItem Visibility="Collapsed" Name="avatar" Tapped="OpenContext" Padding="-5">
|
|
||||||
<StackPanel Orientation="Horizontal" Padding="5">
|
|
||||||
<PersonPicture Height="20" Margin="-5,0,15,0"/>
|
|
||||||
<TextBlock Name="myName" Text="My account"/>
|
|
||||||
</StackPanel>
|
|
||||||
|
|
||||||
<ui:NavigationViewItem.ContextFlyout>
|
|
||||||
<Flyout>
|
|
||||||
<Grid>
|
|
||||||
<Grid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition Width="auto"/>
|
|
||||||
<ColumnDefinition/>
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
<PersonPicture Width="50" Name="avatarFlyout" VerticalAlignment="Top"/>
|
|
||||||
<StackPanel Grid.Column="1" Margin="5">
|
|
||||||
<TextBlock Name="myNameFlyout"/>
|
|
||||||
<TextBlock Style="{StaticResource CaptionTextBlockStyle}" Name="myEmail"/>
|
|
||||||
<HyperlinkButton x:Uid="/Main/signOut" Content="Log out" Click="Logout_Click"/>
|
|
||||||
</StackPanel>
|
|
||||||
</Grid>
|
|
||||||
</Flyout>
|
|
||||||
</ui:NavigationViewItem.ContextFlyout>
|
|
||||||
</ui:NavigationViewItem>-->
|
|
||||||
</ui:NavigationViewList>
|
</ui:NavigationViewList>
|
||||||
</ui:NavigationView.PaneFooter>
|
</ui:NavigationView.PaneFooter>
|
||||||
|
|
||||||
|
|||||||
@@ -591,7 +591,7 @@ namespace FoxTube
|
|||||||
|
|
||||||
private void Nav_BackRequested(Microsoft.UI.Xaml.Controls.NavigationView sender, Microsoft.UI.Xaml.Controls.NavigationViewBackRequestedEventArgs args)
|
private void Nav_BackRequested(Microsoft.UI.Xaml.Controls.NavigationView sender, Microsoft.UI.Xaml.Controls.NavigationViewBackRequestedEventArgs args)
|
||||||
{
|
{
|
||||||
if (videoPlaceholder.Content != null)
|
if (videoPlaceholder.Content != null && videoPlaceholder.Width == double.NaN)
|
||||||
{
|
{
|
||||||
if ((videoPlaceholder.Content as VideoPage).LoadingPage.State != LoadingState.Loaded)
|
if ((videoPlaceholder.Content as VideoPage).LoadingPage.State != LoadingState.Loaded)
|
||||||
CloseVideo();
|
CloseVideo();
|
||||||
|
|||||||
Reference in New Issue
Block a user