RTSP視頻流顯示(海康威視)
本文目的主要是想要實時顯示海康威視的攝像頭數據,筆者嘗試瞭如下幾種方式(部分未做完):
- VLC
- SDK(C++)
- ffmpeg+Nginx
- ffmpeg直接解碼RTSP
VLC
如果使用插件需要注意谷歌瀏覽器版本,本文是在官網下載的軟件,下載下來安裝並運行:
填的地址就是攝像頭RTSP視頻流地址,然後點串流:
左上角是這樣的說明就已經在轉換了:
網頁顯示注意資源地址,同一局域網下的要訪問就需要把localhost改爲轉換軟件運行電腦的ip地址:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Video</title>
</head>
<body>
<video src="http://localhost:8080/test" width="350px" height="250px" controls="controls">
不支持
</video>
</body>
</html>
這種方式轉換多路的時候,時間越久延遲會越大。
SDK(C++)
本文使用環境如下:
- 操作系統:win10 64位
- Qt版本: 5.13.0
- 編譯器版本:mingw73_64
SDK下載。
一定要注意版本。
編寫應用
- 下載SDK下來解壓,複製如下需要的文件到工程:
改名爲:
- 然後在.pro中添加庫路徑,:
LIBS+=$$PWD/libs/HCCore.lib
LIBS+=$$PWD/libs/HCNetSDK.lib
LIBS+=$$PWD/libs/GdiPlus.lib
LIBS+=$$PWD/libs/PlayCtrl.lib
LIBS+=$$PWD/libs/HCNetSDKCom/HCAlarm.lib
LIBS+=$$PWD/libs/HCNetSDKCom/HCGeneralCfgMgr.lib
LIBS+=$$PWD/libs/HCNetSDKCom/HCPreview.lib
添加頭文件幷包含:
#include <windows.h>
#include <head/HCNetSDK.h>
3. 再把庫文件夾中所有dll文件放到編譯後exe所在路徑(有些用不上,但是全部找出來添加不會有問題):
4. 然後開始調用函數初始化:
// 初始化
bool isok = NET_DVR_Init();
if(isok == false)
{
qDebug() << "NET_DVR_Init error;error number is " <<NET_DVR_GetLastError();
return;
}
//設置連接時間與重連時間
NET_DVR_SetConnectTime(2000, 1);
NET_DVR_SetReconnect(10000, true);
點擊按鈕開始連接(佈局中只有一個名爲faceRecognition的label和名爲connectFaceRecognition的按鈕):
int faceRecognitionRealPlayHandle = 0;
int faceRecognitionUserID = 0;
if(ui->connectFaceRecognition->text() =="連接"){
NET_DVR_DEVICEINFO_V30 deviceInfoTmp;
// 攝像頭IP,用戶名和密碼
faceRecognitionUserID = NET_DVR_Login_V30("192.168.31.168",8000,"admin","chuanghai2017",&deviceInfoTmp);
if(faceRecognitionUserID<0)
{
errorCode = NET_DVR_GetLastError();
QMessageBox::warning(NULL,"提示",QString("攝像頭登陸失敗! 錯誤碼:%1").arg(errorCode));
return;
}
//啓動預覽
NET_DVR_PREVIEWINFO struPlayInfo;
struPlayInfo.hPlayWnd = (HWND)ui->faceRecognition->winId(); //設置獲取窗口句柄 需要 SDK 解碼時句柄設爲有效值,僅取流不解碼時可設爲空
struPlayInfo.lChannel = 1; //預覽通道號
struPlayInfo.dwStreamType = 0; //0-主碼流,1-子碼流,2-碼流 3,3-碼流 4,以此類推
struPlayInfo.dwLinkMode = 0; //0- TCP 方式,1- UDP 方式,2- 多播方式,3- RTP 方式,4-RTP/RTSP,5-RSTP/HTTP
struPlayInfo.bBlocked = 1; //0- 非阻塞取流,1- 阻塞取流
struPlayInfo.dwDisplayBufNum = 15; //播放庫播放緩衝區最大緩衝幀數
faceRecognitionRealPlayHandle = NET_DVR_RealPlay_V40(faceRecognitionUserID, &struPlayInfo, NULL, NULL);
if(faceRecognitionRealPlayHandle <0)
{
errorCode = NET_DVR_GetLastError();
QMessageBox::warning(NULL,"提示",QString("攝像頭播放失敗! 錯誤碼:%1").arg(errorCode));
NET_DVR_Logout(faceRecognitionUserID);
}else{
ui->connectFaceRecognition->setText("斷開");
}
}else{
//關閉預覽
NET_DVR_StopRealPlay(faceRecognitionRealPlayHandle);
//註銷用戶
NET_DVR_Logout(faceRecognitionUserID);
ui->connectFaceRecognition->setText("連接");
}
ffmpeg+Nginx
ffmpeg安裝比較簡單,下載下來把bin目錄配置到環境變量,就OK了。
先運行nginx.exe(需要是已經集成rtmp模塊的):
再打開cmd輸入如下並回車:
ffmpeg -i "rtsp://admin:[email protected]:554/h265/ch1/main/av_stream" -f flv -r 25 -s 640x360 -an rtmp://localhost:1935/live/room
看到這樣的狀態就可以訪問rtmp://localhost:1935/live/room顯示圖像,不過需要瀏覽器支持rtmp:
這種方式丟幀明顯,圖像模糊。
直接使用ffmpeg解碼視頻
這裏對這個demo作者表示感謝,寫得確實已經很精簡了,也就不說了,作者提到的關閉Shadow build:
在測試中發現有時候顯示會有一半模糊具體原因還不太清除,如果有讀者知道也請賜教: