自行實現 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協議對接的基本開發流程。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章