libVLC 事件机制
共 1508字,需浏览 4分钟
·
2020-08-23 14:03
在前面的章节中,我们曾说过 libVLC 是异步播放的。也就是说,无法立刻得到要想的结果(例如:媒体时长),倘若要获取这些信息,必须通过事件通知和回调来实现。
1
基本步骤
1. 创建事件管理器 - libvlc_event_manager_t,可选的方式有:
libvlc_media_event_manager():媒体相关的事件管理器。
比如,要监听媒体的改变状态(libvlc_MediaStateChanged),就需要用到它。
libvlc_media_list_event_manager():媒体列表相关的事件管理器。
比如,要监听媒体列表停止(libvlc_MediaListPlayerStopped),就需要用到它。
libvlc_media_player_event_manager():播放器相关的事件管理器。
比如,要监听播放器的音量(libvlc_MediaPlayerAudioVolume),就需要用到它。
2. 通过 libvlc_event_attach() 订阅所感兴趣的事件,如果要退订事件,可使用 libvlc_event_detach()。
3. 编写事件处理程序(回调函数),在里面处理所订阅的各个事件。
libVLC 的事件类型有很多,具体可参考 LibVLC asynchronous events(详见:https://www.videolan.org/developers/vlc/doc/doxygen/html/group__libvlc__event.html)。
2
实现方式
以一个网络流为例,来获取播放器的位置、最新时长和总时长。
首先,要创建一个事件列表,并订阅它们。需要注意的是 libvlc_event_attach(),它的最后一个参数是用户数据,这里暂时没有用到,所以指定为 nullptr:
void attachEvents(libvlc_event_manager_t *eventManager)
{
// 事件列表
list events = {
libvlc_MediaPlayerPositionChanged,
libvlc_MediaPlayerTimeChanged,
libvlc_MediaPlayerLengthChanged
};
// 订阅事件
for (const libvlc_event_e &e : events) {
libvlc_event_attach(eventManager, e, handleEvents, nullptr);
}
}
然后,在事件处理程序(回调函数)中处理它们。对于每一个事件(例如:libvlc_MediaPlayerPositionChanged)来说,都有一个结构体(例如:media_player_position_changed)与之对应,通过它便能很容易地访问具体的信息了:
static void handleEvents(const libvlc_event_t *event, void *userData)
{
switch (event->type) {
case libvlc_MediaPlayerPositionChanged:
cout << "Position: " << event->u.media_player_position_changed.new_position << endl;
break;
case libvlc_MediaPlayerTimeChanged:
cout << "New Time: " << event->u.media_player_time_changed.new_time << endl;
break;
case libvlc_MediaPlayerLengthChanged:
cout << "Length: " << event->u.media_player_length_changed.new_length << endl;
break;
default:
break;
}
}
最后,是对上述实现的具体调用,来一起看看吧:
int main()
{
const char * rtspMrl = "rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov";
libvlc_instance_t *instance;
libvlc_media_player_t *player;
libvlc_media_t *media;
libvlc_event_manager_t *eventManager;
instance = libvlc_new(0, nullptr);
media = libvlc_media_new_location(instance, rtspMrl);
player = libvlc_media_player_new_from_media(media);
// 创建事件管理器
eventManager = libvlc_media_player_event_manager(player);
// 订阅事件
attachEvents(eventManager);
libvlc_media_player_play(player);
waitPlaying(player);
libvlc_media_release(media);
libvlc_media_player_release(player);
libvlc_release(instance);
return 0;
}
3
测试程序
运行程序,可以看到播放位置和时长在实时改变,如下所示:
如果想获取更多的媒体信息,方法与上述实现类似。
·END·