zoukankan      html  css  js  c++  java
  • 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”目录即可调试运行。

     

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

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

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

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

  • 相关阅读:
    51nod 1494 选举拉票 | 线段树
    51nod 1295 XOR key | 可持久化Trie树
    Codeforces 438D (今日gg模拟第二题) | 线段树 考察时间复杂度的计算 -_-|||
    51nod 1563 坐标轴上的最大团(今日gg模拟第一题) | 线段覆盖 贪心 思维题
    良心的可持久化线段树教程
    51nod 1593 公园晨跑 | ST表(线段树?)思维题
    51nod 1595 回文度 | 马拉车Manacher DP
    51nod 1522 上下序列
    胡小兔的OI日志3 完结版
    51nod 1510 最小化序列 | DP 贪心
  • 原文地址:https://www.cnblogs.com/qq260250932/p/4237073.html
Copyright © 2011-2022 走看看