Qt编写Onvif搜索及云台控制工具
一、前言
这个工具很早以前大概在2013年就想做了,后面杂七杂八的事情一再耽搁,记得当时最初用的是soap类来搜索和解析的,后面发现太大了,每次编译都要等好久,光源码文件加起来都快10MB了,而且函数名非常另类,大量的下划线等,反正本人非常不适应,近期经过一个朋友(QQ:408815041)的前期探索,对整个处理流程熟悉以后,发现其实用纯Qt也可以实现,核心就是udp搜索+post数据。
本程序框架的最大难点在找出对应的数据以及节点数据解析。找出对应的数据可以直接使用官方的ONVIF Device Test Tool,抓包即可。数据解析一开始采用xml的节点解析,发现根本行不通,因为返回的数据不是标准的xml数据,而是soap格式的数据,需要用QXmlQuery来解析。本程序只实现了设备信息的搜索和云台控制,并未实现服务端,服务端一般是IPC或者NVR上来实现。
体验地址:https://pan.baidu.com/s/1bbL2ZughZAgfIGrexyN-9g 提取码:zkeh,下面的bin_onviftool.zip,如果是XP系统,请先执行目录下的fixff.cmd。
二、Onvif介绍
ONVIF致力于通过全球性的开放接口标准来推进网络视频在安防市场的应用,这一接口标准将确保不同厂商生产的网络视频产品具有互通性。2008年11月,正式发布了ONVIF第一版规范——ONVIF核心规范1.0。随着视频监控的网络化应用,产业链的分工将越来越细。有些厂商专门做摄像头,有些厂商专门做DVS,有些厂商则可能专门做平台等,然后通过集成商进行集成,提供给最终客户。这种产业合作模式,已经迫切的需要行业提供越来越标准化的接口平台。
ONVIF规范描述了网络视频的模型、接口、数据类型以及数据交互的模式。并复用了一些现有的标准,如WS系列标准等。ONVIF规范的目标是实现一个网络视频框架协议,使不同厂商所生产的网络视频产品(包括摄录前端、录像设备等)完全互通。
ONVIF规范中设备管理和控制部分所定义的接口均以Web Services的形式提供,设备作为服务提供者为服务端。ONVIF规范涵盖了完全的XML及WSDL的定义。每一个支持ONVIF规范的终端设备均须提供与功能相应的Web Service。服务端与客户端的数据交互采用SOAP协议。ONVIF中的其他部分比如音视频流则通过RTP/RTSP进行。
三、处理流程
- 绑定组播IP(239.255.255.250)和端口(3702),发送固定的xml格式的数据搜索设备。
- 接收到的xml格式的数据解析,得到设备的Onvif地址。
- 对Onvif地址发送对应的数据,收到数据取出对应的节点数据。
- 请求Onvif地址获取Media地址和Ptz地址,Media地址用来获取详细的配置文件,Ptz地址用来云台控制。
- ptz控制是对Ptz地址发送对应的数据即可。
- 设置了用户认证的需要组织用户token信息一块发送,每次都需要作鉴权处理。
- 接收到的数据不是标准的xml数据,没法按照正常的节点解析来处理,只能用QXmlQuery来做。
- 每个厂家设备返回的数据未必完全一致,基本上都不一致,需要进行模糊查找节点值。
- 特意采用底层协议解析,因为soap太臃肿函数名称太另类,特意做的轻量级的。
- 两个必备工具,Onvif Device Manager 和 Onvif Device Test Tool。
四、功能特点
- 广播搜索设备,支持IPC和NVR,依次返回,可选择不同的网卡IP。
- 依次获取Onvif地址、Media地址、Profile文件、Rtsp地址。
- 可对指定的Profile获取视频流Rtsp地址,比如主码流子码流地址。
- 可对每个设备设置Onvif用户信息,用于认证获取详细信息。
- 可实时预览摄像机图像。
- 支持云台控制,可上下左右调节云台,支持绝对移动和相对移动,可放到和缩小图像远近。
- 支持Qt4和Qt5任意Qt版本,亲测Qt4.7.0到Qt5.12.4。
- 支持任意编译器,亲测mingw、msvc、gcc、clang。
- 支持任意操作系统,亲测xp、win7、win10、linux、嵌入式linux、树莓派全志H3等。
- 支持任意Onvif摄像机和NVR,亲测海康、大华、宇视、华为、海思芯片内核等,可定制开发。
- 支持对指定IP地址进行单播搜索,比如跨网段情况下非常有用。
- 纯Qt编写,超级小巧轻量,总共约2000行代码,不依赖任何第三方的库和组件,跨平台。
- 封装好了通用的数据发送和接收解析的函数,可以非常方便的自行拓展其他Onvif处理比如修改IP等。
- 工具上提供了收发数据文本框,显示收发的数据,方便查看和分析。
- 支持所有Onvif设备,代码工整,接口友好,直接引入pri即可使用。
五、效果图
六、核心代码
#include "qonvifsearch.h"
#include "qonviffunction.h"
#include "qonvifquery.h"//onvif协议固定的IP和端口
#define OnvifAddr QHostAddress("239.255.255.250")
#define OnvifPort 3702QOnvifSearch::QOnvifSearch(QObject *parent) : QObject(parent)
{isOk = false;//定时器排队发送搜索命令,有好几种timer = new QTimer(this);connect(timer, SIGNAL(timeout()), this, SLOT(sendData()));timer->setInterval(300);udpSocket = new QUdpSocket(this);
#if (QT_VERSION >= QT_VERSION_CHECK(4,8,5))udpSocket->setSocketOption(QAbstractSocket::MulticastLoopbackOption, 1);
#endifconnect(udpSocket, SIGNAL(readyRead()), this, SLOT(readData()));
}QOnvifSearch::~QOnvifSearch()
{if (timer->isActive()) {timer->stop();}
}void QOnvifSearch::sendData()
{QByteArray data = QOnvifFunction::getFile(currentFile);if(!data.isEmpty()) {data = QString(data).arg(QOnvifFunction::getUuid()).toUtf8();udpSocket->writeDatagram(data, OnvifAddr, OnvifPort);emit sendData(data);}//依次发送数据,如果到了最后一个则停止//根据onvif device test工具抓包分析,只要发送前面两个就行,后面两个是ONVIF Device Manager抓包的//在收到结果的地方要对重复的进行过滤,因为部分设备两种协议请求都会返回if (currentFile == ":/send/search1.xml") {currentFile = ":/send/search2.xml";} else if (currentFile == ":/send/search2.xml") {currentFile = ":/send/search3.xml";} else if (currentFile == ":/send/search3.xml") {currentFile = ":/send/search4.xml";} else if (currentFile == ":/send/search4.xml") {timer->stop();}
}void QOnvifSearch::readData()
{QByteArray data;QHostAddress host;quint16 port = 0;while (udpSocket->hasPendingDatagrams()) {data.resize(udpSocket->pendingDatagramSize());udpSocket->readDatagram(data.data(), data.size(), &host, &port);emit receiveData(data);}QOnvifQuery query;query.setData(data);QString addr_path = QString("//%1:ProbeMatches/%1:ProbeMatch/%1:XAddrs").arg(query.getDiscovery());QString scopes_path = QString("//%1:ProbeMatches/%1:ProbeMatch/%1:Scopes").arg(query.getDiscovery());QString addr = query.getValue(addr_path);QString scopes = query.getValue(scopes_path);if(!addr.isEmpty()) {//过滤下IPV6地址 http://192.168.1.64/onvif/device_service http://[fe80::9a8b:aff:fe6e:867c]/onvif/device_serviceQStringList list = addr.split(" ");addr = list.first();//过滤掉重复的设备,发送搜索设备的命令有好几种,某些设备支持多种命令,所以会返回多次foreach (DeviceInfo deviceInfo, deviceInfos) {if (deviceInfo.addr == addr) {return;}}//定义结构体存储设备信息DeviceInfo deviceInfo;deviceInfo.addr = addr;deviceInfo.ip = QOnvifFunction::getIP(addr);//取出其他信息 onvif://www.onvif.org/type/NetworkVideoTransmitter onvif://www.onvif.org/name/NVR onvif://www.onvif.org/hardware/hisi onvif://www.onvif.org/location/shanghai//这里的信息是通过广播搜索返回的无需密码,这里还可以根据打印出来的 scopes 自行增加设备信息list = scopes.split(" ");foreach (QString str, list) {QStringList l = str.split("/");if (l.contains("name")) {deviceInfo.name = l.last();} else if (l.contains("location")) {deviceInfo.location = l.last();} else if (l.contains("hardware")) {deviceInfo.hardware = l.last();}}deviceInfos << deviceInfo;emit receiveDevice(deviceInfo);emit receiveInfo(QString("发现新设备-> %1").arg(addr));}
}bool QOnvifSearch::search(const QString &ip)
{deviceInfos.clear();if (!QOnvifFunction::isIP(ip)) {return false;}//如果还未成功则先绑定if (!isOk) {isOk = udpSocket->bind(QHostAddress(ip), 0, QUdpSocket::ShareAddress);//udpSocket->joinMulticastGroup(OnvifAddr);}if (isOk) {//之前是直接全部放在这里发送,发现部分设备要好几次才能回来//改成定时器排队发送多种广播搜索数据,就没有问题currentFile = ":/send/search1.xml";timer->stop();timer->start();} else {emit receiveError(QString("绑定组播失败-> %1").arg(udpSocket->errorString()));}return isOk;
}QList<QOnvifSearch::DeviceInfo> QOnvifSearch::getDeviceInfos()
{return this->deviceInfos;
}QStringList QOnvifSearch::getAddrs()
{QStringList addrs;foreach (DeviceInfo deviceInfo, deviceInfos) {addrs << deviceInfo.addr;}return addrs;
}
Qt编写Onvif搜索及云台控制工具相关推荐
- onvif协议之云台控制
onvif云台控制,还有有点麻烦的,主要是不知道参数如何填写,通过接近一天的摸索,终于有点名目了. 我使用的是ContinuousMove这个api,介绍如下,网址https://www.onvif. ...
- QT编写简易的SSL证书注册工具
前言:基于内网环境中搭建的SSL证书,想要让浏览器识别并信任它,有一步非常重要的操作就是需要用户手动将证书导入到自己的'受信任根目录'里面去.但是如果处于一个非常庞大的内网环境中,访问我们网站用户是一 ...
- 视频流媒体服务器ONVIF探测和云台控制是如何设置的?
我们知道流媒体服务器是可以支持Onvif协议的,只是需要摄像头具有onvif协议,并且在流媒体服务器后台进行探测. 我们有一位开发者准备了具有onvif协议摄像头球机,但是启动EasyNVR之后,并不 ...
- Qt编写项目作品大全(自定义控件+输入法+大屏电子看板+视频监控+楼宇对讲+气体安全等)...
一.自定义控件大全 (一).控件介绍 超过150个精美控件,涵盖了各种仪表盘.进度条.进度球.指南针.曲线图.标尺.温度计.导航条.导航栏,flatui.高亮按钮.滑动选择器.农历等.远超qwt集成的 ...
- Qt编写安防视频监控系统33-onvif云台控制
一.前言 云台控制也是onvif功能中最常用的,最常用的功能排第一的是拿到视频流地址,排第二的就是云台控制了,云台控制的含义就是对带云台的摄像机进行上下左右的移动,一般云台摄像机都是带有一个小电机,一 ...
- Qt编写安防视频监控系统18-云台控制
一.前言 云台控制是视频监控系统中必备的一个功能,对球机进行上下左右的移动,还有焦距的控制,其实核心就是控制XYZ三个坐标轴,为了开发这个模块,特意研究了各种云台控制的方法和开源库比如soap,有些厂 ...
- Qt编写安防视频监控系统22-摄像机搜索
一.前言 摄像机搜索模块是后面新增加的,这个模块很有必要,一开始做视频监控系统的时候,那时候还没有研究出来一套纯Qt底层通信的onvif类,也就前几个月搞出来了,支持搜索设备信息和云台控制,所以马上加 ...
- SkeyeVSS国标视频汇聚云服务使用Onvif、GB28181协议对监控摄像机设备进行PTZ云台控制
SkeyeVSS平台可在复杂的网络环境中,将分散的各类视频资源进行统一汇聚.整合.集中管理,实现视频资源的鉴权管理.按需调阅.全网分发.智能分析等.平台可支持多协议.多类型设备接入,包括国标GB281 ...
- Qt编写安防视频监控系统(支持win/linux/mac/海康/大华/宇视/264/265等)
一.前言 视频监控系统在整个安防领域,已经做到了烂大街的程序,全国起码几百家公司做过类似的系统,当然这一方面的需求量也是非常旺盛的,各种定制化的需求越来越多,尤其是这几年借着人脸识别的东风,发展更加迅 ...
- Qt编写视频监控管理平台(支持海康/大华/宇视/华为/天地伟业/H264/H265等)
一.前言 海康大华等厂家自己的客户端软件,基本上都是支持自家的设备,不支持其他家的摄像机和硬盘录像机,并不是因为技术上做不到,这些大厂要实现支持兼容其他的家的(他们家的服务端或者收费的都是支持其他家的 ...
最新文章
- python入门之前面内容拾遗
- 学计算机的管理医生,计算机科学与技术系医学生管理工作体会.pdf
- ext.net 开发学习之复杂模板板块 (叁)
- 人脸离线识别模块_人脸识别模块做到市场份额60%,这家AI公司如何用狼性在安防杀开一条血道?...
- DotNet控件缩写
- Python3 不能直接导入reduce
- activemq linux 100M,Linux下安装 activemq 并指定jdk 1.8(示例代码)
- 【5G NR】ZP CSI-RS资源配置
- 手把手教你二维数组打印
- [源码解析] TensorFlow 分布式环境(6) --- Master 动态逻辑
- linux中的通配符指的是?
- css 选父元素,CSS子元素选择父元素的实现
- intel(R)wireless-ac 9462感叹号,WLAN消失,电脑连不上网解决办法
- WOS搜索输出文件的格式整理
- 从现在开始学 Kafka:SpringBoot 集成 Kafka,生产者与消费者示例
- Undefined symbols for architecture i386: _OBJC_CLASS_$_JPUSHService
- 弦振动 matlab,弦振动规律和MATLAB数据处理.doc
- mysql 安装插件 validate_password
- 外贸网站最好用的5大WordPress插件【必须安装】
- servlet+jsp数据库增删改查实例