事件订阅可以拿到文件长度、播放进度、播放状态改变等信息,vlc的事件订阅机制封装的比较友好,只需要先创建一个事件管理器,然后逐个订阅自己感兴趣的需要的事件,不感兴趣的可以不要订阅,只有订阅了的事件才能在事件回调中拿到,所以如果在事件回调中发现一些事件没有拿到,首先要检查下到底订阅了没有,所有事件的枚举在libvlc_events.h头文件中可以查阅到,都用的是通俗易懂的全英文单词描述,有过基本英语能力的开发人员都能看懂。
在调用libvlc_event_attach订阅事件的时候,第三个参数指定事件回调函数,第四个参数传入用户数据,一般是用来传入类的指针,这样在事件回调的时候,可以直接拿到并转换为类指针,然后使用类中的方法,在对Qt4-Qt5的兼容过程中发现,Qt5中的信号是public的,所以可以直接在回调函数中emit发送信号,而Qt4中的信号是protected的,没法直接emit,所以需要做一个通用的中转函数,用来重新分发信号,通过参数type来控制类型,QVariantList来传入参数集合。
//事件回调
static void handleEvents(const libvlc_event_t *event, void *userData)
{
VlcThread *thread = (VlcThread *)userData;
switch (event->type) {
case libvlc_MediaPlayerLengthChanged: {
quint64 length = event->u.media_player_length_changed.new_length;
if (length > 0) {
thread->doEvent(1, QVariantList() << length);
qDebug() << TIMEMS << "文件总长: " << length;
}
}
break;
case libvlc_MediaPlayerTimeChanged: {
quint64 position = event->u.media_player_time_changed.new_time;
if (position > 0) {
thread->doEvent(2, QVariantList() << position);
//qDebug() << TIMEMS << "当前时间: " << position;
}
}
break;
case libvlc_MediaPlayerPositionChanged: {
float position = event->u.media_player_position_changed.new_position;
if (position > 0) {
//qDebug() << TIMEMS << "当前进度: " << position;
}
}
break;
case libvlc_MediaParsedChanged:
qDebug() << TIMEMS << "媒体信息: " << event->u.media_parsed_changed.new_status;
break;
//qDebug() << TIMEMS << "状态改变: " << event->u.media_state_changed.new_state;
case libvlc_MediaPlayerOpening:
qDebug() << TIMEMS << "状态改变: " << "libvlc_MediaPlayerOpening";
break;
case libvlc_MediaPlayerPlaying:
qDebug() << TIMEMS << "状态改变: " << "libvlc_MediaPlayerPlaying";
break;
case libvlc_MediaPlayerPaused:
qDebug() << TIMEMS << "状态改变: " << "libvlc_MediaPlayerPaused";
break;
case libvlc_MediaPlayerStopped:
qDebug() << TIMEMS << "状态改变: " << "libvlc_MediaPlayerStopped";
break;
case libvlc_MediaPlayerEndReached: {
thread->doEvent(0, QVariantList());
qDebug() << TIMEMS << "状态改变: " << "libvlc_MediaPlayerEndReached";
}
break;
default:
break;
}
}
//订阅事件
static void libvlc_event_new(libvlc_event_manager_t *vlcEvent, VlcThread *thread)
{
//逐个订阅自己感兴趣的需要的事件
libvlc_event_attach(vlcEvent, libvlc_MediaPlayerLengthChanged, handleEvents, thread);
libvlc_event_attach(vlcEvent, libvlc_MediaPlayerTimeChanged, handleEvents, thread);
libvlc_event_attach(vlcEvent, libvlc_MediaPlayerPositionChanged, handleEvents, thread);
libvlc_event_attach(vlcEvent, libvlc_MediaParsedChanged, handleEvents, thread);
libvlc_event_attach(vlcEvent, libvlc_MediaPlayerOpening, handleEvents, thread);
libvlc_event_attach(vlcEvent, libvlc_MediaPlayerPlaying, handleEvents, thread);
libvlc_event_attach(vlcEvent, libvlc_MediaPlayerPaused, handleEvents, thread);
libvlc_event_attach(vlcEvent, libvlc_MediaPlayerStopped, handleEvents, thread);
libvlc_event_attach(vlcEvent, libvlc_MediaPlayerEndReached, handleEvents, thread);
}
//反订阅事件
static void libvlc_event_release(libvlc_event_manager_t *vlcEvent, VlcThread *thread)
{
libvlc_event_detach(vlcEvent, libvlc_MediaPlayerLengthChanged, handleEvents, thread);
libvlc_event_detach(vlcEvent, libvlc_MediaPlayerTimeChanged, handleEvents, thread);
libvlc_event_detach(vlcEvent, libvlc_MediaPlayerPositionChanged, handleEvents, thread);
libvlc_event_detach(vlcEvent, libvlc_MediaParsedChanged, handleEvents, thread);
libvlc_event_detach(vlcEvent, libvlc_MediaPlayerOpening, handleEvents, thread);
libvlc_event_detach(vlcEvent, libvlc_MediaPlayerPlaying, handleEvents, thread);
libvlc_event_detach(vlcEvent, libvlc_MediaPlayerPaused, handleEvents, thread);
libvlc_event_detach(vlcEvent, libvlc_MediaPlayerStopped, handleEvents, thread);
libvlc_event_detach(vlcEvent, libvlc_MediaPlayerEndReached, handleEvents, thread);
}
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。