海康sdk中包含了MP4解碼播放庫,對應的API函數都是PlayM4開頭的,顧名思義播放MP4,海康的視頻默認可以保存成MP4文件,可以用通用的播放器來播放,這就是為啥前面好多篇文章講到的各種內核錄像存儲都改成MP4來存儲,vlc、mpv、ffmpeg等,最終錄像存儲都轉換成MP4文件,看來大公司大廠做的也是保存成MP4文件,肯定是有他的道理,至於有多少道理,跟著他學者他這樣處理就行,可以先不用問不用管,直接上手擼代碼就對了,有些東西需要深究原理,而有些東西就沒有必要太過於細緻詢問下去了,折騰下去陷入死胡同,好比知道1+1=2就行,至於為啥=2,交給專門的研究人員去研究就行。
海康sdk的MP4解碼庫,即支持自身的MP4文件,也支持常規的MP4文件,而且最新版本還支持AVI文件格式,隨便試了本地的MP4文件,也都是支持的,如果需要拿到音視頻數據,只需要調用PlayM4_SetDecCallBackMend設置下解碼回調函數即可,比視頻流的回調流程簡單很多,少了設置回調處理函數一大堆處理,只需要解碼轉換成QImage即可。本地文件還需要增加一個文件結束回調,這樣能知道什麼時候文件播放完成了,發出對應的信號進行處理,可以調用PlayM4_SetFileEndCallback設置文件播放完畢回調函數,在FileEndCallback回調函數中,通過異步執行QMetaObject::invokeMethod停止函數來通知界面。
關於本地文件請注意以下幾點:
1. 文件方式播放下,不能調用PlayM4_CloseStream。
2. 流播放下,不能調用PlayM4_CloseFile接口。
3. 流開關接口和文件開關接口不能交叉使用。
1. 支持播放視頻流和本地MP4文件。
2. 支持句柄和回調兩種模式。
3. 多線程顯示圖像,不卡主界面。
4. 自動重連網絡攝像頭。
5. 可設置邊框大小即偏移量和邊框顏色。
6. 可設置是否繪製OSD標籤即標籤文本或圖片和標籤位置。
7. 可設置兩種OSD位置和風格。
8. 可設置是否保存到文件以及文件名。
9. 可直接拖曳文件到haikangwidget控制項播放。
10. 支持h264/h265視頻流。
11. 可暫停播放和繼續播放。
12. 支持存儲單個視頻文件和定時存儲視頻文件。
13. 自定義頂部懸浮條,發送單擊信號通知,可設置是否啟用。
14. 可設置畫面拉伸填充或者等比例填充。
15. 可設置解碼是速度優先、質量優先、均衡處理。
16. 可對視頻進行截圖(原始圖片)和截屏(視頻窗體)。
17. 錄像文件存儲為MP4文件。
18. 支持焦距控制、雲臺控制。
19. 可定製功能。
1. 國內站點:[https://gitee.com/feiyangqingyun/QWidgetDemo](https://gitee.com/feiyangqingyun/QWidgetDemo)
2. 國際站點:[https://github.com/feiyangqingyun/QWidgetDemo](https://github.com/feiyangqingyun/QWidgetDemo)
3. 個人主頁:[https://blog.csdn.net/feiyangqingyun](https://blog.csdn.net/feiyangqingyun)
4. 知乎主頁:[https://www.zhihu.com/people/feiyangqingyun/](https://www.zhihu.com/people/feiyangqingyun/)
5. 體驗地址:[https://blog.csdn.net/feiyangqingyun/article/details/97565652](https://blog.csdn.net/feiyangqingyun/article/details/97565652)
bool HaiKangThread::playLocal(){ //轉碼以便支持中文路徑 QtextCodec *codec = QTextCodec::codecForName(&34;); QByteArray data = codec->fromUnicode(url); PlayM4_GetPort(&port); bool ok = PlayM4_OpenFile(port, data.data()); if (ok) { //設置文件播放完畢回調函數 PlayM4_SetFileEndCallback(port, FileEndCallback, this); //回調則可以拿到音視頻數據,否則就直接句柄播放 if (callback) { PlayM4_SetDecCallBackMend(port, DecCallBack, (quser)this); PlayM4_Play(port, NULL); } else { PlayM4_Play(port, (HWND)playWidget->winId()); } //同時播放聲音 PlayM4_PlaySound(port); //倒放 //PlayM4_ReversePlay(port); //快進播放,多次調用速度更快 //PlayM4_Fast(port); //PlayM4_Fast(port); ok = true; qDebug() << TIMEMS << &34; << url; } else { qDebug() << TIMEMS << &34; << url << PlayM4_GetLastError(port); } return ok;}void HaiKangThread::free(){ if (isRtsp) { //停止播放+登出設備 NET_DVR_StopRealPlay(hand); NET_DVR_Logout(hand); hand = -1; } else { //停止播放+關閉文件+釋放埠 PlayM4_Stop(port); PlayM4_StopSound(); PlayM4_CloseFile(port); PlayM4_FreePort(port); port = -1; }}