原文:c#万能视频播放器(附代码)

c#万能视频播放器

  本人之前很多的文章中均提到了使用libvlc为播放器内核制作的播放器,也许有些朋友对此感兴趣,于是我用c#写了一个调用libvlc api实现的万能视频播放器,与大家分享一下。说它“万能”,当然是因为我们站在了vlc的肩膀上。

  vlc是一个强大而且开源的多媒体播放器,也可以说是一个多媒体平台。它支持非常广泛的媒体格式的本地播放,完全可以媲美mplayer,其对视频网络流的处理能力更是非常强悍。libvlc就是指的vlc的核心,它向外提供了一系列的接口,通过接口,来实现视频播放等复杂的功能。libvlc对外提供了c语言的接口,也有其他语言,包括.net的绑定,在其官网上就有,不过已经“年久失修”。我之前用Qt, MFC实现过基于libvlc的播放器,不过鉴于园子里c#开发人员较多,遂用c#封装了一下libvlc的API接口,并实现了一个视频播放器。

  先上鉴赏图,外表很简单,不过,外表不是重点:)

 

  

  首先是libvlc的一些导出函数,我在注释里对它们的功能都有说明

  1. // 创建一个libvlc实例,它是引用计数的
    [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
    [SuppressUnmanagedCodeSecurity]
    private static extern IntPtr libvlc_new(int argc, IntPtr argv);

    // 释放libvlc实例
    [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
    [SuppressUnmanagedCodeSecurity]
    public static extern void libvlc_release(IntPtr libvlc_instance);

    [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
    [SuppressUnmanagedCodeSecurity]
    public static extern String libvlc_get_version();

    // 从视频来源(例如Url)构建一个libvlc_meida
    [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
    [SuppressUnmanagedCodeSecurity]
    private static extern IntPtr libvlc_media_new_location(IntPtr libvlc_instance, IntPtr path);

    // 从本地文件路径构建一个libvlc_media
    [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
    [SuppressUnmanagedCodeSecurity]
    private static extern IntPtr libvlc_media_new_path(IntPtr libvlc_instance, IntPtr path);

    [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
    [SuppressUnmanagedCodeSecurity]
    public static extern void libvlc_media_release(IntPtr libvlc_media_inst);

    // 创建libvlc_media_player(播放核心)
    [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
    [SuppressUnmanagedCodeSecurity]
    public static extern IntPtr libvlc_media_player_new(IntPtr libvlc_instance);

    // 将视频(libvlc_media)绑定到播放器上
    [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
    [SuppressUnmanagedCodeSecurity]
    public static extern void libvlc_media_player_set_media(IntPtr libvlc_media_player, IntPtr libvlc_media);

    // 设置图像输出的窗口
    [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
    [SuppressUnmanagedCodeSecurity]
    public static extern void libvlc_media_player_set_hwnd(IntPtr libvlc_mediaplayer, Int32 drawable);

    [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
    [SuppressUnmanagedCodeSecurity]
    public static extern void libvlc_media_player_play(IntPtr libvlc_mediaplayer);

    [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
    [SuppressUnmanagedCodeSecurity]
    public static extern void libvlc_media_player_pause(IntPtr libvlc_mediaplayer);

    [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
    [SuppressUnmanagedCodeSecurity]
    public static extern void libvlc_media_player_stop(IntPtr libvlc_mediaplayer);

    // 解析视频资源的媒体信息(如时长等)
    [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
    [SuppressUnmanagedCodeSecurity]
    public static extern void libvlc_media_parse(IntPtr libvlc_media);

    // 返回视频的时长(必须先调用libvlc_media_parse之后,该函数才会生效)
    [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
    [SuppressUnmanagedCodeSecurity]
    public static extern Int64 libvlc_media_get_duration(IntPtr libvlc_media);

    // 当前播放的时间
    [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
    [SuppressUnmanagedCodeSecurity]
    public static extern Int64 libvlc_media_player_get_time(IntPtr libvlc_mediaplayer);

    // 设置播放位置(拖动)
    [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
    [SuppressUnmanagedCodeSecurity]
    public static extern void libvlc_media_player_set_time(IntPtr libvlc_mediaplayer, Int64 time);

    [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
    [SuppressUnmanagedCodeSecurity]
    public static extern void libvlc_media_player_release(IntPtr libvlc_mediaplayer);

    // 获取和设置音量
    [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
    [SuppressUnmanagedCodeSecurity]
    public static extern int libvlc_audio_get_volume(IntPtr libvlc_media_player);

    [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
    [SuppressUnmanagedCodeSecurity]
    public static extern void libvlc_audio_set_volume(IntPtr libvlc_media_player, int volume);

    // 设置全屏
    [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
    [SuppressUnmanagedCodeSecurity]
    public static extern void libvlc_set_fullscreen(IntPtr libvlc_media_player, int isFullScreen);

  

  要使用libvlc api进行播放,首先需要创建一个libvlc的实例,就是lbvlc_instance,之后所有的操作都是基于这个实例来完成。

  每一个播放窗口,对应一个libvlc_media_player,而每一个媒体文件,就是一个libvlc_media。所以,调用的步骤就是:

    1. 创建libvlc_instance
    2. 创建libvlc_media_player
    3. 开始播放时,创建libvlc_media,通知libvlc_media_player要播放的媒体文件,之后就可以释放libvlc_media了
    4. 操作libvlc_media_player,实现播放、暂停等功能

  下面对这些操作进行封装,以供上层使用。

  1. class VlcPlayer
    {
    private IntPtr libvlc_instance_;
    private IntPtr libvlc_media_player_;

    private double duration_;

    public VlcPlayer(string pluginPath)
    {
    string plugin_arg = "--plugin-path=" + pluginPath;
    string[] arguments = { "-I", "dummy", "--ignore-config", "--no-video-title", plugin_arg };
    libvlc_instance_ = LibVlcAPI.libvlc_new(arguments);

    libvlc_media_player_ = LibVlcAPI.libvlc_media_player_new(libvlc_instance_);
    }

    public void SetRenderWindow(int wndHandle)
    {
    if (libvlc_instance_ != IntPtr.Zero && wndHandle != )
    {
    LibVlcAPI.libvlc_media_player_set_hwnd(libvlc_media_player_, wndHandle);
    }
    }

    public void PlayFile(string filePath)
    {
    IntPtr libvlc_media = LibVlcAPI.libvlc_media_new_path(libvlc_instance_, filePath);
    if (libvlc_media != IntPtr.Zero)
    {
    LibVlcAPI.libvlc_media_parse(libvlc_media);
    duration_ = LibVlcAPI.libvlc_media_get_duration(libvlc_media) / 1000.0;

    LibVlcAPI.libvlc_media_player_set_media(libvlc_media_player_, libvlc_media);
    LibVlcAPI.libvlc_media_release(libvlc_media);

    LibVlcAPI.libvlc_media_player_play(libvlc_media_player_);
    }
    }

    public void Pause()
    {
    if (libvlc_media_player_ != IntPtr.Zero)
    {
    LibVlcAPI.libvlc_media_player_pause(libvlc_media_player_);
    }
    }

    public void Stop()
    {
    if (libvlc_media_player_ != IntPtr.Zero)
    {
    LibVlcAPI.libvlc_media_player_stop(libvlc_media_player_);
    }
    }

    public double GetPlayTime()
    {
    return LibVlcAPI.libvlc_media_player_get_time(libvlc_media_player_) / 1000.0;
    }

    public void SetPlayTime(double seekTime)
    {
    LibVlcAPI.libvlc_media_player_set_time(libvlc_media_player_, (Int64)(seekTime * ));
    }

    public int GetVolume()
    {
    return LibVlcAPI.libvlc_audio_get_volume(libvlc_media_player_);
    }

    public void SetVolume(int volume)
    {
    LibVlcAPI.libvlc_audio_set_volume(libvlc_media_player_, volume);
    }

    public void SetFullScreen(bool istrue)
    {
    LibVlcAPI.libvlc_set_fullscreen(libvlc_media_player_, istrue ? : );
    }

    public double Duration()
    {
    return duration_;
    }

    public string Version()
    {
    return LibVlcAPI.libvlc_get_version();
    }
    }

  封装为VlcPlayer之后,调用就会变得非常简单。

  • 首先确定好vlc的插件目录
  • 在你的代码里创建VlcPlayer对象
  • 调用SetRenderWindow,以设置视频显示的窗口,否则会变成一个独立的播放窗口
  • 调用PlayFile,即可开始播放

  程序做好之后,需要带上libvlc.dlllibvlccore.dll,这两个是vlc的播放内核,因为vlc把编解码和格式解析的支持设计成了插件的形式,所以还必须要带上vlc的plugins目录里的插件。

  我把整个工程打包(包括libvlc.dlllibvlccore.dll)上传到了博客上,点击这里,就可以下载。

  plugins目录文件有点大(因为libvlc支持的格式和功能非常多,如果你不需要,删掉对应插件即可),我放到了115网盘,下载地址是http://115.com/file/dnre4jg7#plugins.7z。下载后放到“bin/Debug”目录即可调试运行。

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

haibindev.cnblogs.com,合作请联系QQ。(转载请注明作者和出处)

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

c#万能视频播放器(附代码)的更多相关文章

  1. c#万能视频播放器

    http://blog.csdn.net/yanzhibo/article/details/8972822 本人之前很多的文章中均提到了使用libvlc为播放器内核制作的播放器,也许有些朋友对此感兴趣 ...

  2. C# VLCPlayer视频播放器(附源码)

    VLCPlayer视频播放器. 支持本地播放,支持网络URL.支持全屏,截图. 基于VLCPlayer. 附带基本代码. 下载地址:http://pan.baidu.com/s/1nvjNvID

  3. Android 音视频深入 十九 使用ijkplayer做个视频播放器(附源码下载)

    项目地址https://github.com/979451341/Myijkplayer 前段时候我觉得FFmpeg做个视频播放器好难,虽然播放上没问题,但暂停还有通过拖动进度条来设置播放进度,这些都 ...

  4. html视频播放器的代码 及其参数详解

    播放视频最实用的一段代码是: 程序代码 <"></embed></object> 其他的看参数自己修改吧 .avi格式 代码片断如下: 程序代码 < ...

  5. ios视频播放器,代码和界面分离

    最近业余时间整理的一个ios播放器,界面采用storyboard,以前几乎都是用代码布局,但是用过一个项目storyboard后,就感觉storyboard很靠谱,团队合作版本控制的问题解决其实很简单 ...

  6. 【Egret】Native版本 视频播放器(android)

    前段时间,领导说客户要一个平板版本的视频播放器,把我们做的一些视频资源放进去,要是本地的:我们部门又没有app开发程序员,正好又前段我在实验egret的app打包功能,就说用egret做(ps:本来想 ...

  7. 在C#中实现视频播放器

    当我们需要在C#中实现视频播放器的时候,可以使用如下几种方法: 一.使用MediaPlayer ActiveX控件 在C#中支持视屏播放器最简单的方式就是插入MediaPlayer控件了,在WPF中还 ...

  8. android视频播放器开发

    http://blog.csdn.net/u010181592/article/details/49301703 http://blog.csdn.net/qq_33291295/article/de ...

  9. QT-简易视频播放器

    一直没找到理由去学一下QT,由于工作原因之后的工作内容会用到QT,于是这两天摸索了下:早上临时决定先做个视频播放器玩一下,于是先用qml发现不会用,无果,于是放弃了使用qml,等之后系统的看一下Jav ...

随机推荐

  1. 创建您自己的Maven模板

    相关链接: http://maven.apache.org/archetype/maven-archetype-plugin/ 一.事实上Maven的模板也是一个maven项目,所以我们首先要生成一个 ...

  2. 大话设计模式C++实现-文章7章-代理模式

    一个.UML画画 二.概念 代理模式:为其它对象提供一种代理以控制对这个对象的訪问. 三.应用场景 (1)远程代理.也就是为一个对象在不同的地址空间提供局部代表.这样能够隐藏一个对象存在于不同地址空间 ...

  3. Log4NET 数据库

    阅读目录 Log4NET简介 前提 详细步骤 回到顶部 Log4NET简介 log4net库是Apache log4j框架在Microsoft .NET平台的实现,是一个帮助程序员将日志信息输出到各种 ...

  4. ScrollView 在嵌套 ViewPager 时出现的问题

    1.在ViewPager 外面嵌套ScrollView 时导致ViewPager 中内容不显示,解决的办法是在ScrollView 标签下增加 android:fillViewport="t ...

  5. 7-days-asp-dotnet-mvc-day1

    目录 第 1 天 第 2 天 第 3 天 第 4 天 第 5 天 第 6 天 第 7 天 0. 前言 今天是开心的一天.因为我们终于来到了系列学习的最后一节.我相信你喜欢之前的课程,并从中学到了许多. ...

  6. EL表达式语言

    EL (Expression Language) 目的:为了使JSP写起来更加简单.表达式语言的灵感来自于 ECMAScript 和 XPath 表达式语言,它提供了在 JSP 中简化表达式的方法. ...

  7. Linux(CentOS)系统下安装好apache(httpd)服务后,其他电脑无法访问的原因

    原文:Linux(CentOS)系统下安装好apache(httpd)服务后,其他电脑无法访问的原因 今天试了下在虚拟机上利用CentOS系统的yum命令安装好了httpd(apache2.4.6), ...

  8. Android(Lollipop/5.0) Material Design(六) 使用图像

    Material Design列 Android(Lollipop/5.0)Material Design(一) 简单介绍 Android(Lollipop/5.0)Material Design(二 ...

  9. NSOJ Constructing Roads(图论)

    There are N villages, which are numbered from 1 to N, and you should build some roads such that ever ...

  10. 由一道面试题想到的:Finally

    找工作时,有这样一道题: try{}里面有一条return语句,那么紧跟在这个try后的finally{}里的代码会不会执行,什么时候执行,在return之前还是之后? 我没有怎么思考,根据脑子里仅有 ...