onvif客戶端(轉載)

本文爲轉載文章,文章出處爲:https://www.cnblogs.com/rongpmcu/p/10351204.html

如果有侵權請及時聯繫刪除,如想轉載請先去聯繫原作者

onvif客戶端

前言

做開發有8年時間了,ffmpeg和onvif與我是特別有緣的了(說着玩的,我更認爲是因爲他們確實強大^_^)。 ffmpeg在畢業設計時就有用到,5年後做windows、linux播放庫時又有用到,於是又重新研究!!! onvif是我在畢業第二年的時候,有從0開始寫過一個onvif服務端NVT,沒想到6年後,項目中的客戶端又需要用到它!!!其實本來不想開發它的,但是因爲客戶端依賴的onvif部分是別人的庫,我們需要onvif抓圖功能,結果對方沒時間做,也不願意把代碼開放給我們,我特鬱悶,這個又沒什麼技術含量,沒必要當個寶藏着吧! 於是花了一週時間開發了自己的onvif客戶端(這裏不是從0開發,而是基於現有的開源onvif客戶端開發的)。

onvif客戶端開發過程

開發這類東西一般有兩條路可選擇,要麼從0開始編碼(當然,也不全是從0開始,可以基於onvif的wsdl來生成一些調用類,這樣至少不用自己實現底層通訊及協議封裝了,更多的只是爲上層接口具體功能做封裝,填充結構成員,調用對應的方法等),要麼基於現有的開源代碼進行改進,完善(開源的代碼一般也是通過從wsdl生成的代碼爲基礎而做的封裝)。我通常會先嚐試後者,沒有合適的開源代碼可參考時,纔會從0開始編碼,沒必要發明輪子。下面記錄下我的開發過程。

首先,用搜索引擎搜索onvif客戶端,去github或者gitlab上搜索onvif客戶端,從找到的結果中刷選出一些可能合適的,我最開始得出以下可能:

我主要的過濾條件包括:

  1. 我們項目是C++的,我希望是onvif客戶端庫也是c/c++開發的
  2. 我希望該onvif庫的最後維護時間儘可能新,因爲onvif有很多版本,不同版本的wsdl生成的最終文件包含的功能有很大不同
  3. 能夠在1天內編譯通過該開源的代碼,因爲很多開源的項目不夠完善,別人很難很快的將其用起來
  4. 代碼寫的儘量的標準、規範,換句話說,要寫的好看

經過以上幾個過濾實施後,我選擇了 rapidonvif,它是c++開發的,而且和最新的onvif幾乎同步,也是一次就編譯通過了,通過簡單的代碼閱讀,覺得代碼寫的挺漂亮的^_^

進一步瞭解代碼後,發現rapidonvif所提供的開源部分只是包含了onvif客戶端的開發框架,很多功能都沒有完全實現,但是很容易的進行完善,這得益於它漂亮的代碼編寫!這裏簡單的描述下我二次開發的過程,目錄結構圖如下:
rapidonvif結構圖

onvif客戶端功能的核心部分都是在onvifgen目錄裏面實現的(當然,很多都沒寫完,但是很容易補充全),它對應了onvifcpplib工程,生成onvifclient.lib靜態庫
example\client\onvifclientwin32裏面包含了一個onvifclient.lib靜態庫對應的測試demo

分析出以上兩部分之後,就可以得出二次開發的方案了,我採用的修改example\client\onvifclientwin32,將它變成自己onvif客戶端對外的導出層,將編譯生成exe改成生成dll,然後根據需求完善onvifcpplib。

舉例說明1:onvif搜索實現

搜索的實現是通過OnvifClientSearch類來完成的,該類已定義,但是功能需要自己補充,對應的頭文件onvifclientsearch.hpp,它內部是通過wsddProxy代理來實現搜索的,該代理封裝了soap,代理部分的大部分功能這個開源庫已經實現了,也就是說學會怎麼使用該類即可。

舉例說明2:onvif ptz實現

ptz的實現是通過OnvifClientPTZ類來完成的,該類已定義,但是功能需要自己補充,對應的頭文件onvifclientptz.hpp,它內部是通過PTZBindingProxy代理來實現ptz控制的,該代理封裝了soap,代理部分的大部分功能這個開源庫已經實現了,也就是說學會怎麼使用該類即可。因此,好消息是onvif ptz協議部分基本已經實現,我們要做的就是根據PTZBindingProxy類實現一些ptz方法,然後補充到OnvifClientPTZ類中。

舉例說明3:onvif 抓圖實現

抓圖的實現是通過OnvifClientMedia類來完成的,該類已定義,但是功能需要自己補充,對應的頭文件onvifclientmedia.hpp,它內部是通過MediaBindingProxy代理來實現ptz控制的,該代理封裝了soap,代理部分的大部分功能這個開源庫已經實現了,也就是說學會怎麼使用該類即可。我們主要需要通過onvif協議獲取抓圖uri,然後通過http去這個uri取抓圖的數據即可。參考實現如下:

inline int OnvifClientMedia::GetSnapshotUri(_trt__GetSnapshotUriResponse &SnapshotUriResponse,string profileToken)
{
	string strUrl;
	string strUser;
	string strPass;
	if (m_Device.GetUserPasswd(strUser, strPass) == false 
		|| m_Device.GetMediaUrl(strUrl) == false)
	{
		return SOAP_ERR;
	}

	mediaProxy.soap_endpoint =  strUrl.c_str();
	soap_wsse_add_Security(&mediaProxy);
	soap_wsse_add_UsernameTokenDigest(&mediaProxy, "Id", strUser.c_str() , strPass.c_str());

	_trt__GetSnapshotUri SnapshotUriReq;
	SnapshotUriReq.ProfileToken = profileToken;
	return mediaProxy.GetSnapshotUri(&SnapshotUriReq, &SnapshotUriResponse);
}

總結

我的onvif客戶端的實現沒有從0開始,而是採用基於rapidonvif二次開發實現的,該開源的代碼寫的非常漂亮,且onvif的功能也實現的非常全,同時,要擴展自己的功能的操作也是那固定的幾步,因此我認爲用它作爲自己onvif客戶端實現是非常適合的。


    畢業那兩年在做嵌入式應用開發,主要是單片機和arm linux上的應用開發,後來又做了兩年arm linux驅動開發,15年到現在在做pc端及嵌入式端開發,包括服務器系統裁剪、底層框架實現、硬件加速等。喜歡技術分享、交流!聯繫方式: [email protected][email protected]

 

 

本文爲轉載文章,文章出處爲:https://www.cnblogs.com/rongpmcu/p/10351204.html

如果有侵權請及時聯繫刪除,如想轉載請先去聯繫原作者

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