使用Qt+大华设备SDK预览大华摄像机视频

目录

1、准备工作

2、初始化SDK

3、登录

4、预览视频

5、视频预览示例

6、总结


非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格式的原始视频数据,自己渲染视频,效果应该会好一些。

相关推荐
罗超驿6 小时前
9.优先级队列与堆:从底层原理到实战应用的完整指南
数据结构·算法
byte轻骑兵6 小时前
【LE Audio】CSIS精讲[4]: 从加密原语到RSI解析全链路拆解
音视频·人机交互·蓝牙耳机·le audio·低功耗蓝牙音频
郝学胜-神的一滴7 小时前
Qt 高级编程 035:无边框窗口阴影以及圆角双特效实现
开发语言·c++·qt·程序人生·用户界面
AI科技星7 小时前
光速螺旋时空曲率挠率拓扑统一场论——四大力全域闭环求导、精算验证与第一性原理完备证明
线性代数·算法·决策树·机器学习·常温超导·ai科技星
牧以南歌〆7 小时前
数据结构<三>单循环链表
c语言·数据结构·算法·链表
liuzhijie-06147 小时前
Codeforces 2245 D2 / E / F 题解
算法
EasyDSS7 小时前
视频直播点播/音视频点播/云点播/云直播EasyDSS一站式音视频平台赋能社交娱乐场景创新
音视频·娱乐
薛定e的猫咪7 小时前
在 vibe coding开发项目过程中使用过的命令和概念整理
人工智能·学习·算法·开源
Tisfy7 小时前
LeetCode 1979.找出数组的最大公约数:模拟(附手动gcd)
java·数学·算法·leetcode·题解·最大公约数