- Cursor hiding on playback removed
- Ad free version price is displayed now - Video player muxed streams playback development
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
@@ -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 { }
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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">
|
||||||
|
|||||||
@@ -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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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=""/>
|
<FontIcon Glyph=""/>
|
||||||
</ui:NavigationViewItem.Icon>
|
</ui:NavigationViewItem.Icon>
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user