C# wpf 使用ffplay实现视频播放器

ffplay自定义系列

第一章 自定义播放器接口
第二章 倍速播放
第三章 dxva2硬解渲染
第四章 提供C#接口
第五章 制作wpf播放器(本章)


文章目录

  • ffplay自定义系列
  • 前言
  • 一、播放模块
  • 二、界面
    • 1、关键实现
      • (1)、圆角边框
      • (2)、拖动移动调整大小
      • (3)、播放
      • (4)、停止
      • (4)、进度条
      • (5)、关闭播放
    • 2、效果预览
  • 三、下载
  • 总结


前言

有了《WPF视频渲染系列》的视频渲染方法,再结合笔者已有的一个定制化ffplay播放器《基于ffplay改造成自定义多开播放器》,我们可以很容易的在wpf中实现一个播放器软件,这个播放器可以支持本地播放、摄像头播放、网络点播、rtmp和rtsp拉流。


一、播放模块

参考第四章 提供C#接口


二、界面

由于使用wpf制作界面所以很多酷炫的效果都可以做,界面可以做的比较好看。

1、关键实现

(1)、圆角边框

圆角边框需要设置窗口透明,如果使用AllowsTransparency=“True”,会严重影响性能,可能导致渲染视频卡顿。我使用的是WindowChrome.WindowChrome实现圆角边框。具体代码就不贴出了,网上可以找到解决方案。
还有一个关键点是不能使用窗口阴影,会影响d3dImage渲染性能。

(2)、拖动移动调整大小

由于使用了WindowChrome.WindowChrome实现无边框圆角窗口,所有移动和调整大小功能基本要自己实现了。参考《C# wpf 附加属性实现任意控件(包括窗口)拖动》、《C# wpf 附加属性实现任意控件拖动调整大小》

(3)、播放

由于在界面上渲染视频,且播放中再次Start内部会先调用Stop,Stop是同步实现的,在渲染或停止事件有Invoke时停止容易造成死锁,所以需要判断播放中时异步Stop后再Start。

 async void StartPlay(string url)
 {   
     if (_isStarted)
     {
         await Task.Run(() =>
         {
             _play.Stop();
         });
         _play.Start(url);
         _isStarted = true;    
     }
     else
     {
         _play.Start(url);
         _isStarted = true;    
     }
 }

(4)、停止

与上面相同,停止的时候需要异步停止。

private async void Stop_Button_Click(object sender, RoutedEventArgs e)
{
    await Task.Run(() =>
  {
      _play.Stop();
  });
  _isStarted = false;  
}

(4)、进度条

参考《C# wpf slider实现显示进度、拖动定位、点击定位功能》

(5)、关闭播放

关闭窗口时,使用同步接口停止播放器会导致死锁:主线程等待渲染线程结束,同时渲染线程等待主线程invoke。所以我们需要异步停止来防止死锁。

示例代码如下:

private async void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
    if (_play == null)
        return;
    e.Cancel = true;
    //异步退出,防止死锁
    await Task.Run(() =>
    {
        _play.Dispose();
    });
    _play = null;
    Close();
}

2、效果预览

C# wpf 使用ffplay实现视频播放器_第1张图片

C# wpf 使用ffplay实现视频播放器_第2张图片

C# wpf 使用ffplay实现视频播放器_第3张图片
C# wpf 使用ffplay实现视频播放器_第4张图片


三、下载

https://download.csdn.net/download/u013113678/85437645

注:资源只包含C#源码,C语言播放器模块只提供x86dll,请根据需要下载。C#源码包含了《WPF视频渲染系列》的所有内容,切勿重复下载。


总结

实现一个视频播放器基于ffplay,功能是很强大的同时也具有足够的稳定性,但是其内部实现代码庞杂,改造起来还是不太容易的,而且其功能也不是绝对完善的很多地方需要拓展和优化,比如精准定位、倍速播放、硬解渲染。有一个定制化的底层播放器后,利用wpf的界面优势很容易的就做出一个可以日常使用的播放器。当前版本的播放器功能相对简单,还不足以当成日常使用,还缺少平滑拖动定位、音轨选择、字幕播放以及声音放大等功能。

你可能感兴趣的:(音视频,#,wpf,c++,c#,wpf,音视频,ffmpeg)