Skip to content
This repository has been archived by the owner on Dec 20, 2023. It is now read-only.

支持播放界面长按以倍速播放 #1100

Merged
merged 2 commits into from
Apr 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Richasy.Bili.Models.Enums.App;
using Richasy.Bili.ViewModels.Uwp;
using Richasy.Bili.ViewModels.Uwp.Common;
using Windows.UI.Input;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
Expand Down Expand Up @@ -106,6 +107,7 @@ public partial class BiliPlayerTransportControls
private VisualStateGroup _visibilityStateGroup;
private Button _formatButton;
private Button _liveQualityButton;
private GestureRecognizer _gestureRecognizer;

private int _segmentIndex;
private double _cursorStayTime;
Expand All @@ -122,6 +124,7 @@ public partial class BiliPlayerTransportControls
private PlayerManipulationType _manipulationType = PlayerManipulationType.None;

private bool _isTouch = false;
private bool _isHolding = false;

/// <summary>
/// 实例.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
using Richasy.Bili.ViewModels.Uwp;
using Windows.Foundation;
using Windows.Media.Playback;
using Windows.UI.Input;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
Expand Down Expand Up @@ -109,6 +110,8 @@ protected override void OnApplyTemplate()
_formatButton = GetTemplateChild(FormatButtonName) as Button;
_liveQualityButton = GetTemplateChild(LiveQualityButtonName) as Button;
_rootGrid = GetTemplateChild(RootGridName) as Grid;
_gestureRecognizer = new GestureRecognizer();
_gestureRecognizer.GestureSettings = GestureSettings.HoldWithMouse | GestureSettings.Hold;

_fullWindowPlayModeButton.Click += OnPlayModeButtonClick;
_fullScreenPlayModeButton.Click += OnPlayModeButtonClick;
Expand All @@ -119,6 +122,11 @@ protected override void OnApplyTemplate()
_interactionControl.ManipulationStarted += OnInteractionControlManipulationStarted;
_interactionControl.ManipulationDelta += OnInteractionControlManipulationDelta;
_interactionControl.ManipulationCompleted += OnInteractionControlManipulationCompleted;
_interactionControl.PointerPressed += OnInteractionControlPointerPressed;
_interactionControl.PointerMoved += OnInteractionControlPointerMoved;
_interactionControl.PointerReleased += OnInteractionControlPointerReleased;
_interactionControl.PointerCanceled += OnInteractionControlPointerCanceled;
_gestureRecognizer.Holding += OnGestureRecognizerHoldingAsync;
_backButton.Click += OnBackButtonClick;
_danmakuBarVisibilityButton.Click += OnDanmakuBarVisibilityButtonClick;
_homeButton.Click += OnHomeButtonClickAsync;
Expand Down Expand Up @@ -234,6 +242,18 @@ private void OnSendDanmakuSucceeded(object sender, string e)
_danmakuView.SendDanmu(model);
}

private void OnInteractionControlPointerCanceled(object sender, PointerRoutedEventArgs e)
=> _gestureRecognizer.ProcessUpEvent(e.GetCurrentPoint(this));

private void OnInteractionControlPointerReleased(object sender, PointerRoutedEventArgs e)
=> _gestureRecognizer.ProcessUpEvent(e.GetCurrentPoint(this));

private void OnInteractionControlPointerMoved(object sender, PointerRoutedEventArgs e)
=> _gestureRecognizer.ProcessMoveEvents(e.GetIntermediatePoints(this));

private void OnInteractionControlPointerPressed(object sender, PointerRoutedEventArgs e)
=> _gestureRecognizer.ProcessDownEvent(e.GetCurrentPoint(this));

private void OnBackButtonClick(object sender, RoutedEventArgs e)
{
ViewModel.PlayerDisplayMode = PlayerDisplayMode.Default;
Expand Down Expand Up @@ -295,6 +315,12 @@ private async void OnLiveQualityListViewSelectionChangedAsync(object sender, Sel

private void OnInteractionControlTapped(object sender, TappedRoutedEventArgs e)
{
if (_isHolding)
{
_isHolding = false;
return;
}

if (e.PointerDeviceType == Windows.Devices.Input.PointerDeviceType.Mouse)
{
_isTouch = false;
Expand Down Expand Up @@ -824,6 +850,30 @@ private void OnInteractionControlManipulationCompleted(object sender, Manipulati
_manipulationBeforeIsPlay = false;
}

private async void OnGestureRecognizerHoldingAsync(GestureRecognizer sender, HoldingEventArgs args)
{
if (args.ContactCount == 1)
{
_isHolding = true;
if (args.HoldingState == HoldingState.Started)
{
// 开启倍速播放.
var isStarted = await ViewModel.StartTempQuickPlayAsync();
if (isStarted)
{
var resourceToolkit = ServiceLocator.Instance.GetService<IResourceToolkit>();
ShowTempMessage(resourceToolkit.GetLocaleString(LanguageNames.StartQuickPlay));
}
}
else
{
// 停止倍速播放.
await ViewModel.StopTempQuickPlayAsync();
HideTempMessage();
}
}
}

private void OnInteractionControlManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
if (ViewModel.PlayerStatus != PlayerStatus.Playing && ViewModel.PlayerStatus != PlayerStatus.Pause)
Expand Down
3 changes: 3 additions & 0 deletions src/App/Resources/Strings/zh-CN/Resources.resw
Original file line number Diff line number Diff line change
Expand Up @@ -1424,6 +1424,9 @@ BV号以 BV 开头,是一串英文数字混合的编号, 如 BV1JL4y1875w</v
<data name="StartMethodDescription" xml:space="preserve">
<value>您可以选择应用的启动方式以更快速地打开应用</value>
</data>
<data name="StartQuickPlay" xml:space="preserve">
<value>开始倍速播放</value>
</data>
<data name="Startup" xml:space="preserve">
<value>自启动</value>
</data>
Expand Down
1 change: 1 addition & 0 deletions src/Models/Models.Enums/App/LanguageNames.cs
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,7 @@ public enum LanguageNames
SomeoneLiveRoom,
FixContent,
UnfixContent,
StartQuickPlay,
#pragma warning restore SA1602 // Enumeration items should be documented
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ public partial class PlayerViewModel

private bool _isFirstShowHistory;

private double _originalPlayRate;
private double _originalDanmakuSpeed;

/// <summary>
/// 让直播消息视图滚动到底部.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -878,6 +878,51 @@ public async Task ToggleFixStateAsync()
IsContentFixed = !IsContentFixed;
}

/// <summary>
/// 开始临时快进.
/// </summary>
/// <returns><see cref="Task"/>.</returns>
public async Task<bool> StartTempQuickPlayAsync()
{
if (_currentVideoPlayer == null
|| _currentVideoPlayer.PlaybackSession == null
|| _currentVideoPlayer.PlaybackSession.PlaybackState != Windows.Media.Playback.MediaPlaybackState.Playing
|| PlaybackRate >= 3)
{
return false;
}

await AppViewModel.Instance.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
_originalPlayRate = PlaybackRate;
_originalDanmakuSpeed = DanmakuViewModel.Instance.DanmakuSpeed;
PlaybackRate = PlaybackRate * 2 > 3 ? 3 : PlaybackRate * 2;
DanmakuViewModel.Instance.DanmakuSpeed = _originalDanmakuSpeed * 1.5 > 2 ? 2 : _originalDanmakuSpeed * 1.5;
});

return true;
}

/// <summary>
/// 停止临时快进.
/// </summary>
/// <returns><see cref="Task"/>.</returns>
public async Task StopTempQuickPlayAsync()
{
if (_originalDanmakuSpeed <= 0 || _originalPlayRate <= 0)
{
return;
}

await AppViewModel.Instance.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
PlaybackRate = _originalPlayRate;
DanmakuViewModel.Instance.DanmakuSpeed = _originalDanmakuSpeed;
_originalPlayRate = 0;
_originalDanmakuSpeed = 0;
});
}

private void OnDataRequested(DataTransferManager sender, DataRequestedEventArgs args)
{
var request = args.Request;
Expand Down