目录
非AI生成,觉得有用,就请您帮忙点赞转发收藏吧,您的鼓励是我创作的动力,多谢看官。
由于能力水平有限,文中的错误或不严谨的地方在所难免,还请批评指正。
1、准备工作
访问大华官网下载设备SDK
大华官网下载地址:设备SDK下载地址

2、初始化SDK
调用大华SDK之前,必须初始化SDK,否则SDK函数将无法正常执行。
初始化SDK,调用其他SDK函数的前提。
BOOL CLIENT_Init(fDisConnect cbDisConnect, LDWORD dwUser)
3、登录
登录设备函数:
CLIENT_Login(const char *pchDVRIP, WORD wDVRPort, const char *pchUserName, const char *pchPassword, LPNET_DEVICEINFO lpDeviceInfo, int *error = 0);
pchDVRIP:摄像机IP
wDVRPort:摄像机端口,海康摄像机端口一般都是8000
pchUserName:用户名
pchPassword:用户密码
lpDeviceInfo:设备信息指针,一般初始化设备信息结构体对象取地址就可以了
error:错误编号信息
4、预览视频
视频预览函数:
///@brief 打开实时预览,若返回0表示打开失败
///@paramin lLoginID 登录句柄
///@paramin nChannelID 通道号
///@paramin hWnd 窗口句柄
///@paramin rType 播放类型
///@paramin cbRealData 实时流数据回调
///@paramin cbDisconnect 断线回调
///@paramin dwUser 用户输入参数
///@paramin dwWaitTime 接口超时时间, 单位毫秒
///@return 播放句柄
CLIENT_NET_API LLONG CALL_METHOD CLIENT_StartRealPlay(LLONG lLoginID, int nChannelID, HWND hWnd, DH_RealPlayType rType, fRealDataCallBackEx cbRealData, fRealPlayDisConnect cbDisconnect, LDWORD dwUser, DWORD dwWaitTime = 10000);
实时流回调函数:///@brief 实时预览数据回调函数原形--扩展(pBuffer内存由SDK内部申请释放)
/// 通过 dwDataType 过滤得到对应码流,具体码流类型请参考 EM_REALDATA_FLAG; 转码流时 dwDataType 值请参考 NET_DATA_CALL_BACK_VALUE 说明
typedef void (CALLBACK *fRealDataCallBackEx)(LLONG lRealHandle, DWORD dwDataType, BYTE *pBuffer, DWORD dwBufSize, LONG param, LDWORD dwUser);
视频预览断开回调函数:///@brief 视频预览断开回调函数原形, (param内存由SDK内部申请释放 )
typedef void (CALLBACK *fRealPlayDisConnect)(LLONG lOperateHandle, EM_REALPLAY_DISCONNECT_EVENT_TYPE dwEventType, void* param, LDWORD dwUser);
5、视频预览示例
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
using namespace DaHua;
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
m_isSdkInited = CLIENT_Init(&MainWindow::DisConnectFunc, 0);
//设置连接参数
CLIENT_SetConnectTime(3000, 3);
m_logMsg =QString("%1 初始化大华设备SDK资源 %2").arg(Utility::getNowTimeStrWithMs()).arg(m_isSdkInited?"成功":"失败");;
ui->tbLog->appendPlainText(m_logMsg);
}
MainWindow::~MainWindow()
{
NET_DVR_Cleanup();
delete ui;
}
void MainWindow::on_btnPreview_clicked()
{
if(m_playHandle>0){
QMessageBox::information(this,"系统提示","正在预览视频呢");
return;
}
auto ip = ui->tbIP->text().toUtf8();
ushort port = ui->tbPort->text().toUShort();
auto userName = ui->tbUserName->text().toUtf8();
auto password = ui->tbPassword->text().toUtf8();
qDebug()<<ip<<port<<userName<<password;
NET_DEVICEINFO devInfo;
int error;
m_userHandle = CLIENT_Login(ip.data(),port,userName.data(),password.data(),&devInfo,&error);
if(m_userHandle>0){
m_logMsg = QString("%1 登录句柄:%2").arg(Utility::getNowTimeStrWithMs()).arg(m_userHandle);
ui->tbLog->appendPlainText(m_logMsg);
}
else{
errNo = CLIENT_GetLastError();
m_logMsg = QString("%1 登录句柄:%2,错误信息:错误编码%3").arg(Utility::getNowTimeStrWithMs()).arg(m_userHandle).arg(errNo);
ui->tbLog->appendPlainText(m_logMsg);
return;
}
//注意:大华摄像机起始通道号从0开始,和海康摄像机的起始通道号不同
//rType:DH_RType_Realplay_0 主码流
//cbRealData:实时预览数据回调函数置空
//cbDisconnect:视频预览断开回调函数置空
m_playHandle = CLIENT_StartRealPlay(m_userHandle,0,(void *)ui->frameVideo->winId(),DH_RType_Realplay_0,nullptr,nullptr,0,5000);
if(m_playHandle>0){
m_logMsg = QString("%1 预览视频成功,预览句柄:%2").arg(Utility::getNowTimeStrWithMs()).arg(m_playHandle);
}
else{
errNo = CLIENT_GetLastError();
m_logMsg = QString("%1 预览视频失败,预览句柄:%2,错误信息:错误编码%3").arg(Utility::getNowTimeStrWithMs()).arg(m_userHandle).arg(errNo);
}
ui->tbLog->appendPlainText(m_logMsg);
}
void MainWindow::on_btnStop_clicked()
{
if(m_playHandle>0){
bool ret = CLIENT_StopRealPlayEx(m_playHandle);
if(ret){
m_playHandle = -1;
m_logMsg = QString("%1 停止预览视频成功").arg(Utility::getNowTimeStrWithMs());
ui->tbLog->appendPlainText(m_logMsg);
ret = CLIENT_Logout(m_userHandle);
if(ret){
m_userHandle = -1;
}
ui->frameVideo->update();
}
}
}
void MainWindow::DisConnectFunc(LLONG lLoginID, char *pchDVRIP, LONG nDVRPort, LDWORD dwUser)
{
QString logMsg = QString("Device disconnect, IP=%1, Port=%2").arg(pchDVRIP).arg(nDVRPort);
}
程序运行截图



6、总结
这个例子做的比较简单 ,只支持看一个摄像机的视频,实际的监控软件必须支持同时预览多路视频的,此处使用SDK渲染视频,窗口尺寸变化时视频会有闪烁现象,实际开发中可以用解码库解码得到YUV格式的原始视频数据,自己渲染视频,效果应该会好一些。