自己添加Slider控件(Name:PlaySlider)
隐藏MediaPlayerElement自带的控制条,设置AreTransportControlsEnabled="False"
1.添加自定义计时器
CheckTimer = new DispatcherTimer();
CheckTimer.Interval = TimeSpan.FromMilliseconds(1000);
CheckTimer.Start();
CheckTimer.Tick += (timer, e2vent) =>
{
PlaySlider.Value += CheckTimer.Interval.TotalSeconds;// ((TimeSpan)mediaElement.MediaPlayer.TimelineController.Position).TotalSeconds;
};
本来想用
PlaySlider.Value = mediaElement.MediaPlayer.TimelineController.Position.TotalSeconds;
来进行更新进度条
但是崩溃.所以用累加计时器interVal方式.
计时器时间间隔设置为1s即可,slider不需要和播放时间对应的严丝合缝,只需要报告播放的大体进度即可.1s以内的误差完全可以接受.
****
2.使进度条可以拖拽
//
PlaySlider.Tapped += (s,e)=> {
mediaElement.MediaPlayer.PlaybackSession.Position = TimeSpan.FromSeconds((s as Slider).Value);
};
//
因为Slider的Value一直会被计时器改变,因此不能使用valuechanged事件处理进度拖拽.改为使用Tappped事件效果也不错.点击可以,拖拽没反应.
如果支持拖拽,还应该在PointerMove事件中添加代码:
// 让进度条支持拖动
if (e.GetCurrentPoint(this).Properties.IsLeftButtonPressed)
{
mediaElement.MediaPlayer.PlaybackSession.Position = TimeSpan.FromSeconds(PlaySlider.Value);
}
鼠标移动的同时,如果鼠标左键是按下的状态,就变更播放位置.
点击效果很好,拖拽可能会触发很多次,略有卡顿,但是ValueChanged不能用.另外双向绑定Position经过实验也是不管用的.,目前暂时就用这个方式
3.添加图像预览
效果如图中所示.当鼠标放在进度条上,显示视频画面.
给订阅Slider的MouseMove和MouseLeft事件.
bool IsBusyGrabbing = false;
TimeSpan lastPosition;
private async void PlaySlider_PointerMoved(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
{
e.Handled = true;
if (IsBusyGrabbing)
{
return;
}
Debug.WriteLine("Pointer Moved");
try
{
var slider = sender as Slider;
var length = slider.Width;
var pointerPosition = e.GetCurrentPoint(slider).Position;
var positionSecond = PlaySlider.Maximum * pointerPosition.X / slider.Width;
var VideoPosition = TimeSpan.FromSeconds(positionSecond);
//如果时间间隔变化很小 <1 s 则不处理
if (lastPosition!=null)
{
if (Math.Abs((VideoPosition - lastPosition).TotalSeconds) <1)
{
return;
}
}
lastPosition = VideoPosition;
// 显示鼠标位置的对应的时刻
PointerTimeDisplayTextBlock.Text = VideoPosition.ToString(@"hh\:mm\:ss");
// 获取 鼠标坐标
var pointerPositionOfWindow = e.GetCurrentPoint(this).Position;
IsBusyGrabbing = true;
PreviewImage.Source = await GetThumbnailAsync(null, VideoPosition);
IsBusyGrabbing = false;
// 获取slider 坐标
var t = PlaySlider.TransformToVisual(Window.Current.Content);
Windows.Foundation.Point screenCoords = t.TransformPoint(new Windows.Foundation.Point(0, 0));
PreviewImage_CT.TranslateX = pointerPositionOfWindow.X-170;
PreviewImage_CT.TranslateY = screenCoords.Y - 180;// pointerPositionOfWindow.Y
PreViewStack.Opacity = 1;
}
catch (Exception)
{
}
}
private void PlaySlider_PointerExited(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
{
Task.Run(async ()=> {
do
{
await Task.Delay(200);
}
while (IsBusyGrabbing);
await PreViewStack.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,()=> {
PreViewStack.Opacity = 0;
});
});
Debug.WriteLine("Pointer Left");
}
简单地说,播放器中一直有一个Image控件的,获取视频播放位置的截图图片源,调整Image控件的位置,鼠标进入移动显示,离开隐藏.
另外Slider控件还有一个ThumbToolTipValueConverter="{StaticResource double2TimeStringConvert}" 属性,
和正常的Converter用法一样,可以吧Value换算成 时间 的 字符格式 显示thumb滑块在tooltip中.