原文 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. C++生产和使用的临时对象

     所谓暂时对象就是一种无名对象. 它的出现假设不在程序猿的预期之下(比如不论什么pass by value操作都会引发copy操作,于是形成一个暂时对象),往往照成效率上的负担. 但有时候能够制造 ...

  2. 折返(Reentrancy)VS线程安全(Thread safety)

    在Wiki上,折返例如,下面的定义(接) In computing, a computer program or subroutine is called reentrant if it can be ...

  3. gem 安装nokigiri

    在mac上安装nokogiri的时候各种报错,终于安装成功一次,备份命令. ➜ ~ sudo gem install nokogiri -- --use-system-libraries --with ...

  4. error LNK2019: 解析的外部符号 __imp__DispatchMessageW@4,在函数的符号 _WinMain@16 据引述

    错误: 1>WinMain.obj : error LNK2019: 解析的外部符号 __imp__DispatchMessageW@4,在函数的符号 _WinMain@16 据引述 1> ...

  5. CORS

    CORS(跨域资源共享) 前言:上一篇文章提到使用JSONP实现跨域请求的时候,偶然间提到CORS,即Cross-Origin Resource Sharing(跨域资源共享).虽然前些天也看了一下, ...

  6. hdu4758 Walk Through Squares 自动机+DP

    题意:给n*m的地图,在地图的点上走,(n+1)*(m+1)个点,两种操作:往下走D和往右走R.现在要从左上角走到右下角,给定两个操作串,问包含这两个串的走法总共有多少种. 做法:用这两个串构建自动机 ...

  7. The Swift Programming Language中国完整版

    近来的ios的swift语言似乎火了.我没有objectc基金会,但在此之前有c随着java在...的基础上.从几天开始学习ios的swift语言,晚发表在博客形式.下面是英文版本翻译swif图书.还 ...

  8. 前端是Sencha Touch+ Cordova(转)

    从13年初开始,我的关注点一直在两个点上,一个是股票,一个是移动前端和大数据技术,互联网金融的发展会让互联网证券越来越火热,当然,我也希望将这两个关注点结合到一起,做一些事情.   现在,我的APP和 ...

  9. Microsoft.AlphaImageLoader过滤评论

    Microsoft.AlphaImageLoader是IE滤镜的一种,其主要作用就是对图片进行透明处理.尽管FireFox和IE7以上的IE浏览器已经支持透明的PNG图片,可是就IE5-IE6而言还是 ...

  10. LeetCode——Linked List Cycle II

    Given a linked list, return the node where the cycle begins. If there is no cycle, return null. Foll ...