# FFMEVideoPlayer **Repository Path**: MwhWeb/FFMEVideoPlayer ## Basic Information - **Project Name**: FFMEVideoPlayer - **Description**: 使用FFmepg封装的WPF MideaElement,可以播放rtsp视频流。感谢 https://github.com/unosquare/ffmediaelement - **Primary Language**: C# - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 4 - **Created**: 2023-11-04 - **Last Updated**: 2023-11-04 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 目录 - [如何使用我的Demo](#如何使用我的demo) - [说明](#说明) - [下载、编译并运行](#下载编译并运行) - [Demo的结构](#demo的结构) - [MainWindow](#mainwindow) - [PlayerController](#playercontroller) - [先贴出只实现播放功能的最简单的代码](#先贴出只实现播放功能的最简单的代码) - [PlayerControl.xaml](#playercontrol_xaml) - [PlayerControl.xaml.cs](#playercontrol_xaml_cs) - [MediaElement](#mediaelement) - [demo中其他内容](#demo中其他内容) - [如何使用FFME](#如何使用ffme) - [下载所需内容](#下载所需内容) - [下载源码](#下载源码) - [下载一个压缩包](#下载一个压缩包) - [新建一个WPF应用程序](#新建一个wpf应用程序) - [编译下载的源码](#编译下载的源码) - [在新的WPF应用程序中添加引用](#在新的wpf应用程序中添加引用) - [编辑MainWindow](#编辑mainwindow) - [MediaElement其他方法与属性](#mediaelement其他方法与属性) - [感谢](#感谢) 这是一个WPF中播放rtsp等流视频文件的示例,使用的方式是使用ffmpeg封装MediaElement来实现的。封装的方法是unosquare做的,我只是把他的成果拿来用罢了,找了好久才找到在wpf中播放rtsp流(当然vlc、nvlc、winform控件和流转bitmap的方式也能实现,但都没有这个效率高而且它不依赖任何其他内容),封装的源码请查看:https://github.com/unosquare/ffmediaelement # 如何使用我的Demo ## 说明 为了方遍别人和我以后更方便地使用demo,我将生成地dll文件和所需其他文件也传到了gihub上,这使得我的文件显得很臃肿,看起来很不专业,但方遍简洁最重要不是么,哈哈。 ## 下载编译并运行 此次我使用Visual Stdio2015进行编程工作,只要你下载下这整个文件(zip或者clone),然后双击`.sln`文件打开解决方案,加载完成`Rebuild`一下,然后点击`Start`按钮即可,首先vs会先下载一些NuGet包,配置完成后会顺利运行,此时你就会看到展示了四个视频直播地窗口。 ## Demo的结构 这是一个非常简单的`UserController`的建立与使用的示例 ### MainWindow MainWindow只是展示了四个`PlayerControl`用户控件而已,`PlayerControl`是我自己写好的播放器控件,它的`SourceStr`属性为依赖项属性,从父窗口获取要播放的rtsp流地址。 ### PlayerController #### 先贴出只实现播放功能的最简单的代码 PlayerControl.xaml: ``` ``` PlayerControl.xaml.cs ``` using Microsoft.Practices.Prism.Commands; using System; using System.Collections.Generic; using System.ComponentModel; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace FFMEVideoPlayer.Player { /// /// Interaction logic for PlayerControl.xaml /// public partial class PlayerControl : UserControl { public PlayerControl() { InitializeComponent(); //必须在为播放器指定uri之前设置FFmpegDirectory的值 //它引用一些依赖的.dll和.exe文件,该文件在../bin/DLL/中 Unosquare.FFME.MediaElement.FFmpegDirectory = Directory.GetCurrentDirectory() + "\\DLL\\"; } private void UserControl_Loaded(object sender, RoutedEventArgs e) { if (SourceStr != null) { //指定播放路径 Media.Source = new Uri(SourceStr); //开始播放 Media.Play(); } } public static readonly DependencyProperty SourceStrProperty = DependencyProperty.Register("SourceStr", typeof(string), typeof(PlayerControl)); public string SourceStr { get { return (string)GetValue(SourceStrProperty); } set { SetValue(SourceStrProperty, value); } } } } ``` `PlayerControl`调用`ffme`封装好的`MediaElement`来实现播放功能。经过封装的`MediaElement`被集成到了我所引用的`ffme.dll`文件中,而`ffmpeg.dll`在本程序中也是不可缺少的引用。 所以引用M`ediaElement`的方式如下: #### PlayerControl_xaml PlayerControl.xaml文件 * 首先引入ffme.dll的命名空间: ``` xmlns:player="clr-namespace:Unosquare.FFME;assembly=ffme" ``` * 在Grid中添加MediaElementk控件: ``` ``` xaml中定义的其他内容只是控制播放/停止等命令的按钮而已,若不需要可以删除掉,不影响播放功能。 #### PlayerControl_xaml_cs PlayerControl.xaml.cs * 注册一个依赖项属性,获取父窗体提供的播放地址 ``` public static readonly DependencyProperty SourceStrProperty = DependencyProperty.Register("SourceStr", typeof(string), typeof(PlayerControl)); public string SourceStr { get { return (string)GetValue(SourceStrProperty); } set { SetValue(SourceStrProperty, value); } } ``` * 在构造函数中首先添加一句: ``` Unosquare.FFME.MediaElement.FFmpegDirectory = Directory.GetCurrentDirectory() + "\\DLL\\"; ``` 这是为了要添加一些播放所需的dll和exe文件,位置在/bin/Debug/DLL,它必须在设置播放器`Source`属性之前执行。 * 而后在控件的`Loaded`事件里为`Media`控件的`Source`属性赋值并令其播放。 ``` private void UserControl_Loaded(object sender, RoutedEventArgs e) { if (SourceStr != null) { //指定播放路径 Media.Source = new Uri(SourceStr); //开始播放 Media.Play(); } } ``` 此时就可以实现最简单的播放功能了。 #### MediaElement MediaElement有`Play()`、`Close()`、`Dispose()`、`Pause()`、`Stop()`等方法,有`IsPlaying`、`IsOpen`、`IsOpening`、`MediaState`、`HasAudio`等属性,我们可以通过他们来判断和控制播放状态。 #### demo中其他内容 定义`DelegateCommand`命令实现停止、播放功能,定义公有属性监控当前播放状态,当`MediaElement`播放状态发生改变时`Media_PropertyChanged`事件被触发来更新监控状态的属性的值。 知道了这些内容,如何定义自已的界面以及功能就随君所欲了。 # 如何使用FFME 如果想要按照[unosquare](https://github.com/unosquare/ffmediaelement)的指引来做播放器的话,首先要做的就是下载并安装Visual Stuido 2017来使用C#7.0,否则是无法编译成功的。 ## 下载所需内容 ### 下载源码 从[这里](https://github.com/unosquare/ffmediaelement)下载unosquare/ffmediaelement整个项目源码,里面有使用FFmpeg封装MediaElemnt的源码,也有使用封装得到的dll的Exmaple,我便是按照他的教程来做的。 ### 下载一个压缩包 从[这里](https://ffmpeg.zeranoe.com/builds/win32/shared/ffmpeg-3.3.2-win32-shared.zip)下载文件并解压。 ### 新建一个WPF应用程序 在VS中新建一个你的播放器WPF程序,我取的名字为`FFMEVideoPlayer`。建立完成之后打开其所在文件夹,依次导航到`FFMEVideoPlayer\FFMEVideoPlayer\bin\Debug`下,新建一个文件夹命名为`DLL`,当然你也可以取别的名字。而后将刚才下载并解压得到的`ffmpeg-3.3.2-win32-shared`文件夹中`bin`文件夹下的3个exe文件和8个dll文件全部复制到`DLL`下。 ### 编译下载的源码 下载下载unosquare/ffmediaelemen完成之后使用VS2017打开`Unosquare.FFME.sln`解决方案,重新生`Unosquare.FFME`项目,生成成功之后打开其所在文件夹,找到`bin/Debug`或者`bin/Release`下生成的`ffme.dll`和`ffmpeg.dll`文件,复制到你的WPF应用程序的`bin/DLL`文件夹下。 ### 在新的WPF应用程序中添加引用 在刚才新建的WPF应用程序中添加引用,引用刚刚复制到`bin/DLL`文件夹中的`ffme.dll`和`ffmpeg.dll`文件。 ### 编辑MainWindow 在MainWindow.xaml中: * 添加命名空间: ``` xmlns:player="clr-namespace:Unosquare.FFME;assembly=ffme" ``` * 注册Loaded事件: ``` Loaded="Window_Loaded" ``` * 添加MediaElement控件 ``` ``` 在MainWindow.xaml.cs中: * 修改Loaded事件: ``` private void Window_Loaded(object sender, RoutedEventArgs e) { //必须在为播放器指定uri之前设置FFmpegDirectory的值 //它引用一些依赖的.dll和.exe文件,文件在../bin/DLL/中 Unosquare.FFME.MediaElement.FFmpegDirectory = Directory.GetCurrentDirectory() + "\\DLL\\"; //http://ivi.bupt.edu.cn/hls/cctv1hd.m3u8是cctv1直播地址 Media.Source = new Uri("http://ivi.bupt.edu.cn/hls/cctv1hd.m3u8); //开始播放 Media.Play(); } ``` 此时运行你的程序,稍等一会就回看到cctv1的直播节目了。 ### MediaElement其他方法与属性 [这里](#mediaelement)简要说了下`MediaElement`的几个方法,具体内容可以在` Media.Play();`的` Play`上右键转到定义查看其他属性、方法和事件。 # 感谢 感谢[Unosquare Labs](https://github.com/unosquare)提供的解决方案