libVLC 事件机制

proginn468312

共 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(0nullptr);
    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·
 

作者:一去、二三里
爱学习,爱编程,爱生活。
欢迎来撩,一起畅谈程序人生!

点个在看,么么哒!

浏览 99
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报