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

相关推荐
m0_6145235534 分钟前
音频排障|多段视频音量忽大忽小,怎么统一响度:先分类再校准
音视频·视频编辑
梦帮科技1 小时前
AI 音乐产品的发布工程:验证门、数据发布、回滚与生产运维纪律
数据结构·数据库·架构·node.js·音视频·动态规划·推荐算法
泯泷1 小时前
那段文字是谁删的?Yjs 14 正式版之前,一套删除归属方案的实现与边界
前端·javascript·算法
hold?fish:palm1 小时前
34 合并K个升序链表
javascript·算法·链表
揽秀亭长1 小时前
视频转文字有哪些方法?在线AI、剪辑软件、本地对比
人工智能·音视频
Navigator_Z4 小时前
LeetCode //C - 1252. Cells with Odd Values in a Matrix
c语言·算法·leetcode
Quz5 小时前
QML Repeater 数据模型:ListModel 与 C++ QAbstractListModel
qt
语戚5 小时前
力扣 1621. 大小为K的不重叠线段的数目:动态规划(Java 实现)
java·算法·leetcode·动态规划·力扣·dp
Quz5 小时前
QML Repeater 基础用法:整数、JS 数组、字符串数组三种模型
qt
青山木5 小时前
Hot 100 --- 最长有效括号
java·数据结构·算法·leetcode·动态规划