http://blog.csdn.net/yanzhibo/article/details/8972822

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

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

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

  

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

 1         // 创建一个libvlc实例,它是引用计数的
2 [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
3 [SuppressUnmanagedCodeSecurity]
4 private static extern IntPtr libvlc_new(int argc, IntPtr argv);
5
6 // 释放libvlc实例
7 [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
8 [SuppressUnmanagedCodeSecurity]
9 public static extern void libvlc_release(IntPtr libvlc_instance);
10
11 [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
12 [SuppressUnmanagedCodeSecurity]
13 public static extern String libvlc_get_version();
14
15 // 从视频来源(例如Url)构建一个libvlc_meida
16 [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
17 [SuppressUnmanagedCodeSecurity]
18 private static extern IntPtr libvlc_media_new_location(IntPtr libvlc_instance, IntPtr path);
19
20 // 从本地文件路径构建一个libvlc_media
21 [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
22 [SuppressUnmanagedCodeSecurity]
23 private static extern IntPtr libvlc_media_new_path(IntPtr libvlc_instance, IntPtr path);
24
25 [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
26 [SuppressUnmanagedCodeSecurity]
27 public static extern void libvlc_media_release(IntPtr libvlc_media_inst);
28
29 // 创建libvlc_media_player(播放核心)
30 [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
31 [SuppressUnmanagedCodeSecurity]
32 public static extern IntPtr libvlc_media_player_new(IntPtr libvlc_instance);
33
34 // 将视频(libvlc_media)绑定到播放器上
35 [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
36 [SuppressUnmanagedCodeSecurity]
37 public static extern void libvlc_media_player_set_media(IntPtr libvlc_media_player, IntPtr libvlc_media);
38
39 // 设置图像输出的窗口
40 [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
41 [SuppressUnmanagedCodeSecurity]
42 public static extern void libvlc_media_player_set_hwnd(IntPtr libvlc_mediaplayer, Int32 drawable);
43
44 [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
45 [SuppressUnmanagedCodeSecurity]
46 public static extern void libvlc_media_player_play(IntPtr libvlc_mediaplayer);
47
48 [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
49 [SuppressUnmanagedCodeSecurity]
50 public static extern void libvlc_media_player_pause(IntPtr libvlc_mediaplayer);
51
52 [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
53 [SuppressUnmanagedCodeSecurity]
54 public static extern void libvlc_media_player_stop(IntPtr libvlc_mediaplayer);
55
56 // 解析视频资源的媒体信息(如时长等)
57 [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
58 [SuppressUnmanagedCodeSecurity]
59 public static extern void libvlc_media_parse(IntPtr libvlc_media);
60
61 // 返回视频的时长(必须先调用libvlc_media_parse之后,该函数才会生效)
62 [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
63 [SuppressUnmanagedCodeSecurity]
64 public static extern Int64 libvlc_media_get_duration(IntPtr libvlc_media);
65
66 // 当前播放的时间
67 [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
68 [SuppressUnmanagedCodeSecurity]
69 public static extern Int64 libvlc_media_player_get_time(IntPtr libvlc_mediaplayer);
70
71 // 设置播放位置(拖动)
72 [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
73 [SuppressUnmanagedCodeSecurity]
74 public static extern void libvlc_media_player_set_time(IntPtr libvlc_mediaplayer, Int64 time);
75
76 [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
77 [SuppressUnmanagedCodeSecurity]
78 public static extern void libvlc_media_player_release(IntPtr libvlc_mediaplayer);
79
80 // 获取和设置音量
81 [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
82 [SuppressUnmanagedCodeSecurity]
83 public static extern int libvlc_audio_get_volume(IntPtr libvlc_media_player);
84
85 [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
86 [SuppressUnmanagedCodeSecurity]
87 public static extern void libvlc_audio_set_volume(IntPtr libvlc_media_player, int volume);
88
89 // 设置全屏
90 [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
91 [SuppressUnmanagedCodeSecurity]
92 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
2 {
3 private IntPtr libvlc_instance_;
4 private IntPtr libvlc_media_player_;
5
6 private double duration_;
7
8 public VlcPlayer(string pluginPath)
9 {
10 string plugin_arg = "--plugin-path=" + pluginPath;
11 string[] arguments = { "-I", "dummy", "--ignore-config", "--no-video-title", plugin_arg };
12 libvlc_instance_ = LibVlcAPI.libvlc_new(arguments);
13
14 libvlc_media_player_ = LibVlcAPI.libvlc_media_player_new(libvlc_instance_);
15 }
16
17 public void SetRenderWindow(int wndHandle)
18 {
19 if (libvlc_instance_ != IntPtr.Zero && wndHandle != 0)
20 {
21 LibVlcAPI.libvlc_media_player_set_hwnd(libvlc_media_player_, wndHandle);
22 }
23 }
24
25 public void PlayFile(string filePath)
26 {
27 IntPtr libvlc_media = LibVlcAPI.libvlc_media_new_path(libvlc_instance_, filePath);
28 if (libvlc_media != IntPtr.Zero)
29 {
30 LibVlcAPI.libvlc_media_parse(libvlc_media);
31 duration_ = LibVlcAPI.libvlc_media_get_duration(libvlc_media) / 1000.0;
32
33 LibVlcAPI.libvlc_media_player_set_media(libvlc_media_player_, libvlc_media);
34 LibVlcAPI.libvlc_media_release(libvlc_media);
35
36 LibVlcAPI.libvlc_media_player_play(libvlc_media_player_);
37 }
38 }
39
40 public void Pause()
41 {
42 if (libvlc_media_player_ != IntPtr.Zero)
43 {
44 LibVlcAPI.libvlc_media_player_pause(libvlc_media_player_);
45 }
46 }
47
48 public void Stop()
49 {
50 if (libvlc_media_player_ != IntPtr.Zero)
51 {
52 LibVlcAPI.libvlc_media_player_stop(libvlc_media_player_);
53 }
54 }
55
56 public double GetPlayTime()
57 {
58 return LibVlcAPI.libvlc_media_player_get_time(libvlc_media_player_) / 1000.0;
59 }
60
61 public void SetPlayTime(double seekTime)
62 {
63 LibVlcAPI.libvlc_media_player_set_time(libvlc_media_player_, (Int64)(seekTime * 1000));
64 }
65
66 public int GetVolume()
67 {
68 return LibVlcAPI.libvlc_audio_get_volume(libvlc_media_player_);
69 }
70
71 public void SetVolume(int volume)
72 {
73 LibVlcAPI.libvlc_audio_set_volume(libvlc_media_player_, volume);
74 }
75
76 public void SetFullScreen(bool istrue)
77 {
78 LibVlcAPI.libvlc_set_fullscreen(libvlc_media_player_, istrue ? 1 : 0);
79 }
80
81 public double Duration()
82 {
83 return duration_;
84 }
85
86 public string Version()
87 {
88 return LibVlcAPI.libvlc_get_version();
89 }
90 }

  封装为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”目录即可调试运行。

转载自:http://www.cnblogs.com/haibindev/archive/2011/12/21/2296173.html

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

HaibinDev软件工作室。(版权所有,转载请注明作者和出处~)

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

c#万能视频播放器的更多相关文章

  1. c#万能视频播放器(附代码)

    原文:c#万能视频播放器(附代码) c#万能视频播放器 本人之前很多的文章中均提到了使用libvlc为播放器内核制作的播放器,也许有些朋友对此感兴趣,于是我用c#写了一个调用libvlc api实现的 ...

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

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

  3. 用C/C++开发基于VLC SDK的视频播放器

    在windows系统如果开发万能播放器,一般都是基本DirectShow来开发,开发也很简单,但缺点也很多,一个文件格式是否能够播放完全取决于你 是否安装了正确的解析器和解码器,即使现在有了万能解器安 ...

  4. 将VLC库封装为duilib的万能视频播放控件

    转载请说明出处,谢谢~~ 昨天封装好了基于webkit的浏览器控件,修复了duilib的浏览器功能的不足,而我的仿酷狗播放器项目中不光需要浏览器,同时也需要视频播放功能,也就是完成MV的功能.所以我打 ...

  5. 使用Vitamio打造自己的Android万能播放器(5)——在线播放(播放优酷视频)

    前言 为了保证每周一篇的进度,又由于Vitamio新版本没有发布, 决定推迟本地播放的一些功能(截图.视频时间.尺寸等),跳过直接写在线播放部分的章节.从Vitamio的介绍可以看得出,其支持http ...

  6. 使用Vitamio打造自己的Android万能播放器(2)—— 手势控制亮度、音量、缩放

    前言 本章继续完善播放相关播放器的核心功能,为后续扩展打好基础.   声明 欢迎转载,但请保留文章原始出处:)  博客园:http://www.cnblogs.com 农民伯伯: http://ove ...

  7. 使用Vitamio打造自己的Android万能播放器(1)——准备

    前言 虽然Android已经内置了VideoView组件和MediaPlayer类来支持开发视频播放器,但支持格式.性能等各方面都十分有限,这里与大家一起利用免费的Vitamio来打造属于自己的And ...

  8. linux 常见音乐、视频播放器简介

    2007-1-15 10:00:22     常见音乐播放器     xmms一族     xmms全称是X Multimedia System,这个经典的播放器可能是每个linux的使用者或多或少都 ...

  9. Vitamio视频播放器

    前言 虽然Android已经内置了VideoView组件和MediaPlayer类来支持开发视频播放器,但支持格式.性能等各方面都十分有限,这里与大家一起利用免费的Vitamio来打造属于自己的And ...

随机推荐

  1. centos7 install rabbtimq

    yum install deltarpm erlang wget https://dl.bintray.com/rabbitmq/all/rabbitmq-server/3.7.8/rabbitmq- ...

  2. 盛世狂欢意犹未尽之恋舞OL折扣平台多角度体验

    2018国民级时尚音乐舞蹈手游<恋舞OL>,女生都爱玩的手机游戏.画风Q萌的3D音乐舞蹈手游,多人同时在线,玩法轻松休闲,浪漫场景自由社交互动,恋上指尖舞蹈. 小编看了上述介绍之后,感觉已 ...

  3. Django框架(八) Django之ORM数据库操作

    创建模型 实例:我们来假定下面这些概念,字段和关系 作者模型:一个作者有姓名和年龄. 作者详细模型:把作者的详情放到详情表,包含生日,手机号,家庭住址等信息.作者详情模型和作者模型之间是一对一的关系( ...

  4. Python 模块的加载顺序

    基本概念 module 模块, 一个 py 文件或以其他文件形式存在的可被导入的就是一个模块 package 包,包含有 init 文件的文件夹 relative path 相对路径,相对于某个目录的 ...

  5. 【做题】51NOD1518 稳定多米诺覆盖——容斥&dp

    题意:求有多少种方案,用多米诺骨牌覆盖一个\(n\times m\)的棋盘,满足任意一对相邻行和列都至少有一个骨牌横跨.对\(10^9+7\)取模. \(n,m \leq 16\) 首先,这个问题的约 ...

  6. 强化学习策略梯度方法之: REINFORCE 算法(从原理到代码实现)

    强化学习策略梯度方法之: REINFORCE 算法 (从原理到代码实现) 2018-04-01  15:15:42   最近在看policy gradient algorithm, 其中一种比较经典的 ...

  7. 基于OAuth2.0的第三方认证

    浅显易懂的解释 来源 yahoo OAuth认证 原理 理解OAuth 2.0:原理.分类 一张图搞定OAuth2.0:是什么,怎么用 应用自身,完成用户认证: 缺点: 1.不同的访问Web应用提供不 ...

  8. awk 基础入门

    简介 awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大.简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再 ...

  9. Centos7:查看某个端口被哪个进程占用

    查看端口被哪个进程使用的命令 netstat -lnp | grep 参考: https://blog.csdn.net/u010886217/article/details/83626236 htt ...

  10. Selenium 页面自动化测试 面试 问题汇总

    1.   专业技术 在学习完Selenium的大部分接口或者方法之后,你可能会去面试自动化测试,主要是Selenium的自动化测试.下面这些问题总结,可能会对你有所帮助. 什么是Selenium? S ...