Code Monkey home page Code Monkey logo

ffmevideoplayer's Introduction

目录

这是一个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:

<UserControl x:Class="FFMEVideoPlayer.Player.PlayerControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:FFMEVideoPlayer.Player" 
             Loaded="UserControl_Loaded"
             xmlns:player="clr-namespace:Unosquare.FFME;assembly=ffme"
             mc:Ignorable="d" Name="playerController">
    </UserControl.Resources>
    <Grid>
        <player:MediaElement Name="Media"/>
    </Grid>
</UserControl>

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
{
    /// <summary>
    /// Interaction logic for PlayerControl.xaml
    /// </summary>
    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在本程序中也是不可缺少的引用。 所以引用MediaElement的方式如下:

PlayerControl_xaml

PlayerControl.xaml文件

  • 首先引入ffme.dll的命名空间:
   xmlns:player="clr-namespace:Unosquare.FFME;assembly=ffme"
  • 在Grid中添加MediaElementk控件:
<player:MediaElement Name="Media" HorizontalAlignment="Right" VerticalAlignment="Stretch"/>

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()等方法,有IsPlayingIsOpenIsOpeningMediaStateHasAudio等属性,我们可以通过他们来判断和控制播放状态。

demo中其他内容

定义DelegateCommand命令实现停止、播放功能,定义公有属性监控当前播放状态,当MediaElement播放状态发生改变时Media_PropertyChanged事件被触发来更新监控状态的属性的值。 知道了这些内容,如何定义自已的界面以及功能就随君所欲了。

如何使用FFME

如果想要按照unosquare的指引来做播放器的话,首先要做的就是下载并安装Visual Stuido 2017来使用C#7.0,否则是无法编译成功的。

下载所需内容

下载源码

这里下载unosquare/ffmediaelement整个项目源码,里面有使用FFmpeg封装MediaElemnt的源码,也有使用封装得到的dll的Exmaple,我便是按照他的教程来做的。

下载一个压缩包

这里下载文件并解压。

新建一个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.dllffmpeg.dll文件,复制到你的WPF应用程序的bin/DLL文件夹下。

在新的WPF应用程序中添加引用

在刚才新建的WPF应用程序中添加引用,引用刚刚复制到bin/DLL文件夹中的ffme.dllffmpeg.dll文件。

编辑MainWindow

在MainWindow.xaml中:

  • 添加命名空间:
xmlns:player="clr-namespace:Unosquare.FFME;assembly=ffme"
  • 注册Loaded事件:
Loaded="Window_Loaded"
  • 添加MediaElement控件
<player:MediaElement Name="Media"/>

在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的几个方法,具体内容可以在 Media.Play(); Play上右键转到定义查看其他属性、方法和事件。

感谢

感谢Unosquare Labs提供的解决方案

ffmevideoplayer's People

Contributors

dg-wangtao avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

ffmevideoplayer's Issues

播放延迟

播放一段时间后会越来越慢,有参数可以设置吗?

64bit

如何支持64位呢
选择了编译平台为64,但是首选了32位才可以正常运行
我也试过了去掉首选32位,并且替换ffmpeg为64位的,但是依然无法正常播放

无法生成略缩图

使用原来的FFMPEG,在MediaElement的RenderingVideo事件中可以使用 e.Bitmap.CreateDrawingBitmap()方法生成System.Drawing.Btiamp。但是这个库经过修改,e.Btimap是.WriteableBitmap类型,需要经过转换才能取到Drawing.Bitmap。且某些视频获取略缩图有一定概率会是空白,不清楚这个库的源码是怎样处理的。

RTSP延迟大

通过demo播放一个本地的rtsp摄像头流,延迟很大,如何调优呢?
如果通过FFME播放,也会出现大延迟吗?(ffme方案还没测试)

无法生成略缩图

使用原来的FFMPEG,在MediaElement的RenderingVideo中可以使用 e.Bitmap.CreateDrawingBitmap生成Btiamp。但是经测试这个库经过修改,eBtimap是.WriteableBitmap?需要经过转换,且转换后的图像有一定概率会是空白。不清楚源码是怎样处理的,设置某些属性和事件也不能避免这种情况

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.