libVLC 事件機制

在前面的章節(jié)中,我們曾說過 libVLC 是異步播放的。也就是說,無法立刻得到要想的結(jié)果(例如:媒體時長),倘若要獲取這些信息,必須通過事件通知和回調(diào)來實現(xiàn)。
1
基本步驟
1. 創(chuàng)建事件管理器 - libvlc_event_manager_t,可選的方式有:
libvlc_media_event_manager():媒體相關的事件管理器。
比如,要監(jiān)聽媒體的改變狀態(tài)(libvlc_MediaStateChanged),就需要用到它。
libvlc_media_list_event_manager():媒體列表相關的事件管理器。
比如,要監(jiān)聽媒體列表停止(libvlc_MediaListPlayerStopped),就需要用到它。?
?
libvlc_media_player_event_manager():播放器相關的事件管理器。
比如,要監(jiān)聽播放器的音量(libvlc_MediaPlayerAudioVolume),就需要用到它。??
2. 通過 libvlc_event_attach() 訂閱所感興趣的事件,如果要退訂事件,可使用 libvlc_event_detach()。?
3. 編寫事件處理程序(回調(diào)函數(shù)),在里面處理所訂閱的各個事件。
libVLC 的事件類型有很多,具體可參考 LibVLC asynchronous events(詳見:https://www.videolan.org/developers/vlc/doc/doxygen/html/group__libvlc__event.html)。
2
實現(xiàn)方式
以一個網(wǎng)絡流為例,來獲取播放器的位置、最新時長和總時長。
首先,要創(chuàng)建一個事件列表,并訂閱它們。需要注意的是 libvlc_event_attach(),它的最后一個參數(shù)是用戶數(shù)據(jù),這里暫時沒有用到,所以指定為 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);
????}
}
然后,在事件處理程序(回調(diào)函數(shù))中處理它們。對于每一個事件(例如:libvlc_MediaPlayerPositionChanged)來說,都有一個結(jié)構(gòu)體(例如:media_player_position_changed)與之對應,通過它便能很容易地訪問具體的信息了:
static?void?handleEvents(const?libvlc_event_t?*event,?void?*userData)
{
????switch?(event->type)?{
????case?libvlc_MediaPlayerPositionChanged:
????????cout?<"Position:?"?<u.media_player_position_changed.new_position?<endl;
????????break;
????case?libvlc_MediaPlayerTimeChanged:
????????cout?<"New?Time:?"?<u.media_player_time_changed.new_time?<endl;
????????break;
????case?libvlc_MediaPlayerLengthChanged:
????????cout?<"Length:?"?<u.media_player_length_changed.new_length?<endl;
????????break;
????default:
????????break;
????}
}
最后,是對上述實現(xiàn)的具體調(diào)用,來一起看看吧:
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);
????//?創(chuàng)建事件管理器
????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
測試程序
運行程序,可以看到播放位置和時長在實時改變,如下所示:

如果想獲取更多的媒體信息,方法與上述實現(xiàn)類似。
·END·
?
點個在看,么么噠!

