Onvif library encapsulation and qt project calls onvif library to realize functions such as device search and code stream address acquisition

I. Introduction:

    The OnvifManager project in this article is developed and compiled under vs2010. It realizes the encapsulation and calling of the onvif library. The current project interface realizes the search for onvif, the code stream address acquisition, and the device restart interface. Other interfaces can be changed later by changing the project code. to add. The qt project myonvif calls the dynamic library generated by OnvifManager, uses QTableview to display the searched device information, supports code stream address acquisition and device restart, and supports one-click webpage access.

2. OnvifManager dynamic library interface description

/*****************************************************

  • Device search interface 1
  • @pUser username input
  • @pPwd Password input
  • @pLocalIP local computer IP input
  • @vecDevInfo searched device information output
  • @search timeout input
  • @return value 0: success else: failure
  • ***************************************************/
    int FF_Onvif_Discovery1(char *pUser, char *pPwd, char *pLocalIP,
    std::vector<ONVIF_DEVICE_INFO_T>& vecDevInfo, int nTimeout);

/*****************************************************

  • Device search interface 2
  • @pUser username input
  • @pPwd Password input
  • @pLocalIP local computer IP input
  • @search timeout
  • @Return value: ONVFI_DISCOVERY_DEINFO_T structure device information
  • ***************************************************/
    ONVFI_DISCOVERY_DEINFO_T FF_Onvif_Discovery2(char *pUser, char *pPwd, char *pLocalIP, int nTimeout);

/*****************************************************

  • Get stream address
  • @pMediaXAddress Media service address
  • @pUser username input
  • @pPwd Password input
  • @pOutUrl code stream address output
  • @nOutUrlLen code stream address length input
  • @return value: 0: success else: failure
  • ***************************************************/
    int FF_Onvif_GetStreamUrl(char *pMediaXAddress, char *pUser, char *pPwd,
    char *pOutUrl, int nOutUrlLen);

/*****************************************************

  • Reboot the device
  • @pDeviceXAddress device service address
  • @pUser username input
  • @pPwd Password input
  • ***************************************************/
    int FF_Onvif_Reboot(char *pDeviceXAddress, char *pUser, char *pPwd);

Library header file: OnvifManager.h code

/**************************************************************************
Description:Onvif Lib
Author:ybLin
**************************************************************************/
#ifndef ONVIFMANAGER_H
#define ONVIFMANAGER_H

#include <windows.h>
#include <iostream>
#include <vector>
#include <list>
#include <string>

#ifdef __cplusplus
extern "C" {
#endif

#define MAX_DEV_LEN                     64

typedef struct onvif_device_info_t
{
    std::string sDevIP;
    std::string sMac;
    std::string sNetMask;
    std::string sGateWay;
    std::string sModel;
    std::string sVersion;
    std::string sManufacturer;

    std::string sDeviceXAddrs;
    std::string sMediaAddress;
    std::string Item;
    int nPort;

}ONVIF_DEVICE_INFO_T;

typedef struct onvif_devinfo_t
{
    int nPort;
    char sDevIP[64];
    char sMac[64];
    char sNetMask[64];
    char sGateWay[64];
    char sModel[64];
    char sVersion[64];
    char sManufacturer[64];
    char sDeviceXAddrs[128];
    char sMediaAddress[128];
    char Item[512];

}ONVIF_DEVINFO_T;

typedef struct onvif_disocvey_devinfo_t
{
    ONVIF_DEVINFO_T dev[MAX_DEV_LEN];
    int nDevNum;
    
}ONVFI_DISCOVERY_DEINFO_T;

//搜索接口1
extern  __declspec(dllexport) int WINAPI FF_Onvif_Discovery1(char *pUser, char *pPwd, char *pLocalIP,
                                                            std::vector<ONVIF_DEVICE_INFO_T>& vecDevInfo, int nTimeout);
//搜索接口2
extern  __declspec(dllexport) ONVFI_DISCOVERY_DEINFO_T WINAPI FF_Onvif_Discovery2(char *pUser, char *pPwd, char *pLocalIP, int nTimeout);

//获取码流地址
extern  __declspec(dllexport) int WINAPI FF_Onvif_GetStreamUrl(char *pMediaXAddress, char *pUser, char *pPwd,
                                                            char *pOutUrl, int nOutUrlLen);
//重启
extern  __declspec(dllexport) int WINAPI FF_Onvif_Reboot(char *pDeviceXAddress, char *pUser, char *pPwd);


#ifdef __cplusplus
}
#endif
#endif

3. qt-demo project myonvif

3.1 Operation Introduction

1) Click the search button and wait for the data to load

insert image description here

2) The data loading is complete (device information is not fully loaded because the password is incorrect)

insert image description here

3) Click the table data row to get the service address

insert image description here

4) Click the Get Stream Address button to get the rtsp stream address of the device:

insert image description here

5) Click Device Restart to restart the specified device:

insert image description here

6) web access

insert image description here

3.2 demo core code

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QStandardItemModel>
#include <QRunnable>

namespace Ui {
class MainWindow;
}

enum COLUMN_NUM
{
    DCOLUMN_IP = 0,
    DCOLUMN_MAC_ADDRESS,
    DCOLUMN_PORT,
    DCOLUMN_NETMASK,
    DCOLUMN_GATEWAY,
    DCOLUMN_MANUFACTURER,
    DCOLUMN_MODEL,
    DCOLUMN_SOFT_VERSION,
    DCOLUMN_WEB
};

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

    void initTableView();

signals:
    void sig_CloseWaitBox();

public slots:
    void on_fiterSingleClick(QModelIndex index); // 过滤单双击事件
    void on_tableViewClick(); //单击响应
    void slot_finshTask(bool bSuc);

private slots:
    void on_pushButton_Search_clicked();
    void on_pushButton_GetStreamUrl_clicked();
    void on_pushButton_Restart_clicked();

private:
    QStandardItemModel *m_tableModel;//表数据模型
    // 单双击区分
    bool m_bDBclick;
    QTimer *m_click; //单击的时候触发定时器
    QModelIndex m_bakIndex;

private:
    Ui::MainWindow *ui;
};

class COnvifDiscoveryTask :public QObject, public QRunnable
{
    Q_OBJECT
public:
    COnvifDiscoveryTask(QObject *parent, QString sUser, QString sPwd, QString sIP, QStandardItemModel *pTableModel): QObject(parent),
        m_sUser(sUser), m_sPwd(sPwd), m_sIP(sIP), m_tableModel(pTableModel) {}
    virtual ~COnvifDiscoveryTask() {}
    void run();

signals:
    void sig_finshTask(bool bSuc);

private:
    QString m_sUser;
    QString m_sPwd;
    QString m_sIP;
    QStandardItemModel *m_tableModel;
};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QLinkedList>
#include <QStringList>
#include "OnvifManager.h"
#include <QMessageBox>
#include <QDebug>
#include <string.h>
#include <QTimer>
#include <QThreadPool>
#include <QDesktopServices>
#include <QUrl>
#include "CtWaitBox.h"

using namespace std;

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    initTableView();

    connect(this, &MainWindow::sig_CloseWaitBox,
            CtWaitBox::getInstance(), &CtWaitBox::onWaitBoxClose);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::initTableView()
{
    m_tableModel = new QStandardItemModel(this);
    ui->tableView->setModel(m_tableModel);

    QStringList lables;
    lables << QObject::tr("IP") << QObject::tr("Mac")
           << QObject::tr("Port") << QObject::tr("NetMask")
           << QObject::tr("Gateway") << QObject::tr("Manufacturer")
           << QObject::tr("Model") << QObject::tr("Version") << QObject::tr("Web");
    m_tableModel->setHorizontalHeaderLabels(lables);
    //ui->tableView->horizontalHeader()->setSectionResizeMode(DCOLUMN_WEB, QHeaderView::Fixed);

    int width = 840;
    ui->tableView->setColumnWidth(DCOLUMN_IP, qRound(0.13*width));
    ui->tableView->setColumnWidth(DCOLUMN_MAC_ADDRESS, qRound(0.13*width));
    ui->tableView->setColumnWidth(DCOLUMN_PORT, qRound(0.05*width));
    ui->tableView->setColumnWidth(DCOLUMN_NETMASK, qRound(0.13*width));
    ui->tableView->setColumnWidth(DCOLUMN_GATEWAY, qRound(0.13*width));
    ui->tableView->setColumnWidth(DCOLUMN_MANUFACTURER, qRound(0.12*width));
    ui->tableView->setColumnWidth(DCOLUMN_MODEL, qRound(0.12*width));
    ui->tableView->setColumnWidth(DCOLUMN_SOFT_VERSION, qRound(0.12*width));
    ui->tableView->setColumnWidth(DCOLUMN_WEB, qRound(0.05*width));

    m_click = new QTimer(this);
    m_click->setSingleShot(true);
    m_bDBclick = false;
    connect(ui->tableView, &QTableView::clicked,
            this, &MainWindow::on_fiterSingleClick); //单击检测
    connect(m_click, &QTimer::timeout,
            this, &MainWindow::on_tableViewClick); // 处理单击

}

void MainWindow::on_fiterSingleClick(QModelIndex index)
{
    if(m_bDBclick)
    {
        m_bDBclick = false;
    }
    else
    {
        m_click->start(200); // double click interval 200ms
        m_bakIndex = index;
    }
}

void MainWindow::on_tableViewClick()
{
    int nRow = m_bakIndex.row();//选中数据的行
    int nCol = m_bakIndex.column();//选中数据的列

    QString sIP = m_tableModel->item(nRow, DCOLUMN_IP)->text();
    QString sPort = m_tableModel->item(nRow, DCOLUMN_PORT)->text();
    QString sMediaAddr = QString("http://%1:%2/onvif/Media").arg(sIP).arg(sPort);
    QString sDevAddr = QString("http://%1:%2/onvif/device_service").arg(sIP).arg(sPort);

    ui->lineEdit_MediaAddress->setText(sMediaAddr);
    ui->lineEdit_devAddress->setText(sDevAddr);

    if(nCol == DCOLUMN_WEB)
    {
        QString sUrl = QString("http://%1:%2").arg(sIP).arg(sPort);
        QDesktopServices::openUrl(QUrl(sUrl));
    }
}

void MainWindow::slot_finshTask(bool bSuc)
{
    Q_UNUSED(bSuc)
    emit sig_CloseWaitBox();
}

void MainWindow::on_pushButton_Search_clicked()
{
    QString sUserName = ui->lineEdit_User->text();
    if(sUserName.isEmpty())
    {
        QMessageBox::critical(this, "myOnvif", "错误:用户名不能为空.");
        return;
    }

    QString sPwd = ui->lineEdit_Pwd->text();
    if(sPwd.isEmpty())
    {
        QMessageBox::critical(this, "myOnvif", "错误:密码不能为空.");
        return;
    }

    QString sIP = ui->lineEdit_IP->text();
    if(sIP.isEmpty())
    {
        QMessageBox::critical(this, "myOnvif", "错误:本机IP不能为空.");
        return;
    }

    COnvifDiscoveryTask* pTask = new COnvifDiscoveryTask(NULL, sUserName, sPwd, sIP, m_tableModel);
    connect(pTask, SIGNAL(sig_finshTask(bool)),
            this, SLOT(slot_finshTask(bool)));
    QThreadPool::globalInstance()->start(pTask);

    CtWaitBox::loading(true, geometry().x()+geometry().width()/2-100, geometry().y()+geometry().height()/2-100, 60, true);
}

void MainWindow::on_pushButton_GetStreamUrl_clicked()
{
    char sUrl[128] = {0};
    QString sMediaAddr = ui->lineEdit_MediaAddress->text();
    if(sMediaAddr.isEmpty())
    {
        QMessageBox::critical(this, "myOnvif", tr("媒体服务地址不能为空"));
        return;
    }

    QString sUser = ui->lineEdit_User->text();
    if(sUser.isEmpty())
    {
        QMessageBox::critical(this, "myOnvif", tr("用户名不能为空"));
        return;
    }

    QString sPwd = ui->lineEdit_Pwd->text();
    if(sPwd.isEmpty())
    {
        QMessageBox::critical(this, "myOnvif", "密码不能为空");
        return;
    }

    if(FF_Onvif_GetStreamUrl(sMediaAddr.toLatin1().data(), sUser.toLatin1().data(), sPwd.toLatin1().data(), sUrl, sizeof(sUrl)) != 0)
    {
        QMessageBox::critical(this, "myOnvif", "错误:获取码流地址失败.");
    }
    else
    {
        QString sRtspUrl = QString(sUrl);
        ui->lineEdit_Url->setText(sRtspUrl);
    }
}

void MainWindow::on_pushButton_Restart_clicked()
{
    QString sDevAddr = ui->lineEdit_devAddress->text();
    if(sDevAddr.isEmpty())
    {
        QMessageBox::critical(this, "myOnvif", "设备服务地址不能为空");
        return;
    }

    QString sUser = ui->lineEdit_User->text();
    if(sUser.isEmpty())
    {
        QMessageBox::critical(this, "myOnvif", "用户名不能为空");
        return;
    }

    QString sPwd = ui->lineEdit_Pwd->text();
    if(sPwd.isEmpty())
    {
        QMessageBox::critical(this, "myOnvif", "密码不能为空");
        return;
    }

    if(FF_Onvif_Reboot(sDevAddr.toLatin1().data(), sUser.toLatin1().data(), sPwd.toLatin1().data()) == 0)
        QMessageBox::information(this, "myOnvif", "重启成功");
    else
        QMessageBox::critical(this, "myOnvif", "重启失败.");
}

void COnvifDiscoveryTask::run()
{
    if(m_tableModel->rowCount() > 0)
    {
        m_tableModel->removeRows(0, m_tableModel->rowCount());
    }

    ONVFI_DISCOVERY_DEINFO_T devInfos = FF_Onvif_Discovery2(m_sUser.toLatin1().data(), m_sPwd.toLatin1().data(), m_sIP.toLatin1().data(), 5);

    qDebug() << "devInfos.nDevNum:" << devInfos.nDevNum;
    //数据
    for(int i = 0; i < devInfos.nDevNum; i++)
    {
        qDebug() << "Dev" << i << " IP:" << devInfos.dev[i].sDevIP;
        qDebug() << "Dev" << i << " Port:" << devInfos.dev[i].nPort;
        qDebug() << "Dev" << i << " Mac:" << devInfos.dev[i].sMac;
        qDebug() << "Dev" << i << " NetMask:" << devInfos.dev[i].sNetMask;
        qDebug() << "Dev" << i << " GateWay:" << devInfos.dev[i].sGateWay;
        qDebug() << "Dev" << i << " Manufacturer:" << devInfos.dev[i].sManufacturer;
        qDebug() << "Dev" << i << " Model:" << devInfos.dev[i].sModel;
        qDebug() << "Dev" << i << " Version:" << devInfos.dev[i].sVersion;
        qDebug() << "\r\n"<< endl;

        m_tableModel->insertRow(i, QModelIndex());
        m_tableModel->setData(m_tableModel->index(i, DCOLUMN_IP), devInfos.dev[i].sDevIP);
        m_tableModel->setData(m_tableModel->index(i, DCOLUMN_MAC_ADDRESS), devInfos.dev[i].sMac);
        m_tableModel->setData(m_tableModel->index(i, DCOLUMN_PORT), devInfos.dev[i].nPort);
        m_tableModel->setData(m_tableModel->index(i, DCOLUMN_NETMASK), devInfos.dev[i].sNetMask);
        m_tableModel->setData(m_tableModel->index(i, DCOLUMN_GATEWAY), devInfos.dev[i].sGateWay);
        m_tableModel->setData(m_tableModel->index(i, DCOLUMN_MANUFACTURER), devInfos.dev[i].sManufacturer);
        m_tableModel->setData(m_tableModel->index(i, DCOLUMN_MODEL), devInfos.dev[i].sModel);
        m_tableModel->setData(m_tableModel->index(i, DCOLUMN_SOFT_VERSION), devInfos.dev[i].sVersion);
        m_tableModel->setData(m_tableModel->index(i, DCOLUMN_WEB), QImage(":/image/web.png"), Qt::DecorationRole);

        // 设置全部列居中显示
        for(int j = DCOLUMN_IP; j < DCOLUMN_WEB; j++)
        {
            m_tableModel->item(i, j)->setTextAlignment(Qt::AlignCenter);
        }
    }

    emit sig_finshTask(true);
}

4. Download

Experience address download: https://download.csdn.net/download/linyibin_123/88036919
onvif library source code and qt-demo project source code download: https://download.csdn.net/download/linyibin_123/88036934

Guess you like

Origin blog.csdn.net/linyibin_123/article/details/131664369