前言
工程需要把海康威视网络摄像头的视频流显示在Qt开发的界面上,一时间摸不到头绪。
也提醒大家一下,Qt自带的QCamera类对网络摄像头是无解的,不要白费力气了。
查了资料,发现海康威视官网提供一个SDK包用于支持二次开发,下载下来发现没有Qt版本的Demo,摸索了半天,借鉴了优快云里的大神们的文章,依旧没有成功。
情急之下联系了海康官方,一个邮件指出了我的问题,成功的将网络摄像头的数据显示在了QLabel上。
现在将我的经验分享给大家,希望对大家有所帮助。
环境搭建
系统:Win7 32位
开发环境:Qt 5.7.0+海康威视SDK
首先搭建一个支持海康SDK的环境,对于SDK提供的lib和dll文件的使用,我读了一篇文章,文章提到了哪些需要,哪些不需要,我完全按照他说的挑拣出来搭环境,发现程序是运行起来了,但是总是提示“设备操作失败”。在咨询了海康的工程师后,人家一语道破:你dll拷贝的不全,才会出现设备操作失败。所以对于dll和lib,我的做法是:不挑不捡,全部使用!
具体方法是:
lib文件
把所有的lib文件拷贝到Qt编译的目录中(一般情况是以build开头的文件夹,和Makefile文件同目录下),我为了不乱,新建了一个lib文件夹,统一存放lib文件。
然后在工程的pro文件里把这些lib文件加入工程:
LIBS +="./lib/HCCore.lib"
LIBS +="./lib/HCNetSDK.lib"
LIBS +="./lib/HCAlarm.lib"
LIBS +="./lib/HCGeneralCfgMgr.lib"
LIBS +="./lib/HCPreview.lib"
LIBS +="./lib/PlayCtrl.lib"
dll文件
设置完lib文件,接下来把dll文件拷贝到和执行文件同一根目录下(一般是debug或者release文件夹里),记住,包括“库文件”目录下的dll文件,以及里面的“ClientDemoDll”文件夹,不要把文件夹里的dll拷出了,直接把这个文件夹拷过去就可以了。
.h文件
接下来把SDK中的所有头文件加到Qt工程里面,并将其包含到你想要实现的类里面:
#include "HCNetSDK.h"
#include "DataType.h"
#include "plaympeg4.h"
#include "DecodeCardSdk.h"
除此之外,也把windows.h包含进去吧。
这样一来,环境搭建就完成了。我们可以开始写程序了。
关键代码实现
首先是初始化和注册,直接贴代码吧:
bool HikvisionCameraMan::InitialCameraMan()
{
//初始化
bool ret_value=NET_DVR_Init();
int ret_error_num;
if(ret_value==false)
{
ret_error_num=NET_DVR_GetLastError();
qDebug()<<"error number:"<<ret_error_num;
return ret_value;
}
ret_value=NET_DVR_SetConnectTime(2000, 1);
if(ret_value==false)
{
ret_error_num=NET_DVR_GetLastError();
qDebug()<<"error number:"<<ret_error_num;
return ret_value;
}
ret_value=NET_DVR_SetReconnect(10000, true);
if(ret_value==false)
{
ret_error_num=NET_DVR_GetLastError();
qDebug()<<"error number:"<<ret_error_num;
return ret_value;
}
user_id=NET_DVR_Login_V30("192.168.1.64",8000,"admin","aaaAAA111",&device_info);
if(user_id<0)
{
ret_error_num=NET_DVR_GetLastError();
qDebug()<<"error number:"<<ret_error_num;
return false;
}
real_play_handle=-1;
return true;
}
要注意的是,诸如NET_DVR_Init这样的函数,Qt编译器不会认为是函数,别管,直接写上去编译肯定能通过。
NET_DVR_Login_V30函数中的参数,第一个是网络摄像头的地址,第二个是端口号,这两个是默认的,第三个是用户名,第四个是密码,需要你提前用浏览器登录摄像头配置页进行自己设置,具体教程很容易找到。
初始化和注册函数可以在构造函数里调用,完成对设备的初始化,如果出现初始化或者注册不成功(一般返回-1)时,可以在返回失败的函数后面马上调用NET_DVR_GetLastError函数查看错误码是什么,海康威视SDK有错误码字典,网上很容易找到。
经验之谈:出现初始化或者注册失败的原因,很大可能是你dll文件或者lib文件加载的不够全
接下来是实现打开摄像头的操作了,上代码:
void HikvisionCameraMan::PlayCamera(HWND hWnd, NET_DVR_PREVIEWINFO play_info)
{
play_info={0};
play_info.hPlayWnd = hWnd;//需要 SDK 解码时句柄设为有效值,仅取流不解码时可设为空
play_info.lChannel = 1;//预览通道号
play_info.dwStreamType = 0;//码流类型:0-主码流,1-子码流,2-三码流,3-虚拟码流,以此类推
play_info.dwLinkMode = 0;//0- TCP 方式,1- UDP 方式,2- 多播方式,3- RTP 方式,4-RTP/RTSP,5-RSTP/HTTP
play_info.bBlocked = 1;//0- 非阻塞取流,1- 阻塞取流
real_play_handle= NET_DVR_RealPlay_V40(user_id,&play_info,NULL,NULL);
if(real_play_handle <0)
{
qDebug()<< "NET_DVR_RealPlay_V40 error;error number " <<NET_DVR_GetLastError();
NET_DVR_Logout(user_id);
}else{
is_playing=true;
}
}
关闭摄像头的函数是:
void HikvisionCameraMan::StopCamera()
{
if(real_play_handle!=-1)
{
NET_DVR_StopRealPlay(real_play_handle);
real_play_handle=-1;
is_playing = false;
}
}
好了,摄像头类的编写差不多了,使用方法是:
在界面设计类实例化一个HikvisionCameraMan类,在构造函数中初始化:
camera_man.InitialCameraMan();
然后在界面里拽一个QLabel类,再拽一个pushButton,实现它的单击槽函数:
void MainWindow::on_pushButtonLogin_clicked()
{
HWND hWnd = (HWND)ui->label->winId();
NET_DVR_PREVIEWINFO play_info;
camera_man.PlayCamera(hWnd,play_info);
}
然后编译通过后,单击这个按钮,就会在label中看到视频流了。
如果有任何疑问,可以加我VX:ConciseRabbit进行交流。
本文介绍了如何在Qt环境下,利用海康威视的SDK将网络摄像头的视频流显示在Qt界面中。主要内容包括环境搭建,如lib、dll文件的配置,以及关键代码实现,如设备初始化、登录、视频流显示等。注意,确保dll和lib文件完整,以避免设备操作失败的问题。
864

被折叠的 条评论
为什么被折叠?



