原文 http://www.helyar.net/2009/libvlc-media-player-in-c-part-2/

I gave some simplified VLC media player code in part 1 to show how easy it was to do and how most wrapper libraries make a mountain out of a mole hill. In that entry, I briefly touched on using some classes to make it easier and safer to implement actual programs with this.

The first thing to do is write a wrapper for the exceptions, so that they are handled nicely in C#. For a program using the library, exceptions should be completely transparent and should be handled in the normal try/catch blocks without having to do anything like initialise them or check them.

Another thing to do is to move all of the initialisation functions into constructors and all of the release functions into destuctors or use the System.IDisposable interface.

Here is the code listing for the 4 classes used (VlcInstance, VlcMedia, VlcMediaPlayer and VlcException). Note that the first 3 of these are very similar and that the main difference is that the media player class has some extra functions for doing things like playing and pausing the content.

class VlcInstance : IDisposable
{
internal IntPtr Handle;
 
public VlcInstance(string[] args)
{
VlcException ex = new VlcException();
Handle = LibVlc.libvlc_new(args.Length, args, ref ex.Ex);
if (ex.IsRaised) throw ex;
}
 
public void Dispose()
{
LibVlc.libvlc_release(Handle);
}
}
 
class VlcMedia : IDisposable
{
internal IntPtr Handle;
 
public VlcMedia(VlcInstance instance, string url)
{
VlcException ex = new VlcException();
Handle = LibVlc.libvlc_media_new(instance.Handle, url, ref ex.Ex);
if (ex.IsRaised) throw ex;
}
 
public void Dispose()
{
LibVlc.libvlc_media_release(Handle);
}
}
 
class VlcMediaPlayer : IDisposable
{
internal IntPtr Handle;
private IntPtr drawable;
private bool playing, paused;
 
public VlcMediaPlayer(VlcMedia media)
{
VlcException ex = new VlcException();
Handle = LibVlc.libvlc_media_player_new_from_media(media.Handle, ref ex.Ex);
if (ex.IsRaised) throw ex;
}
 
public void Dispose()
{
LibVlc.libvlc_media_player_release(Handle);
}
 
public IntPtr Drawable
{
get
{
return drawable;
}
set
{
VlcException ex = new VlcException();
LibVlc.libvlc_media_player_set_drawable(Handle, value, ref ex.Ex);
if (ex.IsRaised) throw ex;
drawable = value;
}
}
 
public bool IsPlaying { get { return playing && !paused; } }
 
public bool IsPaused { get { return playing && paused; } }
 
public bool IsStopped { get { return !playing; } }
 
public void Play()
{
VlcException ex = new VlcException();
LibVlc.libvlc_media_player_play(Handle, ref ex.Ex);
if (ex.IsRaised) throw ex;
 
playing = true;
paused = false;
}
 
public void Pause()
{
VlcException ex = new VlcException();
LibVlc.libvlc_media_player_pause(Handle, ref ex.Ex);
if (ex.IsRaised) throw ex;
 
if (playing)
paused ^= true;
}
 
public void Stop()
{
VlcException ex = new VlcException();
LibVlc.libvlc_media_player_stop(Handle, ref ex.Ex);
if (ex.IsRaised) throw ex;
 
playing = false;
paused = false;
}
}
 
class VlcException : Exception
{
internal libvlc_exception_t Ex;
 
public VlcException() : base()
{
Ex = new libvlc_exception_t();
LibVlc.libvlc_exception_init(ref Ex);
}
 
public bool IsRaised { get { return LibVlc.libvlc_exception_raised(ref Ex) != 0; } }
 
public override string Message { get { return LibVlc.libvlc_exception_get_message(ref Ex); } }
}

Using these classes is even easier than before, can use proper exception handling (removed for brevity) and cleans up better at the end. In this example, I have added an OpenFileDialog, which is where the file is loaded.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
 
namespace MyLibVLC
{
public partial class Form1 : Form
{
VlcInstance instance;
VlcMediaPlayer player;
 
public Form1()
{
InitializeComponent();
 
openFileDialog1.FileName = "";
openFileDialog1.Filter = "MPEG|*.mpg|AVI|*.avi|All|*.*";
 
string[] args = new string[] {
"-I", "dummy", "--ignore-config",
@"--plugin-path=C:\Program Files (x86)\VideoLAN\VLC\plugins",
"--vout-filter=deinterlace", "--deinterlace-mode=blend"
};
 
instance = new VlcInstance(args);
player = null;
}
 
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
if(player != null) player.Dispose();
instance.Dispose();
}
 
private void Open_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() != DialogResult.OK)
return;
 
using (VlcMedia media = new VlcMedia(instance, openFileDialog1.FileName))
{
if (player != null) player.Dispose();
player = new VlcMediaPlayer(media);
}
 
player.Drawable = panel1.Handle;
}
 
private void Play_Click(object sender, EventArgs e)
{
player.Play();
}
 
private void Pause_Click(object sender, EventArgs e)
{
player.Pause();
}
 
private void Stop_Click(object sender, EventArgs e)
{
player.Stop();
}
}
}

Update:

I have just corrected a minor bug (the wrong release function being called on the player handle) and uploaded the full Visual Studio 2005 project. You can download the full project here (or see 1.1.2 version below). It comes with the libvlc.dll and libvlccore.dll for VLC 1.0.1 in the bin\x86\Debug directory so if you have a version other than this, just overwrite those files.

Update for VLC 1.1.2:

You can now download the VLC 1.1.2 compatible version. There were some changes to the way libvlc handles exceptions that needed to be corrected. Other than that, there were a couple of minor function name changes.

Please use these posts as a starting point to use your own code though. These posts are intended to stoppeople from being reliant on the already existing, large, overcomplicated and quickly outdated libraries. They are not intended to be just another library for people to blindly use without understanding how it works. You can use this to learn how to write your own native interop code on a well designed library then adapt it for your own changes and keep it up to date with whichever version of VLC you want. This also means you never have to use the terrible code on pinvoke.net for other libraries, as you can write your own from the original documentation and it will almost always be better.

Bugfix: VlcException should use Marshal.PtrToStringAnsi not Marshal.PtrToStringAuto

libvlc media player in C# (part 2)的更多相关文章

  1. libvlc media player in C# (part 1)

    原文 http://www.helyar.net/2009/libvlc-media-player-in-c/ There seems to be a massive misconception ab ...

  2. 【流媒体开发】VLC Media Player - Android 平台源码编译 与 二次开发详解 (提供详细800M下载好的编译源码及eclipse可调试播放器源码下载)

    作者 : 韩曙亮  博客地址 : http://blog.csdn.net/shulianghan/article/details/42707293 转载请注明出处 : http://blog.csd ...

  3. 用VLC Media Player搭建简单的流媒体服务器

    VLC可以作为播放器使用,也可以搭建服务器. 在经历了Helix Server和Darwin Streaming Server+Perl的失败之后,终于找到了一个搭建流媒体简单好用的方法. 这个网址中 ...

  4. android错误之MediaPlayer用法的Media Player called in state *,androidmediaplayer

    用到Media Player,遇到几个问题,记一下 用法就不说了,使用的时候最好参考一下mediaPlayer的这张图 第一个错误是Media Player called in state 8 这个是 ...

  5. win7自带windows media player 已停止工作

    解决方法如下: 在计算机开始,菜单找到控制面板 ,然后打开程序和功能,选择打开或关闭window功能,媒体功能.再取消windows Media Center Windows MediaPlayer选 ...

  6. 转:Media Player Classic - HC 源代码分析

    VC2010 编译 Media Player Classic - Home Cinema (mpc-hc) Media Player Classic - Home Cinema (mpc-hc)播放器 ...

  7. Media Player 把光盘中的内容拷贝出来的方法

    http://jingyan.baidu.com/article/cb5d610529f0c1005c2fe0b4.html  这个链接是通过Media  Player 把光盘中的内容拷贝出来的方法h ...

  8. 20 Free Open Source Web Media Player Apps

    free Media Players (Free MP3, Video, and Music Player ...) are cool because they let web developers ...

  9. Windows Media Player安装了却不能播放网页上的视频

    前段时间遇到Windows Media Player安装了却不能播放网页上的视频的问题,在网上查找资料时,发现大部分资料都没能解决我这个问题.偶尔试了网上一牛人的方法,后来竟然解决了.现在再找那个网页 ...

随机推荐

  1. linux命令之删除

      linux删除文件夹非常easy,非常多人还是习惯用rmdir,只是一旦文件夹非空,就陷入深深的苦恼之中,如今使用rm -rf命令就可以. 直接rm就能够了,只是要加两个參数-rf 即:rm -r ...

  2. 基于Gsoap 的ONVIF C++ 库

    https://github.com/xsmart/onvifcpplib 该库支持ProfileS 和ProfileG,目前正在开发哪些,现拥有支持Event 下面是一个client样本 int _ ...

  3. 王立平--Button底,点击效果设置

    1.新....xml <? xml version="1.0" encoding="utf-8"?>        <selector xml ...

  4. 解决一bug的流程复盘

    听同事说有一个功能不好使了,当时有事,过了一段时间来看看这个bug 解决问题时,看的是老的日志,根据老日志看来看去没有发现问题,觉得很困惑 然后手动执行了一下,发现问题没有重现.与另一个团队的同事沟通 ...

  5. Simditor图片上传

    上一篇文章(Simditor用法)仅仅是简单的默认配置,我们可自己定义工具栏button使其更丰富和实现上传图片功能 初始化编辑器 <script type="text/javascr ...

  6. JAVA学习第六十二课 — TCP协议练习

    通过练习掌握TCP在进行传输过程中的问题 练习1:创建一个英文大写转换server client输入字母数据,发送给服务端,服务端收到后显示到控制台,并将该数据转成大写返回client,知道clien ...

  7. 怎样改动、扩展并重写Magento代码

    作为一个开发人员的你,肯定要改动Magento代码去适应你的业务需求,可是在非常多时候我们不希望改动Magento的核心代码,这里有非常多原因, 比如将来还希望升级Magento.还想使用很多其它的M ...

  8. 【C++】智能指针auto_ptr简单的实现

    //[C++]智能指针auto_ptr简单的实现 #include <iostream> using namespace std; template <class _Ty> c ...

  9. printf 对齐

      printf关于对其的问题(参考有关博客加上自己的一些总结) 1.关于左对齐或右对齐问题, 默认的如果%后没有“-”是右对齐的,如果%后跟“0”,不足的个数用0来填充, 例如:printf(&qu ...

  10. ASP.NET MVC+EF框架+EasyUI实现权限管理系列(21)-用户角色权限基本的实现说明

    原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(21)-用户角色权限基本的实现说明     ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇)   (1):框 ...