请移步https://higoge.github.io/,全部下载资料在那个博客都能找到。谢谢。 c++
--------------------------------------------------------------------git
本篇博客将简单介绍MFC调用libvlc.dll做一个简单的播放器,抛砖引玉,各位VC++达人继续深刻研究,Jeremiah对VC++确实不太感兴趣,因此就不作太深刻的研究了。
github
2009.10.29修改:加入clip_children属性设置。参考第1步。ide
2010.04.14修改:中文路径问题。参考第7步。函数
环境:
1) VC6 SP5
2) vlc-0.9.9a测试
0. 引言
根据上一篇博客的研究,任何一个VC环境均可以调用MinGW/Gcc编译获得的libvlc.dll。VLC在编译打包以后(也就是执行完make package-win32-base),或者去官网下载zip包解压以后,或者是安装完VLC以后,在vlc-0.9.9a目录下有个sdk文件夹,里面又包含两个文件夹:include--头文件及lib--库。这些都是咱们用MFC调用libvlc.dll所必须的。头文件没啥好说的,库里面的libvlc.dll.a及libvlccore.dll.a就是上一篇博客所说的静态库,咱们分别手动改为libvlc.lib及libvlccore.lib就能够在VC环境中调用啦。下面简要说一下调用的过程,对各位VC++达人来讲绝对是小菜一碟。ui
1. 创建工程
新建MFC AppWizard(exe)工程,名字为:MFCVLC。选择项目为Dialog based,点击完成。删除Dialog窗体上的全部的控件,包括“肯定”、“取消”按钮及"TODO"静态文本。勾选窗口的clip_children属性,这样就会避免拖动、最大化最小化及全屏还原时找不到图像的缺陷。this
2. 画控件
画四个控件,两个静态文本框,一个输入框,一个按钮。其中,第一个静态文本框修改Caption为“路径:”,第二个文本框为视频的显示区域,因此讲ID改成IDC_DISPLAY,Caption去掉。输入框关联一个变量,CString类型,命名为m_path。按钮的Caption改成“播放”,并为BN_CLICKED增长一个Function。在CMFCVLCdlg的构造方法中加入一下语句方便调试。spa
m_path = _T("d:/01.avi"); // 输入经常使用的视频地址debug
3. 拷贝vlc的相关库及头文件
在资源管理器的MFCVLC工程目录下新建文件夹vlc,lib,将vlc-0.9.9a/sdk/include/vlc.h拷贝到MFCVLC工程目录下,将vlc-0.9.9a/sdk/include除了vlc.h以外的全部文件拷贝到vlc目录下,将vlc-0.9.9a/sdk/lib下的libvlc.dll.a及libvlccore.dll.a拷贝到lib下,并分别修改成libvlc.lib及libvlccore.lib。将vlc-0.9.9a目录下的libvlc.dll, libvlccore.dll, plugins目录拷贝到Debug目录下。若是有Cygwin环境,须要将stdint.h(/usr/include/stdint.h)这个头文件也拷贝到MFCVLC工程目录下。在VC6环境中FileView中新建文件夹及导入上述文件,最后入下图所示。
4. 修改头文件
1) 修改vlc.h,将全部的#include <***>改成 #include "***"
2) 修改stdint.h,将全部的long long替换为__int64
3) 修改libvlc_structures.h,#include <stdint.h>为#include "stdint.h"
5. 编写代码
在MFCVLCDlg.cpp中加入头文件导入。
#include "vlc.h"
在button的onclick关联函数中加入代码:
void CMFCVLCDlg::OnButton1()
{
// TODO: Add your control notification handler code here
char path[100];
this->GetDlgItemText(IDC_EDIT1, path, 100);
libvlc_exception_t ex;
libvlc_exception_init(&ex);
int vlc_argc = 0;
char *vlc_argv[100];
vlc_argv[vlc_argc++] = "--ignore-config";
libvlc_instance_t *p_instance = libvlc_new(
vlc_argc, vlc_argv, &ex);
libvlc_media_t *p_media = libvlc_media_new(
p_instance, path, &ex);
libvlc_media_player_t *p_media_player
= libvlc_media_player_new_from_media(
p_media, &ex);
libvlc_drawable_t hwnd =
(libvlc_drawable_t) this->GetDlgItem(IDC_DISPLAY)->GetSafeHwnd();
libvlc_media_player_set_drawable(p_media_player, hwnd, &ex);
libvlc_media_player_play(p_media_player, &ex);
}
7. 两个BUG
第6步执行的是Execute模式,若是是Debug模式,点击“播放”后,后台会显示加载的vlc的plugins的dll的信息,可是加载完最后一个dll的时候程序就Block住了。暂时不晓得为啥。通过更多的测试(win2003虚拟机里的vc6),发现Jeremiah的VC6可能真的有问题,debug的时候,打开Output窗口显示加载的dll的状况,就会block住。不打开Output窗口偶尔会set_drawable不成功,弹出新窗口。其余几位朋友测试则正常。
上面的代码若是开带中文路径的地址会没法打开,由于传入的中文路径vlc识别不了。须要将路径也就是path变量从ANSIZ转换为UTF8代码。具体怎么转换,各位VC达人本身研究吧。
8. 用VC6以上版本调试结果
Jeremiah使用了vs2003及vs2005。
1) 会两个重复定义的错误,解决方法是将stdint.h中注释掉:
#ifndef __intptr_t_defined
#define __intptr_t_defined
//typedef long intptr_t;
#endif
//typedef unsigned long uintptr_t;
2) 发布Release版本会报内存错误。具体缘由待查,应该是.lib不兼容的问题。不知道为啥Debug版就能够而Release版就不行。解决方法是用dll2lib.exe(附件提供)将0.9.9a的libvlc.dll及libvlccore.dll转换为相应的lib库,替换工程的lib/下面的相应的库,而后再次Release便可。
Jeremiah对MFC只有一点点了解,因此上述的各个过程若是重复烦琐,及如何修复第7,8步讲的BUG及问题,请各位VC++达人指导Jeremiah。先谢过。本文附件中提供了MFCVLC的源码,只是须要把vlc-0.9.9a的libvlc.dll, libvlccore.dll, plugins目录拷贝到Debug目录下就能够编译执行。须要的本身下载添加调试。