
vlc的应用之三:动态调用vlc-0.9.4的libvlc.dll
2008-12-03 17:38:46
vlc-0.9.4提供的libvlc.dll是可以动态调用的,Jeremiah这一篇博客就介绍下如何用C#和WinForm框架调用libvlc.dll作个简易播放器。
1. vs2005新建工程,将vlc-0.9.4的libvlc.dll,libvlccore.dll,plugins目录全部拷贝到工程目录下面inDebug中。
2. 创建异常结构体
using System;
using System.Collections.Generic;
using System.Text;
namespace MyOwnPlayer

{
//异常结构体
public struct ExceptionStruct

{
private int raised;
private int code;
private string message;

}
class MediaException

{

}

}
3. CoreHandle和Core类
using System;
using System.Runtime.InteropServices;
namespace MyOwnPlayer

{
class CoreHandle : SafeHandle

{
//构造方法
public CoreHandle()

:
base(IntPtr.Zero,
true)

{

}
//重写的方法
public override bool IsInvalid

{

get {
return handle == IntPtr.Zero; }

}
protected override bool ReleaseHandle()

{
if (!IsInvalid)

{

libvlc_release(
this);

handle = IntPtr.Zero;

}
return true;

}
protected override void Dispose(
bool disposing)

{

ReleaseHandle();
base.Dispose(disposing);

}
//Dll动态导入 
[DllImport(
"libvlc")]
private static extern void libvlc_release(CoreHandle coreHandle);

}

}
using System;
using System.Runtime.InteropServices;
namespace MyOwnPlayer
{
class Core
{
//coreHandle字段和属性
private CoreHandle coreHandle;
public CoreHandle CoreHandle
{
get { return coreHandle; }
}
//构造方法
public Core(string[] argv, ref ExceptionStruct ex)
{
coreHandle = libvlc_new(argv.Length, argv, ref ex);
}
//Dll动态导入
[DllImport("libvlc")]
private static extern CoreHandle libvlc_new(int argc, string[] args, ref ExceptionStruct ex);
}
}
3. MediaHandle和Media类,注意里面的非英文路径处理方法。
using System;
using System.Runtime.InteropServices;
namespace MyOwnPlayer
{
class MediaHandle : SafeHandle
{
//构造方法
public MediaHandle()
: base(IntPtr.Zero, true)
{
}
//重写的方法
public override bool IsInvalid
{
get { return handle == IntPtr.Zero; }
}
protected override bool ReleaseHandle()
{
if (!IsInvalid)
{
libvlc_media_release(this);
handle = IntPtr.Zero;
}
return true;
}
protected override void Dispose(bool disposing)
{
ReleaseHandle();
base.Dispose(disposing);
}
//Dll动态导入
[DllImport("libvlc")]
private static extern void libvlc_media_release(MediaHandle mediaHandle);
}
}
using System;
using System.Text;
using System.Runtime.InteropServices;
namespace MyOwnPlayer

{
class Media

{
//mediaHandle字段和属性
private MediaHandle mediaHandle;
public MediaHandle MediaHandle

{

get {
return mediaHandle; }

}
//构造方法
public Media(CoreHandle coreHandle, String filename,
ref ExceptionStruct ex)

{
//c#为UTF-16编码, libvlc.dll为UTF-8编码, 需要转换. 
UTF8Encoding utf8 =
new UTF8Encoding();

mediaHandle = libvlc_media_new(coreHandle, utf8.GetBytes(filename),
ref ex);

}
//Dll动态导入 
[DllImport(
"libvlc")]
private static extern MediaHandle libvlc_media_new

(CoreHandle coreHandle, [MarshalAs(UnmanagedType.LPArray)]
byte[] link,
refExceptionStruct ex);

}

}
5. MediaPlayerHandle和MediaPlayer类
using System;
using System.Runtime.InteropServices;
namespace MyOwnPlayer

{
class MediaPlayerHandle : SafeHandle

{
//构造方法
public MediaPlayerHandle()

:
base(IntPtr.Zero,
true)

{

}
//重写的方法
public override bool IsInvalid

{

get {
return handle == IntPtr.Zero; }

}
protected override bool ReleaseHandle()

{
if (!IsInvalid)

{

libvlc_media_player_release(this);

handle = IntPtr.Zero;

}
return true;

}
protected override void Dispose(
bool disposing)

{

ReleaseHandle();
base.Dispose(disposing);

}
//Dll动态导入 
[DllImport(
"libvlc")]
private static extern void libvlc_media_player_release(MediaPlayerHandle mediaPlayerHandle);

}

}
using System;
using System.Runtime.InteropServices;
namespace MyOwnPlayer

{
class MediaPlayer

{
//mediaPlayerHandle字段和属性
private MediaPlayerHandle mediaPlayerHandle;
public MediaPlayerHandle MediaPlayerHandle

{

get {
return mediaPlayerHandle; }

}
//构造方法
public MediaPlayer(MediaHandle mediaHandle,
ref ExceptionStruct ex)

{

mediaPlayerHandle = libvlc_media_player_new_from_media(mediaHandle,
ref ex);

}
//设置父窗口
public void VedioSetParent(CoreHandle coreHandle, IntPtr hDT,
ref ExceptionStruct ex)

{

libvlc_video_set_parent(coreHandle, hDT,
ref ex);

}
//播放
public void Play(
ref ExceptionStruct ex)

{

libvlc_media_player_play(mediaPlayerHandle,
ref ex);

}
//停止
public void Stop(
ref ExceptionStruct ex)

{

libvlc_media_player_stop(mediaPlayerHandle,
ref ex);

}
//Dll动态导入 
[DllImport(
"libvlc")]
private static extern MediaPlayerHandle libvlc_media_player_new_from_media(MediaHandle libvlc_media_handle,
ref ExceptionStruct ex);

[DllImport(
"libvlc")]
private static extern void libvlc_video_set_parent(CoreHandle coreHandle, IntPtr hDT,
refExceptionStruct ex);

[DllImport(
"libvlc")]
private static extern void libvlc_media_player_play(MediaPlayerHandle mediaPlayerHandle,
ref ExceptionStruct ex);

[DllImport(
"libvlc")]
private static extern void libvlc_media_player_stop(MediaPlayerHandle mediaPlayerHandle,
ref ExceptionStruct ex);

}

}
6. 基本工作做好了。下一步建立一个Form,里面画一个Panel(播放容器),画一个Textbox(播放地址),画一个Button(播放按钮),Button的点击事件为:
private void button1_Click(object sender, EventArgs e)
{
//要播放的文件的uri
string uri = this.textBox1.Text;

//进行播放的控件的句柄
IntPtr hdl = this.panel1.Handle;

//播放参数
string[] argv = new string[] { "-I", "--ignore-config" };

//vlc对象的创建
ExceptionStruct ex = new ExceptionStruct();
Core core = new Core(argv, ref ex);
Media media = new Media(core.CoreHandle, uri, ref ex);
MediaPlayer player = new MediaPlayer(media.MediaHandle, ref ex);

//垃圾回收
GC.Collect();

//播放
player.VedioSetParent(core.CoreHandle, hdl, ref ex);
player.Play(ref ex);

//继续回收垃圾等相关操作
GC.Collect();
GC.WaitForPendingFinalizers();
}
7. 基本的播放功能就是这样实现的。其他接口请参考源码下面的includevlclibvlc.h文件,里面有比较详细的对外接口的说明。
8. 以上代码已经发送到附件中(MyOwnPlayer.rar),参考网址的楼主写的代码也在附件中(Marx_libvlc_wrapper(2).zip)。调试附件请注意第1步。
参考网址:
本文出自 “海狗哥的流媒体空间” 博客,请务必保留此出处http://jeremiah.blog.51cto.com/539865/116981
lbp0200、xc_shen、jiang421122 |
8人
|
了这篇文章 |