paslibvlc使用方法_使用libVLC实现的播放器:支持双击全屏

背景

最近在学习duilib这个库,看了网上Alberl的教程,他那个仿迅雷播放器做的不错,我就直接拿来学习duilib了。不过这个播放器有个缺点,就是无法双击全屏,也就是鼠标放到libVLC播放窗口时无法响应消息,消息都被libVLC内部处理了。这对我们而言不是很方便。因为有时我们需要双击全屏,或者弹出鼠标右键菜单做一些操作。后来上网查了下,好多人遇到这个问题。下面是一些查到的解决方法。

解决libVLC无法响应鼠标消息

如下是查到的一些方法:

1)使用全局钩子;

2)修改libVLC鼠标消息处理代码,重新编译;

3)禁用子窗口消息。

第一种方法不安全,容易被杀毒软件干掉,而且效率不高,第二种方法麻烦,编译就得花你好多时间,而且很麻烦,第三种方法比较简单,解决方法如下:

// First step is start a timer when you play a video,

// Second step : in the timer function i call :

EnumChildWindows(MyWindow_HWND, EnumerateVLC, NULL);

// Third step : if EnumerateVlc get some child window these window is the VlcEventWindow, and need disable it, to reach mouse events on MyWindow

BOOL CALLBACK EnumerateVLC(HWND hWndvlc, LPARAM lParam) {

EnableWindow(hWndvlc, FALSE);

// And kill timer, i only need get this handle one time.

return TRUE;

}

// When EnumerateVLC is called all mouse events are redirected to MyWindow

1

2

3

4

5

6

7

8

9

10

11

12

13

// First step is start a timer when you play a video,

// Second step : in the timer function i call :

EnumChildWindows(MyWindow_HWND,EnumerateVLC,NULL);

// Third step : if EnumerateVlc get some child window these window is the VlcEventWindow, and need disable it, to reach mouse events on MyWindow

BOOLCALLBACKEnumerateVLC(HWNDhWndvlc,LPARAMlParam){

EnableWindow(hWndvlc,FALSE);

// And kill timer, i only need get this handle one time.

returnTRUE;

}

// When EnumerateVLC is called all mouse events are redirected to MyWindow

具体实现见下面。

基于duilib实现

duilib学起来还是很容易上手的,这里我的代码是基于Alberl的仿迅雷播放器。最后实现的界面如下:

按照上面的解决方法,在这个程序中我是这么解决无法响应消息的:

1)当开始播放某个文件后,创建一个一秒的定时器(也可以不创建,直接跳到直接第二步,创建定时器是为了确保我们处理时VLC窗口已经生成);

SetTimer(NULL, 1, 1000, TimeProc);

1

SetTimer(NULL,1,1000,TimeProc);

2)在定时器的回调函数中枚举得到VLC创建的窗口的句柄,通过spy++可以了解到libVLC创建的播放窗口名为:VLC video output,获取到VLC窗口的句柄后使用EnableWindow函数禁用掉键鼠输入,EnableWindow函数的作用是允许/禁止指定的窗口或控件接受鼠标和键盘的输入,代码如下:

C++

//定时器回调

void CALLBACK TimeProc(

HWND hwnd,

UINT message,

UINT idTimer,

DWORD dwTime)

{

//我的播放器窗口名称为JCHPlayer,也可以直接获取主程序窗口句柄

WCHAR *strWindwoName = L"JCHPlayer";

HWND hNMMainWnd = FindWindowEx(NULL, NULL, NULL, strWindwoName);

if (hNMMainWnd != NULL)

{

EnumChildWindows(hNMMainWnd, EnumerateVLC, NULL);

}

}

//枚举得到VLC播放窗口句柄

BOOL CALLBACK EnumerateVLC(HWND hWndvlc, LPARAM lParam)

{

TCHAR szWndTitle[1024];

int nLen = GetWindowText(hWndvlc, szWndTitle, 1024);

if (0!= nLen)

{

//禁用鼠标消息

EnableWindow(hWndvlc, FALSE);

KillTimer(NULL, 1);

}

return TRUE;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

//定时器回调

voidCALLBACKTimeProc(

HWNDhwnd,

UINTmessage,

UINTidTimer,

DWORDdwTime)

{

//我的播放器窗口名称为JCHPlayer,也可以直接获取主程序窗口句柄

WCHAR*strWindwoName=L"JCHPlayer";

HWNDhNMMainWnd=FindWindowEx(NULL,NULL,NULL,strWindwoName);

if(hNMMainWnd!=NULL)

{

EnumChildWindows(hNMMainWnd,EnumerateVLC,NULL);

}

}

//枚举得到VLC播放窗口句柄

BOOLCALLBACKEnumerateVLC(HWNDhWndvlc,LPARAMlParam)

{

TCHARszWndTitle[1024];

intnLen=GetWindowText(hWndvlc,szWndTitle,1024);

if(0!=nLen)

{

//禁用鼠标消息

EnableWindow(hWndvlc,FALSE);

KillTimer(NULL,1);

}

returnTRUE;

}

通过如上方法,在VLC播放窗口上的鼠标键盘消息我们都可以获得,这样就可以去实现自己想要的功能。比如我在全屏时响应WM_MOUSEMOVE消息,实现底部播放面板自动隐藏。双击全屏也很简单,当响应双击消息时,只显示作为libvlc父窗口那个控件,其他控件都隐藏即可。整个播放器的代码我已经上传到Github。

地址:https://github.com/yjfxfjch/JCHPlayer

我是用的是VS2015编译,低版本VS可能无法直接打开编译。下面一节是使用MFC做界面实现的版本。

基于MFC实现

1)在MFC对话框程序中,首先添加一个控件,这里我添加了一个Picture Contron:IDC_PLAYWND;

2)获得IDC_PLAYWND控件句柄;

C++

gPlayHwnd = GetDlgItem(IDC_PLAYWND)->GetSafeHwnd();

1

gPlayHwnd=GetDlgItem(IDC_PLAYWND)->GetSafeHwnd();

3)让libVLC播放对象设置gPlayHwnd 为播放窗口句柄,这样libVLC播放窗口就成为IDC_PLAYWND控件的子窗口;

libvlc_media_player_set_hwnd (mp, gPlayHwnd );

1

libvlc_media_player_set_hwnd(mp,gPlayHwnd);

4)开始播放后创建一个定时器(也可以不创建,直接EnableWindow相应窗口句柄);

C++

::SetTimer(NULL, 1, 1000, TimeProc);

1

::SetTimer(NULL,1,1000,TimeProc);

5)定时器回调函数以及处理过程如下:

C++

//定时器回调

void CALLBACK TimeProc(

HWND hwnd,

UINT message,

UINT idTimer,

DWORD dwTime)

{

EnumChildWindows(gPlayHwnd, EnumerateVLC, NULL);

}

BOOL CALLBACK EnumerateVLC(HWND hWndvlc, LPARAM lParam)

{

TCHAR szWndTitle[1024];

int nLen = GetWindowText(hWndvlc, szWndTitle, 1024);

if (0 != nLen)

{

//禁用鼠标消息

EnableWindow(hWndvlc, FALSE);

KillTimer(NULL, 1);

}

return TRUE;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

//定时器回调

voidCALLBACKTimeProc(

HWNDhwnd,

UINTmessage,

UINTidTimer,

DWORDdwTime)

{

EnumChildWindows(gPlayHwnd,EnumerateVLC,NULL);

}

BOOLCALLBACKEnumerateVLC(HWNDhWndvlc,LPARAMlParam)

{

TCHARszWndTitle[1024];

intnLen=GetWindowText(hWndvlc,szWndTitle,1024);

if(0!=nLen)

{

//禁用鼠标消息

EnableWindow(hWndvlc,FALSE);

KillTimer(NULL,1);

}

returnTRUE;

}

在上述代码中,我们通过之前得到的IDC_PLAYWND控件句柄枚举得到子窗口VLC播放窗口句柄,接着通过EnableWindow函数禁止VLC播放窗口接受鼠标键盘输入。这时我们的程序就可以响应鼠标点击libVLC播放窗口的消息了;

6)设置全屏,主要是设置IDC_PLAYWND控件全屏时占满整个屏幕,然后隐藏其他控件以及标题栏,这样VLC子窗口就可以全屏播放了。不需要使用libvlc_set_fullscreen这个内置api,使用这个api无法达到效果。

最后实现的简单版本如下:

MFC版本支持双击全屏的libvlc播放器代码我也上传到Github,具体的可以去看下。

Github地址:https://github.com/yjfxfjch/SimpleVlcPlayer

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值