目录
1. 文章背景
2. 主要模块
2.1 初始化SDK
2.2登录账号
2.3 捕获图片
2.4 实时显示
2.5 断开时释放
2.6回调函数
3. 源代码
3.1 头文件
3.2 源文件
1. 文章背景
项目中需要使用大华的网络摄像头,之前为了图方便,我是通过opencv打开rtsp地址,从而显示和存图,但由于客户后期更换了摄像头,且希望采图效率更高,预估rtsp难以达到,所以考虑从大华官方SDK下手,就有了这篇文章。
2. 主要模块
其实官方的例程已经写得很详细了,不过官方的Demo是用MFC写的,考虑到一些朋友对MFC不是很熟(主要是指我自己 0-0),我就用qt c++写了这部分功能,因为基于QT,所以我的很多代码习惯是qt的,比如实时图像显示的窗体句柄,我是直接取的Qt上的一个QLbel的句柄。
2.1 初始化SDK
初始SDK:CLIENT_Init,就一个接口,没啥好说的。
// 初始化 SDKg_bNetSDKInitFlag = CLIENT_Init((fDisConnect)DisConnectFunc, 0);QString logInfo = QSC("SDK初始化%1。").arg(g_bSnapPictureFlag ? QSC("成功") : QSC("失败"));qDebug() << logInfo;
2.2登录账号
按摄像头信息登录:CLIENT_LoginWithHighLevelSecurity,这里需要注意的就是把ip,port,用户,密码这些信息按照固定格式存进输入参数结构里,再调相应的接口就好了。
//获取登录信息strcpy(D_Ip, ip.toLatin1().data());strcpy(D_UserName, name.toLatin1().data());strcpy(D_Pasdwd, password.toLatin1().data());D_Port = port;strncpy(stInparam.szIP, D_Ip, sizeof(stInparam.szIP) - 1);strncpy(stInparam.szUserName, D_UserName, sizeof(stInparam.szUserName) - 1);strncpy(stInparam.szPassword, D_Pasdwd, sizeof(stInparam.szPassword) - 1);stInparam.nPort = D_Port;stInparam.emSpecCap = EM_LOGIN_SPEC_CAP_TCP;// 登录设备tagNET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY stOutparam;LoginHandle = CLIENT_LoginWithHighLevelSecurity(&stInparam, &stOutparam);QString logInfo = QSC("设备登录%1:%2 %3。").arg(ip).arg(D_Port).arg(LoginHandle? QSC("成功") : QSC("失败,错误码[%1]").arg(QString::number(CLIENT_GetLastError(), 16)));qDebug() << logInfo;
2.3 捕获图片
捕获图片要做两个动作:
1. 首先是设置回调函数:CLIENT_SetSnapRevCallBack(回调函数名, NULL); 回调函数的内容在后面我会贴出来。
2. 然后在你想抓图的时候调抓图接口:CLIENT_SnapPictureEx(登录句柄, &stuSnapParams);
// 设置抓图回调函数CLIENT_SetSnapRevCallBack(SnapRev, NULL);//事例中默认通道 ID 为 0、抓图模式为抓一幅图,用户可根据实际情况自行选择int nChannelId = 0;int nSnapType = 0;// 抓图模式;-1:表示停止抓图, 0:表示请求一帧, 1:表示定时发送请求, 2:表示连续请求// 发送抓图命令给前端设备SNAP_PARAMS stuSnapParams;stuSnapParams.Channel = nChannelId;stuSnapParams.mode = nSnapType;stuSnapParams.CmdSerial = 0;//++g_nCmdSerial; // 请求序列号,有效值范围 0~65535,超过范围会被截断为 unsigned shortg_bSnapPictureFlag = CLIENT_SnapPictureEx(LoginHandle, &stuSnapParams);QString logInfo = QSC("SDK抓图%1。").arg(g_bSnapPictureFlag? QSC("成功") : QSC("失败,错误码[%1]").arg(QString::number(CLIENT_GetLastError(), 16)));qDebug() << logInfo;
2.4 实时显示
实时显示有两种方式:一是直接在某个窗体句柄下显示;二是存起来,用其他方式解码。
我这里只是为了能实时看到,所以是用了一个QLabel来显示,首先获取这个控件的句柄:winId(),然后在你想看实时图像的时候调实时预览的接口:CLIENT_RealPlayEx(登录句柄, 通道号, 用于显示图像的控件句柄, 也可以不写默认就是实时监视);
// 实现实时监视功能业务// 获取控制台窗口句柄// 1.例程中的方法// HMODULE hKernel32 = GetModuleHandle("kernel32");// GetConsoleWindow = (PROCGETCONSOLEWINDOW)GetProcAddress(hKernel32,"GetConsoleWindow");// HWND hWnd = GetConsoleWindow();// NULL;// 2.获取qt控件的方法HWND hWnd = (HWND)ui->label_RealDisplay->winId();//开启实时监视int nChannelID = 0; // 预览通道号DH_RealPlayType emRealPlayType = DH_RType_Realplay; // 实时监视lHandle = CLIENT_RealPlayEx(LoginHandle, nChannelID, hWnd, emRealPlayType);QString logInfo = QSC("实时显示开启%1。").arg(lHandle ? QSC("成功") : QSC("失败,错误码[%1]").arg(QString::number(CLIENT_GetLastError(), 16)));qDebug() << logInfo;
2.5 断开时释放
我个人觉得有一个好的习惯是很重要的,就像指针一样,一定要有new 有delete,当然如果你懒得写相应的函数,你也可以把它们写在析构里。
// 关闭预览if (lHandle){bool lHandleFlag = CLIENT_StopRealPlayEx(lHandle);QString logInfo = QSC("实时显示关闭%1。").arg(lHandleFlag ? QSC("成功") : QSC("失败,错误码[%1]").arg(QString::number(CLIENT_GetLastError(), 16)));qDebug() << logInfo;if(lHandleFlag)lHandle = false;}// 退出设备if (LoginHandle){bool LoginHandleFlag = CLIENT_Logout(LoginHandle);QString logInfo = QSC("实时显示关闭%1。").arg(LoginHandleFlag ? QSC("成功") : QSC("失败,错误码[%1]").arg(QString::number(CLIENT_GetLastError(), 16)));qDebug() << logInfo;if(LoginHandleFlag)LoginHandle = false;}// 清理初始化资源if (g_bNetSDKInitFlag){CLIENT_Cleanup();g_bNetSDKInitFlag = false;}
2.6回调函数
能正常显示的前提还需要一些回调函数,断开重连那几个都一样,你如果需要是连了很多个摄像头,可以在回调函数里把一些信息log出来,我这里暂时是连一个,所以就没打印信息,只是打印了一下调用信息。
//断线回调void CALLBACK MainWidget::DisConnectFunc(LLONG lLoginID, char *pchDVRIP, LONG nDVRPort, DWORD dwUser){qDebug() << QSC("断线回调\n");}
//重连回调void CALLBACK MainWidget::HaveReConnect(LLONG lLoginID,char *pchDVRIP,LONG nDVRPort,LDWORD dwUser){qDebug() << QSC("重连回调\n");}
抓图回调里面可以设置抓图的路径
//抓图回调void CALLBACK MainWidget::SnapRev(LLONG lLoginID, BYTE *pBuf, UINT RevLen, UINT EncodeType, DWORD CmdSerial, LDWORD dwUser){qDebug() << QSC("抓图回调\n");qDebug() << QSC("抓图句柄:") << lLoginID;// if(lLoginID == LoginHandle){if (NULL != pBuf && RevLen > 0){char szPicturePath[256] = "";_snprintf(szPicturePath, sizeof(szPicturePath)-1, QString("D:\\%1.bmp").arg(lLoginID).toLatin1());qDebug() << QSC("图片地址:%1").arg(szPicturePath);FILE* pFile = fopen(szPicturePath, "wb");if (NULL == pFile)return;int nWrite = 0;while(nWrite != RevLen)nWrite += fwrite(pBuf + nWrite, 1, RevLen - nWrite, pFile);fclose(pFile);}}}
3. 源代码
3.1 头文件
#pragma once#include <QWidget>#include "haatwidgetmain.h"#include <opencv2/core/core.hpp>#include <opencv2/highgui/highgui.hpp>#include <opencv2/opencv.hpp>#include "dhnetsdk.h"using namespace std;using namespace Haat;using namespace cv;QT_BEGIN_NAMESPACEnamespace Ui{class MainWidget;}QT_END_NAMESPACEclass MainWidget : public HaatWidgetBase{Q_OBJECTpublic:MainWidget(HaatWidgetFlags flag, QWidget *parent = nullptr);~MainWidget();// DHSDK开发接口Q_INVOKABLE double haat_CameraConnect(QString ip, int port, QString name = "admin", QString password = "admin123");Q_INVOKABLE bool haat_SDKCapture(int channel = 0);Q_INVOKABLE int haat_CameraCapture(QString imagePath);Q_INVOKABLE bool haat_RealDisplay(int channel = 0);Q_INVOKABLE bool haat_CloseDisplay();Q_INVOKABLE bool haat_CameraDisconnect();private slots:void on_tabWidget_currentChanged(int index);void on_btn_connect_clicked();void on_capture_clicked();void on_showImage_clicked();void on_realdisplay_clicked();void on_btn_browse_clicked();void on_sbx_num_valueChanged(int arg1);void on_cmb_ip_currentTextChanged(const QString &arg1);void on_cmb_channel_currentTextChanged(const QString &arg1);private:Ui::MainWidget *ui;QString DHSDK = "dhsdk";int getImageType(QString imagePath);void showImageInLabel(QLabel *m_label, QString imagePath);double getValue(QString value, int valueType = 0);QPalette pal;private:// ***************************大华SDK二次开发*********************************QString m_imagePath;bool g_bNetSDKInitFlag = false;bool g_bSnapPictureFlag = false;LLONG LoginHandle = false; //登录句柄LLONG lHandle = false;//监视句柄char D_Ip[32] = {0};char D_UserName[32] = {0};char D_Pasdwd[32] = {0};int D_Port = 37777;void h_capture(int channel);void h_connect(QString ip, int port, QString name = "admin", QString password = "admin123");void h_realDisplay(int channel);void h_closeDisplay();void h_disconnect();static void CALLBACK DisConnectFunc(LLONG lLoginID, char *pchDVRIP, LONG nDVRPort, DWORD dwUser);static void CALLBACK SnapRev(LLONG lLoginID, BYTE *pBuf, UINT RevLen, UINT EncodeType, DWORD CmdSerial, LDWORD dwUser);static void CALLBACK HaveReConnect(LLONG lLoginID, char *pchDVRIP, LONG nDVRPort, LDWORD dwUser);};
3.2 源文件
#include "mainwidget.h"#include "ui_mainwidget.h"#include <QVariantMap>#include <QDebug>#include "haatserviceclients.h"#include <QFileInfo>#include <QPainter>#include <QProxyStyle>#include <QFileDialog>#include <QTime>#define ISRPC trueMainWidget::MainWidget(HaatWidgetFlags flag, QWidget *parent): HaatWidgetBase(flag, parent), ui(new Ui::MainWidget){qDebug() << "Haat Rtsp Widget starting...";ui->setupUi(this);}MainWidget::~MainWidget(){h_closeDisplay();//登出设备CLIENT_Logout(LoginHandle);//清理SDK资源CLIENT_Cleanup();SERVICES->client(DHSDK)->quit();delete ui;}double MainWidget::haat_CameraConnect(QString ip, int port, QString name, QString password){h_connect(ip, port);return LoginHandle;}bool MainWidget::haat_SDKCapture(int channel){QString capImagePath = QString("D:\\%1.bmp").arg(LoginHandle);QDir m_capImagePath(capImagePath);if (m_capImagePath.exists())QFile::remove(capImagePath);h_capture(channel);return g_bSnapPictureFlag;}int MainWidget::haat_CameraCapture(QString imagePath){int imageType = -1;QDir *folder = new QDir();if(folder->exists(imagePath))QFile::remove(imagePath);qDebug() << QSC("登录句柄:") << LoginHandle;QString capImagePath = QString("D:\\%1.bmp").arg(LoginHandle);QFile file(capImagePath);if (folder->exists(capImagePath)){file.copy(imagePath);QFile::remove(capImagePath);}if (folder->exists(imagePath))imageType = getImageType(imagePath);delete folder;return imageType;}int MainWidget::getImageType(QString imagePath){std::string imagePathStr = imagePath.toStdString();Mat img = imread(imagePathStr);int row = img.rows;int col = img.cols;ui->textEdit->append(QSC("图片分辨率:%1 x %2").arg(col).arg(row));int imageType = -1;if(row == 1080 && col == 1920)imageType = 0;else if(row == 1620 && col == 2880)imageType = 1;elseimageType = 0;return imageType;}bool MainWidget::haat_RealDisplay(int channel){h_realDisplay(channel);return lHandle;}bool MainWidget::haat_CloseDisplay(){h_closeDisplay();return !lHandle;}bool MainWidget::haat_CameraDisconnect(){h_disconnect();return !g_bNetSDKInitFlag;}void MainWidget::on_btn_connect_clicked(){if(ui->btn_connect->text() == "Connect"){#if defined ISRPCauto status = SERVICES->client(DHSDK)->call("haat_CameraConnect", ui->ip->text(), ui->port->text().toInt());double result = status->result().toDouble();#elsedouble result = haat_CameraConnect(ui->ip->text(), ui->port->text().toInt());#endifui->textEdit->append(QSC("rpc登录句柄:%1\r\n全局变量登录句柄:%2\r\n").arg(result, 0, 'f', 0).arg(LoginHandle));ui->btn_connect->setAutoFillBackground(true);ui->btn_connect->setFlat(true);pal = ui->btn_connect->palette();if(result)pal.setColor(QPalette::Button, Qt::green);elsepal.setColor(QPalette::Button, Qt::red);ui->btn_connect->setPalette(pal);ui->btn_connect->setText(result? "Disconnect" : "Connect");ui->capture->setEnabled(result);ui->realdisplay->setEnabled(result);}else{#if defined ISRPCauto status = SERVICES->client(DHSDK)->call("haat_CameraDisconnect");#elsehaat_CameraDisconnect();#endifpal.setColor(QPalette::Button, Qt::yellow);ui->btn_connect->setPalette(pal);ui->btn_connect->setText("Connect");ui->capture->setEnabled(false);ui->realdisplay->setEnabled(false);}}void MainWidget::on_capture_clicked(){if(ui->imagePath->text().isEmpty())on_btn_browse_clicked();QTime startTime = QTime::currentTime();// rtsp协议拍照// auto status = SERVICES->client(DHSDK)->call("haat_rtspCapture", ui->ip->text(), ui->channel->text().toInt(), imagePath);// DHSDK拍照#if defined ISRPCauto status = SERVICES->client(DHSDK)->call("haat_SDKCapture");bool isCap = status->result().toBool();#elsebool isCap = haat_SDKCapture(ui->channel->text().toInt());#endifui->showImage->setEnabled(isCap);ui->textEdit->append(QSC("图片拍照: %1").arg(isCap ? QSC("成功") : QSC("失败")));QTime stopTime = QTime::currentTime();int elapsed = startTime.msecsTo(stopTime);ui->textEdit->append(QSC("图片拍照耗时:%1 ms\r\n").arg(elapsed));}void MainWidget::on_showImage_clicked(){QString imagePath = ui->imagePath->text();QTime startTime = QTime::currentTime();#if defined ISRPCauto status = SERVICES->client(DHSDK)->call("haat_CameraCapture", imagePath);int imageType = status->result().toInt();#elseint imageType = haat_CameraCapture(imagePath);#endifui->textEdit->append(QSC("图片获取: %1").arg(imageType == -1 ? QSC("失败") : QSC("成功")));QTime stopTime = QTime::currentTime();int elapsed = startTime.msecsTo(stopTime);ui->textEdit->append(QSC("图片获取耗时:%1 ms\r\n").arg(elapsed));showImageInLabel(ui->label_RealDisplay,imagePath);ui->showImage->setEnabled(false);}void MainWidget::showImageInLabel(QLabel* m_label, QString imagePath){QPixmap Pix; Pix.load(imagePath);Pix= Pix.scaled(m_label->width(), m_label->height(), Qt::KeepAspectRatio, Qt::SmoothTransformation);m_label->setScaledContents(true);m_label->setPixmap(Pix);}void MainWidget::on_realdisplay_clicked(){if(ui->realdisplay->text() == "RealDisplay"){#if defined ISRPCauto status = SERVICES->client(DHSDK)->call("haat_RealDisplay", ui->channel->text().toInt());bool result = status->result().toBool();#elsebool result = haat_RealDisplay(ui->channel->text().toInt());#endifui->realdisplay->setAutoFillBackground(true);ui->realdisplay->setFlat(true);pal = ui->realdisplay->palette();if(result)pal.setColor(QPalette::Button, Qt::green);elsepal.setColor(QPalette::Button, Qt::red);ui->realdisplay->setPalette(pal);ui->realdisplay->setText(result? "CloseDisplay" : "RealDisplay");}else{#if defined ISRPCauto status = SERVICES->client(DHSDK)->call("haat_CloseDisplay");#elsehaat_CloseDisplay();#endifpal.setColor(QPalette::Button, Qt::yellow);ui->realdisplay->setPalette(pal);ui->realdisplay->setText("RealDisplay");}}double MainWidget::getValue(QString value, int valueType){QString resultSFRStr = value;QStringList resultSFRList = resultSFRStr.split(";");QList<double> SFRList = {};for(QString temp : resultSFRList)if(!temp.isEmpty())SFRList.append(temp.toDouble());double result = -100;if(valueType == 0){double numTemp = 0;for(double doubleTemp : SFRList)numTemp = numTemp + doubleTemp;result = numTemp / SFRList.size();}elseresult = *std::min_element(SFRList.begin(), SFRList.end());return result;}void MainWidget::on_btn_browse_clicked(){QString srcDirPath = QFileDialog::getExistingDirectory(this, QSC("选择Rtsp截取图片储存路径"), "/");if (!srcDirPath.isEmpty())ui->imagePath->setText(srcDirPath + QString("/cap%1.bmp").arg(ui->sbx_num->value()));}void MainWidget::on_sbx_num_valueChanged(int arg1){QString imagePath = ui->imagePath->text();if(!imagePath.isEmpty()){QFileInfo appInfo(imagePath);QString newPath = appInfo.path() + QString("/cap%1.bmp").arg(arg1);ui->imagePath->setText(newPath); }}void MainWidget::on_cmb_ip_currentTextChanged(const QString &arg1){ui->ip->setText(arg1);}void MainWidget::on_cmb_channel_currentTextChanged(const QString &arg1){ui->channel->setText(arg1);}void MainWidget::on_tabWidget_currentChanged(int index){QString configName = ":/Config/RedisDataInit.json";QVariantMap redisData = HaatGlobalUtils::jsonfileToVariantMap(configName);}// ***************************大华SDK二次开发*********************************void MainWidget::h_capture(int channel){if (!g_bNetSDKInitFlag){g_bSnapPictureFlag = false;return;}if (!LoginHandle){g_bSnapPictureFlag = false;return;}// 设置抓图回调函数CLIENT_SetSnapRevCallBack(SnapRev, NULL);//事例中默认通道 ID 为 0、抓图模式为抓一幅图,用户可根据实际情况自行选择int nChannelId = channel;int nSnapType = 0;// 抓图模式;-1:表示停止抓图, 0:表示请求一帧, 1:表示定时发送请求, 2:表示连续请求// 发送抓图命令给前端设备SNAP_PARAMS stuSnapParams;stuSnapParams.Channel = nChannelId;stuSnapParams.mode = nSnapType;stuSnapParams.CmdSerial = 0;//++g_nCmdSerial; // 请求序列号,有效值范围 0~65535,超过范围会被截断为 unsigned shortg_bSnapPictureFlag = CLIENT_SnapPictureEx(LoginHandle, &stuSnapParams);QString logInfo = QSC("SDK抓图%1。").arg(g_bSnapPictureFlag? QSC("成功") : QSC("失败,错误码[%1]").arg(QString::number(CLIENT_GetLastError(), 16)));qDebug() << logInfo;}void MainWidget::h_connect(QString ip, int port, QString name, QString password){// 初始化 SDKg_bNetSDKInitFlag = CLIENT_Init((fDisConnect)DisConnectFunc, 0);QString logInfo = QSC("SDK初始化%1。").arg(g_bSnapPictureFlag ? QSC("成功") : QSC("失败"));qDebug() << logInfo;if (!g_bNetSDKInitFlag)return;// 设置断线重连回调接口,设置过断线重连成功回调函数后,当设备出现断线情况,SDK内部会自动进行重连操作// 此操作为可选操作,但建议用户进行设置CLIENT_SetAutoReconnect(&HaveReConnect, 0);// 设置登录超时时间和尝试次数// 此操作为可选操作int nWaitTime = 5000; // 登录请求响应超时时间设置为 5sint nTryTimes = 3; // 登录时尝试建立链接 3 次CLIENT_SetConnectTime(nWaitTime, nTryTimes);// 设置更多网络参数,NET_PARAM 的 nWaittime,nConnectTryNum 成员与CLIENT_SetConnectTime 接口设置的登录设备超时时间和尝试次数意义相同// 此操作为可选操作NET_PARAM stuNetParm = {0};stuNetParm.nConnectTime = 3000; // 登录时尝试建立链接的超时时间CLIENT_SetNetworkParam(&stuNetParm);NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY stInparam;memset(&stInparam, 0, sizeof(stInparam));stInparam.dwSize = sizeof(stInparam);//获取登录信息strcpy(D_Ip, ip.toLatin1().data());strcpy(D_UserName, name.toLatin1().data());strcpy(D_Pasdwd, password.toLatin1().data());D_Port = port;strncpy(stInparam.szIP, D_Ip, sizeof(stInparam.szIP) - 1);strncpy(stInparam.szUserName, D_UserName, sizeof(stInparam.szUserName) - 1);strncpy(stInparam.szPassword, D_Pasdwd, sizeof(stInparam.szPassword) - 1);stInparam.nPort = D_Port;stInparam.emSpecCap = EM_LOGIN_SPEC_CAP_TCP;// int loginCount = 0;// while(!LoginHandle && loginCount < 3){// 登录设备tagNET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY stOutparam;LoginHandle = CLIENT_LoginWithHighLevelSecurity(&stInparam, &stOutparam);QString logInfo = QSC("设备登录%1:%2 %3。").arg(ip).arg(D_Port).arg(LoginHandle? QSC("成功") : QSC("失败,错误码[%1]").arg(QString::number(CLIENT_GetLastError(), 16)));qDebug() << logInfo;// 用户初次登录设备,需要初始化一些数据才能正常实现业务功能,建议登录后等待一小段时间,具体等待时间因设备而异。QThread::msleep(100);}}void MainWidget::h_closeDisplay(){// 关闭预览if (lHandle){bool lHandleFlag = CLIENT_StopRealPlayEx(lHandle);QString logInfo = QSC("实时显示关闭%1。").arg(lHandleFlag ? QSC("成功") : QSC("失败,错误码[%1]").arg(QString::number(CLIENT_GetLastError(), 16)));qDebug() << logInfo;if(lHandleFlag)lHandle = false;}}void MainWidget::h_disconnect(){// 退出设备if (LoginHandle){bool LoginHandleFlag = CLIENT_Logout(LoginHandle);QString logInfo = QSC("实时显示关闭%1。").arg(LoginHandleFlag ? QSC("成功") : QSC("失败,错误码[%1]").arg(QString::number(CLIENT_GetLastError(), 16)));qDebug() << logInfo;if(LoginHandleFlag)LoginHandle = false;}// 清理初始化资源if (g_bNetSDKInitFlag){CLIENT_Cleanup();g_bNetSDKInitFlag = false;}}void MainWidget::h_realDisplay(int channel){if (!LoginHandle)return;// 实现实时监视功能业务// 获取控制台窗口句柄// 1.例程中的方法// HMODULE hKernel32 = GetModuleHandle("kernel32");// GetConsoleWindow = (PROCGETCONSOLEWINDOW)GetProcAddress(hKernel32,"GetConsoleWindow");// HWND hWnd = GetConsoleWindow();// NULL;// 2.获取qt控件的方法HWND hWnd = (HWND)ui->label_RealDisplay->winId();//开启实时监视int nChannelID = channel; // 预览通道号DH_RealPlayType emRealPlayType = DH_RType_Realplay; // 实时监视lHandle = CLIENT_RealPlayEx(LoginHandle, nChannelID, hWnd, emRealPlayType);QString logInfo = QSC("实时显示开启%1。").arg(lHandle ? QSC("成功") : QSC("失败,错误码[%1]").arg(QString::number(CLIENT_GetLastError(), 16)));qDebug() << logInfo;}//断线回调void CALLBACK MainWidget::DisConnectFunc(LLONG lLoginID, char *pchDVRIP, LONG nDVRPort, DWORD dwUser){qDebug() << QSC("断线回调\n");}//抓图回调void CALLBACK MainWidget::SnapRev(LLONG lLoginID, BYTE *pBuf, UINT RevLen, UINT EncodeType, DWORD CmdSerial, LDWORD dwUser){qDebug() << QSC("抓图回调\n");qDebug() << QSC("抓图句柄:") << lLoginID;// if(lLoginID == LoginHandle){if (NULL != pBuf && RevLen > 0){char szPicturePath[256] = "";// time_t stuTime;// time(&stuTime);// char szTmpTime[128] = "";// strftime(szTmpTime, sizeof(szTmpTime) - 1, "%y%m%d_%H%M%S", // gmtime(&stuTime));// _snprintf(szPicturePath, sizeof(szPicturePath)-1, "%d_%s.bmp", CmdSerial, szTmpTime);_snprintf(szPicturePath, sizeof(szPicturePath)-1, QString("D:\\%1.bmp").arg(lLoginID).toLatin1());qDebug() << QSC("图片地址:%1").arg(szPicturePath);FILE* pFile = fopen(szPicturePath, "wb");if (NULL == pFile)return;int nWrite = 0;while(nWrite != RevLen)nWrite += fwrite(pBuf + nWrite, 1, RevLen - nWrite, pFile);fclose(pFile);}}}//重连回调void CALLBACK MainWidget::HaveReConnect(LLONG lLoginID,char *pchDVRIP,LONG nDVRPort,LDWORD dwUser){qDebug() << QSC("重连回调\n");}QString MainWidget::loginWeb(QString ipAdress){QString url = QString("http://%1/RPC2_Login").arg(ipAdress);QVariantMap postDataMap = HaatGlobalUtils::jsonfileToVariantMap(QString(":/Config/loginPostData.json"));int sendID = postDataMap["id"].toInt();bool result = false;int count = 0;QString m_session;while(!result && count < 2){QString postDataStr = HaatGlobalUtils::getJsonStringFromMap(postDataMap);QByteArray postData = postDataStr.toLatin1();QByteArray responseData = m_http->postSync(url, postData);count ++;QVariantMap loginResponse = HaatGlobalUtils::getMapFromJsonString(QString(responseData));if(sendID == loginResponse["id"].toInt()){result = loginResponse["result"].toBool();m_session = loginResponse["session"].toString();postDataMap["session"] = m_session;if(count == 1){QString loginInfo = QSC("获取session%1").arg(m_session.isEmpty()? QSC("失败") : QSC("成功"));ui->textEdit->append(loginInfo);qDebug() << loginInfo;} else{QString loginInfo = QSC("登录%1").arg(result? QSC("成功") : QSC("失败"));ui->textEdit->append(loginInfo);qDebug() << loginInfo;}}else{ui->textEdit->append(QSC("错误:收发不对应!"));qDebug() << QSC("错误:收发不对应!");}}return result? m_session : "";}bool MainWidget::alterIP(QString sessionStr, QString ipAdress, QString alterIPAdress){QString url = QString("http://%1/RPC2").arg(ipAdress);QVariantMap postDataMap = HaatGlobalUtils::jsonfileToVariantMap(QString(":/Config/alterPostData.json"));postDataMap["session"] = sessionStr;QVariantList paramsList = postDataMap["params"].toList();for(QVariant paramsTemp : paramsList)if(paramsTemp.toMap().keys().contains("session"))paramsTemp.toMap()["session"] = sessionStr;QString postDataStr = HaatGlobalUtils::getJsonStringFromMap(postDataMap);postDataStr.replace(QString("%1").arg(ipAdress), QString("%1").arg(alterIPAdress));// ui->textEdit->append(postDataStr);// qDebug() << postDataStr;QByteArray postData = postDataStr.toLatin1();QByteArray responseData = m_http->postSync(url, postData);QVariantMap alterResponse = HaatGlobalUtils::getMapFromJsonString(QString(responseData));bool result = alterResponse["result"].toBool();ui->textEdit->append(QSC("ip:%1 -> %2 修改%3").arg(ipAdress).arg(alterIPAdress).arg(result? QSC("成功") : QSC("失败")));qDebug() << QSC("ip:%1 -> %2 修改%3").arg(ipAdress).arg(alterIPAdress).arg(result? QSC("成功") : QSC("失败"));return result; }