原文 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. JSTL实现int数据的类型的长度

    JSTL否int类型转换string该功能.为了解决增益int数据的类型的长度,闹失踪. 得到String的数据的长度是jstl的fn能够${fn:length(string)},但int做数据? 经 ...

  2. 编写爬虫程序的神器 - Groovy + Jsoup + Sublime(转)

    写过很多个爬虫小程序了,之前几次主要用C# + Html Agility Pack来完成工作.由于.NET FCL只提供了"底层"的HttpWebRequest和"中层& ...

  3. [SignalR]在非Hub继承类中使用脚本方法

    原文:[SignalR]在非Hub继承类中使用脚本方法 新建一个普通类OutHub,里面包含一个脚本方法OutHubTest. 因为大家知道,若能让脚本调用到的话,必须继承Hub,那怎么实现了?通过G ...

  4. iis7、iis8配置备份还原

    原文 iis7.iis8配置备份还原 方法1: 1.打开我们的IIS管理器,在功能视图里找到“共享的配置”这个功能然后双击进入. 2.进入“共享的配置”后单机右上方的“导出配置”选项,选择导出配置文件 ...

  5. java通用抹去魔,在边界行动,擦除补偿

    java通用抹去魔 package org.rui.generics.erasure; public class HasF { public void f(){ System.out.println( ...

  6. jQuery整理笔记文件夹

    jQuery整理笔记文件夹 jQuery整理笔记一----jQuery開始 jQuery整理笔记二----jQuery选择器整理 jQuery整理笔记三----jQuery过滤函数 jQuery整理笔 ...

  7. python派QQ邮件

    #encoding=utf-8 __author__ = 'ds' #文件名冲突 from email.mime.text import MIMEText import smtplib if __na ...

  8. java一般使用基础

    1.这是一个通用 仿制药javaA型安全机制来保护. 它是通过变量的类型,如果,实现变量类型限制,从而保证了程序编译变量类型的安全性在一定程度上.反之.如果没有泛型,这些只存在于程序,如果猿的大脑,这 ...

  9. SQL Server---触发

    今天的第一次SQL Server触发感觉很方便,本文将向您介绍一个简单的SQL Server触发器和简单的使用. 我将确定其.原理.使用细节都是关于. 定义 触发器(trigger)是个特殊的存储过程 ...

  10. hdu More is better

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1856 题意:王老师要找一些男生帮助他完成一项工程.要求最后挑选出的男生之间都是朋友关系,可以说直接的, ...