Archived
1
0

- Cursor hiding on playback removed

- Ad free version price is displayed now
- Video player muxed streams playback development
This commit is contained in:
Michael Gordeev
2019-04-30 16:53:38 +03:00
parent a9788b728f
commit 5eb56f2335
7 changed files with 50 additions and 34 deletions
+2 -2
View File
@@ -8,7 +8,6 @@
- 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 - Fixed videos loading
- Fixed special characters appearing in toast notifications - Fixed special characters appearing in toast notifications
- Cursor now hides on playback
- 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)
- Extended history information for videos (watching progress) - Extended history information for videos (watching progress)
@@ -17,6 +16,7 @@
- If video is longer than 1 hour ads will be shown every 30 minutes - If video is longer than 1 hour ads will be shown every 30 minutes
- 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
</en-US> </en-US>
<ru-RU>### Что нового: <ru-RU>### Что нового:
- Исправлена проблема получения истории, "Посмотреть позже" и рекомендаций - Исправлена проблема получения истории, "Посмотреть позже" и рекомендаций
@@ -24,7 +24,6 @@
- Исправлено появление водяных занков рекламы на видео при открытии через уведомления - Исправлено появление водяных занков рекламы на видео при открытии через уведомления
- Исправлена загрузка видео - Исправлена загрузка видео
- Исправлено появление особых символов в уведомлениях - Исправлено появление особых символов в уведомлениях
- Теперь курсор скрывается при просмотре
- Редизайн страницы истории - Редизайн страницы истории
- Добавлено управление историей просмотра приложения (не влияет на историю просмотров на сайте) - Добавлено управление историей просмотра приложения (не влияет на историю просмотров на сайте)
- Расширенная информация о просмотренном видео (прогресс просмотра) - Расширенная информация о просмотренном видео (прогресс просмотра)
@@ -33,6 +32,7 @@
- Если видео длится более 1 часа, рекламный баннер будет появляться каждые 30 минут - Если видео длится более 1 часа, рекламный баннер будет появляться каждые 30 минут
- Добавлен режим инкогнито (доступен в контекстном меню видео карточки) - Добавлен режим инкогнито (доступен в контекстном меню видео карточки)
- Подсказки при поиске работают плавнее - Подсказки при поиске работают плавнее
- Теперь на кнопке отключения рекламы отображается текущая цена
</ru-RU> </ru-RU>
</content> </content>
</item> </item>
+1 -1
View File
@@ -257,7 +257,7 @@ namespace FoxTube
if (!requset.Products["9NP1QK556625"].IsInUserCollection) if (!requset.Products["9NP1QK556625"].IsInUserCollection)
{ {
AdsDisabled = false; AdsDisabled = false;
Purchased?.Invoke(args:false); Purchased?.Invoke(null, false, requset.Products["9NP1QK556625"].Price.FormattedPrice);
} }
} }
catch { } catch { }
+36 -2
View File
@@ -1,35 +1,69 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.IO;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using YoutubeExplode.Models.MediaStreams; using YoutubeExplode.Models.MediaStreams;
using Windows.Media.Editing; using Windows.Media.Editing;
using Windows.Media.Core; using Windows.Media.Core;
using Windows.Storage; using Windows.Storage;
using Windows.UI.Xaml.Controls;
using System.Net;
using YoutubeExplode;
namespace FoxTube.Classes namespace FoxTube.Classes
{ {
public class VideoProcessor public class VideoProcessor
{ {
public VideoPlayer Player { get; set; } public MediaElement Player { get; set; }
MediaComposition composition = new MediaComposition(); MediaComposition composition = new MediaComposition();
StorageFolder roaming = ApplicationData.Current.RoamingFolder; StorageFolder roaming = ApplicationData.Current.RoamingFolder;
StorageFile audioCache; StorageFile audioCache;
StorageFile videoCache; StorageFile videoCache;
public async Task<MediaStreamSource> GetStream(MediaStreamInfo video, MediaStreamInfo audio) 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); audioCache = await roaming.CreateFileAsync("audioCache.mp4", CreationCollisionOption.ReplaceExisting);
videoCache = await roaming.CreateFileAsync("videoCache.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.BackgroundAudioTracks.Add(await BackgroundAudioTrack.CreateFromFileAsync(audioCache));
composition.Clips.Add(await MediaClip.CreateFromFileAsync(videoCache)); composition.Clips.Add(await MediaClip.CreateFromFileAsync(videoCache));
return composition.GenerateMediaStreamSource(); 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 -2
View File
@@ -8,8 +8,7 @@
mc:Ignorable="d" mc:Ignorable="d"
d:DesignHeight="1080" d:DesignHeight="1080"
d:DesignWidth="1920" d:DesignWidth="1920"
RequestedTheme="Dark" RequestedTheme="Dark">
PointerMoved="UserControl_PointerMoved">
<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"> <MediaElement Name="videoSource" MarkerReached="VideoSource_MarkerReached" AreTransportControlsEnabled="True" PosterSource="ms-appx:///Assets/videoThumbSample.png" CurrentStateChanged="VideoSource_CurrentStateChanged" MediaOpened="VideoSource_MediaOpened" VolumeChanged="VideoSource_VolumeChanged">
+8 -26
View File
@@ -1,5 +1,4 @@
using System; using System;
using System.Linq;
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;
@@ -9,9 +8,9 @@ using Windows.Media;
using Windows.Storage.Streams; using Windows.Storage.Streams;
using YoutubeExplode.Models.MediaStreams; using YoutubeExplode.Models.MediaStreams;
using YoutubeExplode; using YoutubeExplode;
using System.Diagnostics; using System.IO;
using Windows.Foundation;
using FoxTube.Classes; using FoxTube.Classes;
using Windows.Media.Core;
namespace FoxTube namespace FoxTube
{ {
@@ -31,9 +30,7 @@ namespace FoxTube
set { videoSource.Position = value; } set { videoSource.Position = value; }
} }
VideoProcessor processor = new VideoProcessor(); VideoProcessor processor;
DispatcherTimer cursorTimer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(5) };
TimeSpan timecodeBackup; TimeSpan timecodeBackup;
bool needUpdateTimecode = false; bool needUpdateTimecode = false;
@@ -95,20 +92,11 @@ namespace FoxTube
public void InitializeContols() public void InitializeContols()
{ {
videoSource.Volume = SettingsStorage.Volume; processor = new VideoProcessor
cursorTimer.Tick += (s, e) =>
{ {
Point cursorPoint = CoreWindow.GetForCurrentThread().PointerPosition; Player = videoSource
cursorPoint.X -= Window.Current.Bounds.X;
cursorPoint.Y -= Window.Current.Bounds.Y;
Rect playerBounds = TransformToVisual(Methods.MainPage).TransformBounds(new Rect(0, 0, ActualWidth, ActualHeight));
if((cursorPoint.Y > playerBounds.Top && cursorPoint.Y < playerBounds.Bottom &&
cursorPoint.X > playerBounds.Left && cursorPoint.X < playerBounds.Right) || videoSource.IsFullWindow)
CoreWindow.GetForCurrentThread().PointerCursor = null;
cursorTimer.Stop();
}; };
videoSource.Volume = SettingsStorage.Volume;
Controls.CloseRequested += Controls_CloseRequested; Controls.CloseRequested += Controls_CloseRequested;
Controls.NextRequested += (s, e) => NextClicked?.Invoke(); Controls.NextRequested += (s, e) => NextClicked?.Invoke();
@@ -155,7 +143,8 @@ namespace FoxTube
if (requestedQuality is MuxedStreamInfo) if (requestedQuality is MuxedStreamInfo)
videoSource.Source = requestedQuality.Url.ToUri(); videoSource.Source = requestedQuality.Url.ToUri();
else else
videoSource.SetMediaStreamSource(await processor.GetStream(requestedQuality, list.Audio.First())); videoSource.SetPlaybackSource(MediaSource.CreateFromStream((await new YoutubeClient().GetMediaStreamAsync(requestedQuality)).AsRandomAccessStream(), "video"));
//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)
@@ -235,12 +224,5 @@ namespace FoxTube
{ {
Controls.Advert.PushAdvert(); Controls.Advert.PushAdvert();
} }
private void UserControl_PointerMoved(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
{
if (CoreWindow.GetForCurrentThread().PointerCursor == null)
CoreWindow.GetForCurrentThread().PointerCursor = new CoreCursor(CoreCursorType.Arrow, 0);
cursorTimer.Start();
}
} }
} }
+1 -1
View File
@@ -126,7 +126,7 @@
</ui:NavigationViewItem.Icon> </ui:NavigationViewItem.Icon>
</ui:NavigationViewItem>--> </ui:NavigationViewItem>-->
<ui:NavigationViewItem x:Uid="/Main/adsFree" 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="&#xE14D;"/> <FontIcon Glyph="&#xE14D;"/>
</ui:NavigationViewItem.Icon> </ui:NavigationViewItem.Icon>
+1
View File
@@ -45,6 +45,7 @@ namespace FoxTube
SecretsVault.Purchased += async (sender, e) => SecretsVault.Purchased += async (sender, e) =>
{ {
removeAds.Visibility = (e[0] as bool?).Value ? Visibility.Collapsed : Visibility.Visible; removeAds.Visibility = (e[0] as bool?).Value ? Visibility.Collapsed : Visibility.Visible;
removeAds.Content = $"{resources.GetString("/Main/adsFree/Content")} ({e[1]})";
if (!(bool)e[0]) if (!(bool)e[0])
return; return;