將 libVLC 視頻渲染到 QWidget 中

在用 libVLC 播放視頻時(shí),會默認(rèn)顯示一個(gè) Direct3D output 窗口。這個(gè)窗口不太美觀,而且也沒辦法做一些定制,所以在絕大多數(shù)情況下都需要禁用(或者隱藏)它,好將視頻渲染到我們自己的窗口中。
在 libVLC 中,要實(shí)現(xiàn)這個(gè)功能并不難,只要調(diào)用平臺相關(guān)的接口,并將媒體播放器和窗口句柄傳遞進(jìn)去就可以了,這樣媒體播放器就會把視頻呈現(xiàn)到該窗口上。
1
主要接口
一定要區(qū)分開下面這幾個(gè)接口,因?yàn)樵诓煌脚_上(Windows/Linux/Mac OS)調(diào)用的不一樣:

好在它們的參數(shù)幾乎是一樣的,就拿適用于 Windows 平臺的接口來說,函數(shù)原型是這樣的:
void?libvlc_media_player_set_hwnd?(?libvlc_media_player_t?*p_mi,?void?*drawable?);
其中,p_mi 就是我們的媒體播放器,而 drawable 是一個(gè)可繪制的窗口句柄(即:最終要顯示視頻的那個(gè)窗口)。對于 Qt 來說,它可以是一個(gè)普通的 QWidget,也可以是一個(gè) QLabel,或者其他一些可用于顯示的部件。
2
實(shí)現(xiàn)方式
在 Qt 中,幾乎所有的 GUI 程序都使用 QApplication(控制臺程序使用 QCoreApplication),它的作用是管理 GUI 程序的控制流和主要設(shè)置:
int?main(int?argc,?char?*argv[])
{
????const?char?*?rtspMrl?=?"rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov";
????QApplication?app(argc,?argv);
接下來,創(chuàng)建 libVLC?媒體環(huán)境,具體解釋見《最簡單的 libVLC 播放器》:
????libvlc_instance_t?*instance;
????libvlc_media_player_t?*player;
????libvlc_media_t?*media;
????//?創(chuàng)建?libvlc?實(shí)例、媒體、播放器
????instance?=?libvlc_new(0,?nullptr);
????media?=?libvlc_media_new_path(instance,?localMrl);
????player?=?libvlc_media_player_new_from_media(media);
到了最關(guān)鍵的一步?- 創(chuàng)建一個(gè) QWidget,并將其傳遞給 VLC,然后顯示該窗口并進(jìn)行播放:
????//?創(chuàng)建一個(gè)窗口,用于顯示視頻
????QWidget?widget;
????widget.resize(600,?400);
????WId?currentWId?=?widget.winId();
????//?設(shè)置視頻輸出窗口
#if?defined?(Q_OS_WIN)
????libvlc_media_player_set_hwnd(player,?(void?*)currentWId);
#elif?defined?(Q_OS_UNIX)
????libvlc_media_player_set_xwindow(player,?currentWId);
#elif?defined(Q_OS_MAC)
????libvlc_media_player_set_nsobject(player,?(void?*)currentWId);
#endif
????//?將窗口顯示出來
????widget.show();
????//?播放
????libvlc_media_player_play(player);
調(diào)用 exec() 進(jìn)入主事件循環(huán)。Qt 會接受并處理用戶和系統(tǒng)的事件,并將它們傳遞給適當(dāng)?shù)牟考?/p>
????int?retVal?=?app.exec();
最后,在程序退出之前,記得釋放資源:
????//?釋放資源
????libvlc_media_release(media);
????libvlc_media_player_release(player);
????libvlc_release(instance);
????return?retVal;
}
和之前的代碼相比,這里的改動并不算大。除了加了一些 Qt 的東西之外,主要就是使用了一些條件語句,根據(jù)特定的宏來區(qū)分不同的操作系統(tǒng),這樣我們的程序就能夠跨平臺了。
注意:這里用到的 RTSP 是一個(gè)測試地址,并不能保證隨時(shí)有效。倘若無法播放,請更換為可用的地址。
3
測試程序
迫不及待了,運(yùn)行看看效果吧(網(wǎng)絡(luò)流稍慢,稍等片刻):

哇~,簡直棒極了!
·END·
?
點(diǎn)個(gè)在看,么么噠!

