Onvif 协议操作网络摄像头

在前面的话
因为主要工作在arm环境下,平时对网络摄像头使用的场景也比较多,就想着基于onvif(onvif估计大家都了解差不多吧)协议做一些开发,适配多个品牌的设备。网上都使用gsoap实现的,因为gsoap体量太大,编译比较费劲,我是基于大佬的思路实现的,大家可以参考下
https://qtchina.blog.csdn.net/category_9290431.html

主要功能包括:

  1. 设备搜索
  2. 获取视频码流
  3. 云台控制
  4. 预置位
  5. 获取设备信息
  6. 时间配置
  7. 网络配置
  8. 显示设置(亮度、对比度等)
  9. OSD

工具
Onvif Device Manager 和 Onvif Device Test Tool

基本思路

  1. 设备搜索
    首先要了解组播(详细了解到网上查),简单理解就是当你的软件加入到摄像头的组播中后,在向该组播发送数据,在同一个组播里的摄像头都能收到数据,并会将信息返回,类似于我们将部分人拉入腾讯会议,在会议内的人都能收到你发的消息,所以我们首先要加入onvif的组播,onvif的组播地址也是固定的:IP:239.255.255.250 端口:3702

  2. 设备控制
    onvif协议的使用简单理解就是将摄像头当做服务器,我们自己写的做客户端,通过http将XML发送给摄像头,摄像头收到会返回XML,比如你要获取现在设备头的亮度,你就将亮度相关的xml发送过去,摄像头就会返回一个xml,你在根据规则解析到亮度值,如果要设置也是一样,将预设置的值写到xml中,发送给设备,格式没有问题的话,就会成功,但在通信中会用到会遇到鉴权问题,其实就是要把用户名和密码填到xml中发过去,不然设备就会返回鉴权失败。
    以上就是主要思路,下来就是要知道xml从哪里来,里面的标签分别表示什么,如何鉴权的问题了。

3.工具使用
要进行后面的工作就要了解下Onvif Device Test Tool 工具的使用,包括设备搜索、设备控制等功能肯定都是有的,网上都是查,我说几个点帮助下理解。
a)工具中,选择Debug->Requests 再选择对应的模块,发送请求(点击Send Request),就能在Request 窗口和Response窗口看到我们上面说的,发送给摄像头的xml和摄像头返回的xml。
b)每个功能有对应的模块服务地址,你在请求前需要填写正确的Service和Service Address,这个地址从哪里来呢?首先我们会在Discovery界面选择要操作的ip设备后,就能在Device Service Address 获取到服务地址(http://192.168.1.10:8899/onvif/device_service),转到Debug界面,选择“Device Management” 并输入 “http://192.168.1.10:8899/onvif/device_service”地址,再选择“GetCapabilities”,进行请求,就能获得所有模块的服务地址了。
地址有很多种,你可以解析Response。

Line <span class="token number">7</span><span class="token operator">:</span> <span class="token operator"><</span>tt<span class="token operator">:</span>XAddr<span class="token operator">></span>http<span class="token operator">:</span> Line <span class="token number">12</span><span class="token operator">:</span> <span class="token operator"><</span>tt<span class="token operator">:</span>XAddr<span class="token operator">></span>http<span class="token operator">:</span> Line <span class="token number">59</span><span class="token operator">:</span> <span class="token operator"><</span>tt<span class="token operator">:</span>XAddr<span class="token operator">></span>http<span class="token operator">:</span> Line <span class="token number">65</span><span class="token operator">:</span> <span class="token operator"><</span>tt<span class="token operator">:</span>XAddr<span class="token operator">></span>http<span class="token operator">:</span> Line <span class="token number">68</span><span class="token operator">:</span> <span class="token operator"><</span>tt<span class="token operator">:</span>XAddr<span class="token operator">></span>http<span class="token operator">:</span> Line <span class="token number">81</span><span class="token operator">:</span> <span class="token operator"><</span>tt<span class="token operator">:</span>XAddr<span class="token operator">></span>http<span class="token operator">:</span> Line <span class="token number">85</span><span class="token operator">:</span> <span class="token operator"><</span>tt<span class="token operator">:</span>XAddr<span class="token operator">></span>http<span class="token operator">:</span>
 Line <span class="token number">7</span><span class="token operator">:</span> <span class="token operator"><</span>tt<span class="token operator">:</span>XAddr<span class="token operator">></span>http<span class="token operator">:</span> Line <span class="token number">12</span><span class="token operator">:</span> <span class="token operator"><</span>tt<span class="token operator">:</span>XAddr<span class="token operator">></span>http<span class="token operator">:</span> Line <span class="token number">59</span><span class="token operator">:</span> <span class="token operator"><</span>tt<span class="token operator">:</span>XAddr<span class="token operator">></span>http<span class="token operator">:</span> Line <span class="token number">65</span><span class="token operator">:</span> <span class="token operator"><</span>tt<span class="token operator">:</span>XAddr<span class="token operator">></span>http<span class="token operator">:</span> Line <span class="token number">68</span><span class="token operator">:</span> <span class="token operator"><</span>tt<span class="token operator">:</span>XAddr<span class="token operator">></span>http<span class="token operator">:</span> Line <span class="token number">81</span><span class="token operator">:</span> <span class="token operator"><</span>tt<span class="token operator">:</span>XAddr<span class="token operator">></span>http<span class="token operator">:</span> Line <span class="token number">85</span><span class="token operator">:</span> <span class="token operator"><</span>tt<span class="token operator">:</span>XAddr<span class="token operator">></span>http<span class="token operator">:</span> 
Line 7: <tt:XAddr>http: Line 12: <tt:XAddr>http: Line 59: <tt:XAddr>http: Line 65: <tt:XAddr>http: Line 68: <tt:XAddr>http: Line 81: <tt:XAddr>http: Line 85: <tt:XAddr>http:

在这里插入图片描述
c) 有的请求会失败,主要是你在请求时要输入正确的用户名和密码,如下图,还有就是会用到token这种值(token很多种,比如主码流和次码流对应不同的token,输入哪个token,就是对哪个码流操作)。
在这里插入图片描述

  1. xml 获取
    xml获取就是从Onvif Device Test Tool 拿到的,获得通过抓包工具对Onvif Device Test Tool和Onvif Device Manager进行抓包。

  2. 解析xml
    当解析xml时,要了解每个标签代表的含义是非常重要的,我们可以通过Onvif官网,找到对应模块找到对应接口进行阅读。
    Onvif接口地址
    比如 点击device.wsdl ,搜索GetCapabilities ,就能看到其字段说明,就是上面说的Response回复内容。
    在这里插入图片描述
    在这里插入图片描述

  3. 鉴权
    鉴权可以参考 Onvif鉴权
    红框的是需要鉴权的模块
    鉴权模块

    我是用Qt实现的。

<span class="token keyword">void</span> <span class="token class-name">Onvifrequest</span><span class="token double-colon punctuation">::</span><span class="token function">usernameToken</span><span class="token punctuation">(</span>QString <span class="token operator">&</span>username<span class="token punctuation">,</span> QString <span class="token operator">&</span>password<span class="token punctuation">,</span>QString <span class="token operator">&</span>nonce<span class="token punctuation">,</span>QString <span class="token operator">&</span>created<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token function">Q_UNUSED</span><span class="token punctuation">(</span>username<span class="token punctuation">)</span> <span class="token punctuation">}</span>
<span class="token keyword">void</span> <span class="token class-name">Onvifrequest</span><span class="token double-colon punctuation">::</span><span class="token function">usernameToken</span><span class="token punctuation">(</span>QString <span class="token operator">&</span>username<span class="token punctuation">,</span> QString <span class="token operator">&</span>password<span class="token punctuation">,</span>QString <span class="token operator">&</span>nonce<span class="token punctuation">,</span>QString <span class="token operator">&</span>created<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token function">Q_UNUSED</span><span class="token punctuation">(</span>username<span class="token punctuation">)</span>       <span class="token punctuation">}</span> 
void Onvifrequest::usernameToken(QString &username, QString &password,QString &nonce,QString &created) { Q_UNUSED(username) }

Onvif协议控制IPC

原文链接:https://blog.csdn.net/weixin_41349971/article/details/140214519?ops_request_misc=%257B%2522request%255Fid%2522%253A%252204dfaf3d156ee7a93762168645f3508a%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=04dfaf3d156ee7a93762168645f3508a&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~times_rank-23-140214519-null-null.nonecase&utm_term=%E9%A3%9E%E7%89%9BOS

© 版权声明
THE END
喜欢就支持一下吧
点赞6 分享