Qt音視訊開發4-vlc讀取和控制
阿新 • • 發佈:2020-08-06
一、前言
vlc本身是個全功能的很牛逼的播放器,你能夠想到的播放的功能他都有,比如獲取視訊檔案的長度、唱片的封面、當前播放進度、設定播放進度、聲音控制、靜音控制等,這些vlc都給你封裝好了,你直接呼叫對應的api函式即可。
看vlc的官方對vlc的更新頻率也是蠻高的,所以在各種新的視訊標準和格式出來以後,他也是在不斷的更新完善,比如H265,8K視訊等,都能正常的播放,查閱vlc的動態庫目錄可以看見,vlc的部分解碼用的就是ffmpeg,所以知道了為啥他這麼強大了吧,原來是依賴ffmpeg這個超級牛逼的全功能解碼庫呢。
用vlc做控制這塊有兩種處理方式,一種是線上程中來定時讀取,比如讀取播放進度、當前各種狀態、當前音量、靜音等,還有一種方式是採用事件回撥的形式,預設建議事件回撥的機制,能夠拿到很多事件訊息,效率也更高。你只需要在開啟視訊以前呼叫libvlc_event_attach訂閱自己感興趣的事件,在不需要的時候比如關閉的時候呼叫libvlc_event_detach登出訂閱的事件即可。
二、功能特點
- 多執行緒實時播放視訊流和本地視訊。
- 支援windows+linux+mac,支援vlc2和vlc3。
- 多執行緒顯示影象,不卡主介面。
- 自動重連網路攝像頭。
- 可設定邊框大小即偏移量和邊框顏色。
- 可設定是否繪製OSD標籤即標籤文字或圖片和標籤位置。
- 可設定兩種OSD位置和風格。
- 可設定是否儲存到檔案以及檔名。
- 可直接拖曳檔案到vlcwidget控制元件播放。
- 支援h265視訊流+rtmp等常見視訊流。
- 可暫停播放和繼續播放。
- 支援回撥模式和控制代碼兩種模式。
- 支援執行緒讀取進度等資訊和事件回撥兩種處理模式。
- 自動將當前播放位置和音量大小是否靜音以訊號發出去。
- 提供介面設定播放位置和音量及設定靜音。
- 支援儲存單個視訊檔案和定時儲存視訊檔案。
- 自定義頂部懸浮條,傳送單擊訊號通知,可設定是否啟用。
三、效果圖
四、相關站點
- 國內站點:https://gitee.com/feiyangqingyun/QWidgetDemo
- 國際站點:https://github.com/feiyangqingyun/QWidgetDemo
- 個人主頁:https://blog.csdn.net/feiyangqingyun
- 知乎主頁:https://www.zhihu.com/people/feiyangqingyun/
- 體驗地址:https://blog.csdn.net/feiyangqingyun/article/details/97565652
五、核心程式碼
void VlcThread::setSize(int width, int height)
{
if (vlcPlayer != NULL) {
QString option = QString("%1:%2").arg(width).arg(height);
QByteArray data = option.toUtf8();
const char *arg = data.constData();
//一旦開啟視訊以後要動態更改寬高比,值只能是vlc認識的比如 16:9 1:1 之類的
//const char *arg = "4:3";
libvlc_video_set_aspect_ratio(vlcPlayer, arg);
}
}
bool VlcThread::getIsPlaying()
{
bool isPlaying = false;
if (vlcPlayer != NULL) {
int result = libvlc_media_player_is_playing(vlcPlayer);
isPlaying = (result != 0);
}
return isPlaying;
}
VlcThread::VlcState VlcThread::getState()
{
VlcState state = VlcThread::VlcState_NothingSpecial;
if (vlcPlayer != NULL) {
state = (VlcState)libvlc_media_player_get_state(vlcPlayer);
}
return state;
}
uint VlcThread::getLength()
{
uint length = 0;
if (vlcPlayer != NULL) {
length = libvlc_media_player_get_length(vlcPlayer);
}
return length;
}
uint VlcThread::getPosition()
{
uint positon = 0;
if (vlcPlayer != NULL) {
positon = libvlc_media_player_get_time(vlcPlayer);
}
return positon;
}
void VlcThread::setPosition(int position)
{
if (vlcPlayer != NULL && !isRtsp) {
libvlc_media_player_set_time(vlcPlayer, position);
}
}
bool VlcThread::getMute()
{
bool ok = false;
if (vlcPlayer != NULL) {
int result = libvlc_audio_get_mute(vlcPlayer);
ok = (result == 0);
}
return ok;
}
void VlcThread::setMute(bool mute)
{
if (vlcPlayer != NULL) {
libvlc_audio_set_mute(vlcPlayer, mute ? 1 : 0);
}
}
int VlcThread::getVolume()
{
int volume = 0;
if (vlcPlayer != NULL) {
volume = libvlc_audio_get_volume(vlcPlayer);
}
return volume;
}
void VlcThread::setVolume(int volume)
{
if (vlcPlayer != NULL) {
libvlc_audio_set_volume(vlcPlayer, volume);
}
}
int VlcThread::getTrack()
{
int track = 0;
if (vlcPlayer != NULL) {
track = libvlc_audio_get_track(vlcPlayer);
}
return track;
}
int VlcThread::getTrackCount()
{
int trackCount = 0;
if (vlcPlayer != NULL) {
trackCount = libvlc_audio_get_track_count(vlcPlayer);
}
return trackCount;
}
void VlcThread::setTrack(int track)
{
if (vlcPlayer != NULL) {
track = libvlc_audio_set_track(vlcPlayer, track);
}
}