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

c#万能视频播放器

本人之前很多的文章中均提到了使用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”目录即可调试运行。

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏张善友的专栏

MSDN杂志上的Windows Phone相关文章

Windows Phone 7 开发工具和资源 http://msdn.microsoft.com/zh-cn/magazine/gg598932.aspx 在...

21750
来自专栏张善友的专栏

.NET Core 2.0 正式发布信息汇总

万众瞩目的.NET Core 2.0终于发布了,原定于9.19的 dotnetconf 大会的发布时间大大提前了1个月,.NET Core 2.0/.NET S...

20400
来自专栏walterlv - 吕毅的博客

3 Ways to create a window with blurring background on Windows 10

发布于 2018-07-16 11:14 更新于 2018-09...

10810
来自专栏哲学驱动设计

WPF中ICommand接口 的一个设计问题

public interface ICommand { // Summary: // Occurs wh...

28670
来自专栏张善友的专栏

WPF E 文章汇总

MSDN "WPF/E" (codename) Dev Center : http://msdn2.microsoft.com/en-us/asp.net/bb...

19490
来自专栏张善友的专栏

WPF/XML 资源及相关开源项目

昨天参加微软的一个小技术新一代设计工具 - Microsoft Expression 看到很多相关的工具.在网上一搜,找到下面这些东东,和大家分享一下. XAM...

20570
来自专栏张善友的专栏

微软开源Erik Meijer团队开发的异步编程库Rx(Reactive Extensions)

2012年11月6日,微软开源异步编程Rx(Reactive Extensions)库。Rx是一个模型,允许开发者把所有的异步数据粘和在一起。它的源代码现在基于...

22680
来自专栏张善友的专栏

Silverlight 2 Beta 1学习资源

Silverlight 2 Beta 1发布了,大家都介绍了怎么去下载安装了,晚上整理了一些资料放上来和大家共享: 1、Silverlight 2 Beta 1...

18370
来自专栏逍遥剑客的游戏开发

WPF工具开发: 第三库选择

29260
来自专栏张善友的专栏

Mono.Addins 插件式框架

      Visual Studio,Office,Delphi,Eclipse等等都有插件式的框架。Eclipse将插件模式发挥到了及至,因为他是开源的,开...

26360

扫码关注云+社区

领取腾讯云代金券