Qt 调用海康威视的SDK进行视频预览及云台控制

特别说明:个人笔记,不惜勿喷。

  Qt获取海康摄像头图像方法很多,比如可以只用RTSP的方式直接拉流获取。但是RTSP拉流的方式我也尝试过,需要用到FFMPEG,由于这个库东西比较多,而且里面很多流程需要自己去做解析,程序员本就是图方便和高效,与其去折腾,还不如直接用官方提供的SDK。这样省很多事情。

 海康SDK开发心得:在预览图像的时候图像时延是非常低的,相比ffmpeg的rtsp要低很多,因此如果项目对于时延要去高的地方可以考虑用sdk来试试。

  于是乎,自己研究了下,发现比较简单,此处仅作笔记,无技术含量。

1、首先工程文件添加海康SDK的库和头文件

LIBS += -L$$PWD/hiklib/lib/ -lHCNetSDK
INCLUDEPATH += $$PWD/hiklib/include
DEPENDPATH += $$PWD/hiklib/include

2、登录摄像头

    NET_DVR_Init();
    NET_DVR_SetConnectTime(2000, 1);
    NET_DVR_SetReconnect(10000, true);

    NET_DVR_USER_LOGIN_INFO struLoginInfo;
    NET_DVR_DEVICEINFO_V40 struDeviceInfoV40;
    memset(&struLoginInfo, 0x00, sizeof(NET_DVR_USER_LOGIN_INFO));
    memset(&struDeviceInfoV40, 0x00, sizeof(NET_DVR_DEVICEINFO_V40));

    struLoginInfo.bUseAsynLogin = 0;                            // 同步登录方式
    strcpy(struLoginInfo.sDeviceAddress, "192.168.0.143");      // 设备IP地址
    struLoginInfo.wPort = 8000 ;                                // 设备服务端口
    strcpy_s(struLoginInfo.sUserName, "admin");                 // 设备登录用户名
    strcpy_s(struLoginInfo.sPassword, "123456");                // 设备登录密码

    m_userId = NET_DVR_Login_V40(&struLoginInfo, &struDeviceInfoV40);
    if (m_userId < 0)
    {
        qDebug() << "登录失败" << m_userId << NET_DVR_GetErrorMsg();
    }

3、登录成功后就可以直接启动图像预览了。

    NET_DVR_PREVIEWINFO struPreviewInfo;
    memset(&struPreviewInfo, 0x00, sizeof(NET_DVR_PREVIEWINFO));
    struPreviewInfo.lChannel = 1;               // 通道id
    struPreviewInfo.hPlayWnd = (HWND)ui->labelPreview->winId();
    struPreviewInfo.dwStreamType = 0;           // 码流类型: 0-主码流
    struPreviewInfo.dwLinkMode = 0;             // 链接方式: 0- TCP方式
    struPreviewInfo.bBlocked = 0;               // 0 - 非阻塞取流,1 - 阻塞取流

    m_previewHandle = NET_DVR_RealPlay_V40(m_userId, &struPreviewInfo, NULL, NULL);

4、云台控制 

#define START   0
#define STOP    1
    NET_DVR_PTZControl(m_previewHandle, TILT_UP, START);
    NET_DVR_PTZControl(m_previewHandle, TILT_UP, STOP);
    /* 下 */
    NET_DVR_PTZControl(m_previewHandle, TILT_DOWN, START);
    NET_DVR_PTZControl(m_previewHandle, TILT_DOWN, STOP);
    /* 其他方向可以自行查看头文件,方法一样 */

5、辅助功能:网络摄像头局域网扫描通信协议,方便在不知道摄像头ip的情况下进行

通过UDP报文广播的方式扫描在线摄像头

    QString strData = QString("");
    m_strUuid = QUuid::createUuid().toString(QUuid::WithoutBraces).toUpper();
    strData += m_strUuid;
    strData += "inquiry";

    qint64 len = m_udpSocket->writeDatagram(strData.toLatin1(), QHostAddress("239.255.255.250"), 37020);
    qDebug() << "==>" << len << strData;

协议解析:

void ScanIPCameras::sltUdpSocketRead()
{
    QByteArray byData;
    //    qDebug() << "udp recv" << m_udpSocket->pendingDatagramSize();
    while (m_udpSocket->hasPendingDatagrams()) {
#if (QT_VERSION > QT_VERSION_CHECK(5, 8, 0))
        QNetworkDatagram datagram = m_udpSocket->receiveDatagram();
        QHostAddress host = datagram.senderAddress();
        byData += datagram.data();
#else
        QByteArray datagram;
        datagram.resize(m_udpSocket->pendingDatagramSize());
        m_udpSocket->readDatagram(datagram.data(), datagram.size());
        byData += datagram;
#endif
    }
    parseXmlData(byData);
}

解析如下:

void ScanIPCameras::parseXmlData(const QByteArray &_byContent)
{
    QDomDocument document;
    QString error;
    int row = 0, column = 0;
    if (!document.setContent(_byContent, false, &error, &row, &column))
    {
        return;
    }

    if (document.isNull())
    {
        return;
    }

    QDomElement root = document.documentElement();
    for(QDomNode node = root.firstChild(); !node.isNull(); node = node.nextSibling())
    {
        QDomElement e = node.toElement();
        QString tag = node.nodeName();
        QString value = e.text();
        if ("Uuid" == tag) {
            qDebug() << "value" << value;
            qDebug() << "Uuid " << m_strUuid;
            m_strUuid = value;
        }
        else if ("DeviceDescription" == tag) {

        }
        else if ("IPv4Address" == tag) {
            emit signalCamera(value);
            emit signalNotify(QString("摄像头扫描: 扫描完成,发现设备[%1]!~").arg(value));
        }
        else if ("CommandPort" == tag) {

        }
        else if ("HttpPort" == tag) {

        }
        else if ("DHCP" == tag) {

        }
        else if ("DeviceSN" == tag) {

        }
        else {
            qDebug() << tag << value;
        }
    }
}

效果图:

Qt 调用海康威视的SDK进行视频预览及云台控制_第1张图片

 

你可能感兴趣的:(Qt,Qt,海康SDK,qt)