自行实现 Onvif 对接开发模式

对于Onvif协议,在安防视频行业的地方,谁都知道。但是网上就有onvif协议对接的方案都是使用开源的第三方库进行对接,讲解。那么问题来了,我们能不能用代码自己实现呢?答案是肯定的。而要用我们自己的代码实现onvif协议对接,其中牵扯到诸多的协议和概念,这里我大致整理一下,对自行实现Onvif协议对接者提供一个学习思路。

1、工具很重要

学习onvif之前,需要两个最基本工具:

1、ONVIF Device Test Tool 官方的onvif协议测试工具

2、wireshark 网络抓包工具

其中wireshark 大家自行去网上下载,一个通用的工具,如果你还在想工具如何使用,那么感觉行动起来,因为它是网络开发中的瑞士军刀,开发者的必备工具。如何使用ONVIF Device Test Tool可以在我的文章中了解: http://blog.csdn.net/yuanbinquan/article/details/65443898

ONVIF Device Test Tool资源下载:http://download.csdn.net/detail/yuanbinquan/9871234

2、资料很重要

onvif 协议定义的部分wsdl文档

1、http://www.onvif.org/ver10/media/wsdl

2、http://www.onvif.org/ver20/media/wsdl

等等这里有个名词:wsdl ,这里会在后续的篇幅中介绍。这两个网址直接进入,即查看。

3、概念很重要

作为一个开发者,有了开发工具和开发资料之后,那么接下来自然是学习了。学习onvif第一步也是很重要的一步,就是onvif中的概念。对于一个初学者来说,开始接触onvif的时候,很有可能被网上一大堆的各种资料弄的晕头转向。就连笔者在最开始接触onvif的时候,也有过来人给我传输资料,而这个资料就是一个2百多兆的压缩包,里面可谓是大杂烩啥都有,这些资料也没有个纲领说明主次和功能,那个内心惶惶的...... 废话不多说了,下面列举重要概念,并逐一解释。

1、服务器和客户端

在onvif协议对接中,首先要明确服务器和客户端的身份

服务器:通常是你要对接的其他厂家的数字摄像头(IPC)

客户端:通常是对接的ipc的设备程序,安防业内多称(NVR),当然其他软件工具也可称为客户端,如ONVIF Device Test Tool, vlc软件

明确了服务器和客服端身份之后,就是两者之间基于某种协议通信了,这里先从服务器说起。

服务器:是一个基于web server的服务器,也就是一个网页服务器。那么问题来了,一个网页服务器如何同客户端通信呢,通信时涉及到哪些知识,这就是我们对接onvif需要学习的。下面 我先把知识点列举出来,并初步介绍一下:

4、了解基本语法和概念

1、xml:可扩展标记语言标准通用标记语言的子集,是一种用于标记电子文件使其具有结构性的标记语言

2、http:超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议

3、soap:简单对象访问协议是交换数据的一种协议规范,是一种轻量的、简单的、基于XML标准通用标记语言下的一个子集)的协议,它被设计成在WEB上交换结构化的和固化的信息

4、WS-discovery:你在预先不知道目标服务的情况下,可以动态的探测可用的服务并调用

5、wsdl:网络服务描述语言是Web Service的描述语言,它包含一系列描述某个web service的定义。这里可以通俗的理解为协议定义。

这里列举了五个重要的概念的定义,但这些协议是需要你自己去学习和认知的。不能盲目的为了实现功能和学习,一定要知其然。

这里除了WS-discovery外,其他概念都很好学习,跟着这个网站:http://www.w3school.com.cn/ 学就可以了,当然这些知识不需要你有多精通,只需要你对其有个全面的认知,就可以掉头回来学习Onvif。

5、onvif对接流程

1、收搜设备

客户端对接ipc第一件事,是在组网内发现可用的ipc的ip、端口,这里用到的是WS-discovery协议,当然WS-discovery协议本身又涉及到了xml,http,soap。对了这个协议是基于upd协议的广播包实现了,那么读者有需要熟悉一下udp的数据广播原理了。

2、链接设备实现参数获取与设置

获取到组网内可用的ipc的ip、端口之后就是,建立tcp链接和服务器进行通信,来获取和设置参数了。这里面涉及的协议有xml,http,soap,wsdl。

6、示例数据详解

这里以获取ipc设备信息为例,对onvif对接时的参数进行详解。

#############SEND:
POST /onvif/device_service HTTP/1.1
Host: 192.168.100.125
Content-Type:application/soap+xml;charset=utf-8
Content-Length:275

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:tds="http://www.onvif.org/ver10/device/wsdl" xmlns:tt="http://www.onvif.org/ver10/schema">
<soap:Body><tds:GetDeviceInformation /></soap:Body></soap:Envelope>


#############recv ret = 1261, RECV:
HTTP/1.1 200 OK
Server: hsoap/2.8
Content-Type: application/soap+xml;charset=utf-8
Content-Length: 1132
Connection: close

<?xml version="1.0" encoding="UTF-8"?><s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:e="http://www.w3.org/2003/05/soap-encoding" xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:tns1="http://www.onvif.org/ver10/topics" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tt="http://www.onvif.org/ver10/schema" xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2" xmlns:wstop="http://docs.oasis-open.org/wsn/t-1" xmlns:tds="http://www.onvif.org/ver10/device/wsdl" xmlns:trt="http://www.onvif.org/ver10/media/wsdl" xmlns:tev="http://www.onvif.org/ver10/events/wsdl" xmlns:tptz="http://www.onvif.org/ver20/ptz/wsdl" xmlns:timg="http://www.onvif.org/ver20/imaging/wsdl" xmlns:tan="http://www.onvif.org/ver20/analytics/wsdl" xmlns:ter="http://www.onvif.org/ver10/error" ><s:Body><tds:GetDeviceInformationResponse><tds:Manufacturer>ONVIF_IPNC</tds:Manufacturer><tds:Model></tds:Model><tds:FirmwareVersion>1.0.12-20170118Z1S</tds:FirmwareVersion><tds:SerialNumber>2855568997</tds:SerialNumber><tds:HardwareId>8FE1887A-72EE-403f-9385-5a57aa348665</tds:HardwareId></tds:GetDeviceInformationResponse></s:Body></s:Envelope>


其中#############SEND:代表的是客户端发送的数据,发送到服务器的。

#############recv ret = 1261, RECV:代表着客户端接收的数据,是服务器发送给客户端的。

1、客户端发送数据讲解

1、可以认为是一个http协议的post指令

2、在http post指令中可以看到,指定的数据体是soap+xml格式的,也就是4。

3、http数据体长度为275

4、是一个xml文件,同时也是符合soap语法的。

5、6 部分需要讲解一下,这是soap语法的一部分。

xmlns:xml namespace,即xml 命名空间。

使用的规则为,首先定义命名空间xmlns:namespace-prefix="namespaceURI"Androidxml中的使用是:xmlns:前缀=http://schemas.android.com/apk/res/应用程序包路径;然后使用的时候按格式:namespace-prefix(前缀):属性

如果使用xmlns,则xmlns的定义必须放在最外层开始的的标记中

当命名空间被定义之后,所有带有相同前缀的子元素都会与同一个命名空间相关联。避免XML解析器对xml解析时的发送名字冲突,这就是使用xmlns的必要性。当自定义的View有自己的属性的时候,就用到xmlns来定义一个命名空间。


2、服务器发送数据讲解

服务器发送数据部分和客户端发送数据部分的基本格式相同,就不做多述,这里重点讲解一下命名空间和wsdl的理解。

前面已经讲过了xmlns的含义了,这里联合着wsdl一起讲解:xmlns:trt="http://www.onvif.org/ver10/media/wsdl",这句文本的含义,xml节点以trt开始命名的节点,它的定义需要在http://www.onvif.org/ver10/media/wsdl wsdl文档中查看,那我们看这个wsdl的部分定义是怎么样的。如下:

如果xml节点以trt开始命名的节点名为AddAudioDecoderConfiguration,那么它基本意思为添加一个音频编码器。不难理解是客户端可以发送这条指令给服务器,从而达到增加服务器音频编码器的目的,发送该指令需要输入的参数为:ProfileToken,configrationToken,然后服务器接收到这条请求指令后,会给客户端进行回复。这里对wsdl初步描述之后,对wsdl的认知就更为清晰了,它就是一个协议定义文档。

这里的wsdl文档我只找到了部分。可惜了......

7、自行实现onvif对接

在学习了前面6部分了之后,接下来就是对接onvif协议了,比如我需要一个设置osd的显示的功能,那么首先你需要http、soap、xml作为基础知识,封装最基本的数据格式,然后是在相关wsdl文档中找到设置osd显示的定义。然后填充成一个完成的数据包,发送给服务器,等待服务器应答,并处理相应的应答数据。

在"http://www.onvif.org/ver10/media/wsdl 找到设置osd的解析:

然后生成文本,由客户端发送数据:

#############SEND:
POST /onvif/device_service HTTP/1.1
Host: 192.168.100.125
Content-Type:application/soap+xml;charset=utf-8
Content-Length:584

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:trt="http://www.onvif.org/ver10/media/wsdl" xmlns:tt="http://www.onvif.org/ver10/schema">
<soap:Body> <trt:SetOSD> <trt:OSD token="osd_token_0">
<tt:VideoSourceConfigurationToken>V_SRC_000</tt:VideoSourceConfigurationToken>
<tt:Type>Text</tt:Type>
<tt:Position><tt:Type>LowerLeft</tt:Type></tt:Position><tt:TextString><tt:Type>Plain</tt:Type>
<tt:PlainText>CH07,  466662,,,0 KM/H</tt:PlainText></tt:TextString></trt:OSD>
</trt:SetOSD></soap:Body></soap:Envelope>


服务器应答数据:
 #############recv ret = 966, RECV:
HTTP/1.1 200 OK
Server: hsoap/2.8
Content-Type: application/soap+xml;charset=utf-8
Content-Length: 838
Connection: close

<?xml version="1.0" encoding="UTF-8"?><s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:e="http://www.w3.org/2003/05/soap-encoding" xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:tns1="http://www.onvif.org/ver10/topics" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tt="http://www.onvif.org/ver10/schema" xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2" xmlns:wstop="http://docs.oasis-open.org/wsn/t-1" xmlns:tds="http://www.onvif.org/ver10/device/wsdl" xmlns:trt="http://www.onvif.org/ver10/media/wsdl" xmlns:tev="http://www.onvif.org/ver10/events/wsdl" xmlns:tptz="http://www.onvif.org/ver20/ptz/wsdl" xmlns:timg="http://www.onvif.org/ver20/imaging/wsdl" xmlns:tan="http://www.onvif.org/ver20/analytics/wsdl" xmlns:ter="http://www.onvif.org/ver10/error" ><s:Body><trt:SetOSDResponse /></s:Body></s:Envelope>


整篇文正都只是一个onvif协议对接的基本开发流程。

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页