自己添加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中.