onvif 開發摘要

對應onvif開發,步驟比較囉嗦。常規流程是:

1.下載gsoap工具

2.利用gsoap中wsdl2h在線生成頭文件或者離線生成頭文件。

1)在線生成頭文件,但因爲自帶的wsdl2h.exe工具不支持https,需要自己編譯一個windows版本工具,支持https還要移植openssl比較繁瑣。

在Linux編譯就方便多了安裝openssl依賴,直接./configure make 即可生成新的wsdl2h

2)離線生成頭文件,需要事先下載相關的wsdl文件以及依賴的xsd文件,相當的折騰,然後使用wsdl2h生成頭文件

3 生成onvif.h頭文件之後,即可根據soapcpp2命令生成C源文件或者CPP源文件。

注意:

1.因爲鑑權的需要,在onvif.h頭文件中加入#import "wsse.h"。

2.避免接下來產生框架發生錯誤,修改OnvifFramework(C++)\gsoap-2.8\gsoap\import路徑下的wsa5.h,將SOAP_ENV__Fault結構體名字修改爲SOAP_ENV__Fault_alex。

將生成的文件放到目錄,後面即可調用。開發ONVIF客戶端程序,使用XXXXProxy.h和XXXXProxy.scpervice.cpp,開發ONVIF服務器端程序,使用XXXXService.h和XXXXService.cpp

以上環境配置相當繁瑣,運氣不好可能會磕磕碰碰折騰一陣子。以上工作本質就將WSDL文檔描述生成對應的C/C++代碼,支持SOAP協議的發送和接收,以及onvif相關接口。

爲了防止重複造輪子,筆者整理一套現成的SDK,以便後續快速進行二次開發。

目前提供了設備發現,獲取媒體URL,雲臺控制,接收事件,錄製管理等等,代碼框架清楚直白,很容易二次開發

開發demo如下:

string GetMidaStreamUrl(OnvifClientDevice &onvifclientdevice,int channel)

{

_trt__GetProfilesResponse profiles;

_trt__GetStreamUriResponse StreamUriResponse;

tt__StreamSetup StreamSetup;

tt__Transport Transport;

Transport.Protocol = tt__TransportProtocol__UDP;

Transport.Tunnel = NULL;

StreamSetup.Stream = tt__StreamType__RTP_Unicast;

StreamSetup.Transport = &Transport;

#if 0

OnvifClientMedia* pmedia = new OnvifClientMedia(onvifclientdevice);

pmedia->GetProfiles(profiles);

//traverseVector(profiles.Profiles);

pmedia->GetStreamUri(StreamUriResponse, StreamSetup, profiles.Profiles[channel]->token);

#else

OnvifClientMedia media(onvifclientdevice);

media.GetProfiles(profiles);

//traverseVector(profiles.Profiles);

media.GetStreamUri(StreamUriResponse, StreamSetup, profiles.Profiles[channel]->token);

#endif

return StreamUriResponse.MediaUri->Uri;

}

typedef struct DeviceInfo

{

char uuid[64];

char deviceURL[64];

}DeviceInfo;

typedef struct DeviceList

{

int device_num;

DeviceInfo* pDeviceInfoList;

}DeviceList;

void ListDevideInfo(DeviceList DeviceList)

{

for (int i = 0; i < DeviceList.device_num; i++)

{

printf("uuid[%d]: %s\n", i,DeviceList.pDeviceInfoList[i].uuid);

printf("device[%d]: %s\n", i,DeviceList.pDeviceInfoList[i].deviceURL);

}

}

// SOAP_IO_UDP|SOAP_IO_FLUSH

int _tmain(int argc, _TCHAR* argv[])

{

if (argc < 3)

{

printf("usage: onvifclient.exe username password");

return 0;

}

int ret;

//發現設備

char* searchurl = "soap.udp://239.255.255.250:3702";

OnvifClientDiscovery tOnvifClientDiscovery(searchurl);

DeviceList DeviceList;

DeviceInfo* pDeviceInfo = NULL;

 

wsdd__ProbeMatchesType t_ProbeMatchesType;

tOnvifClientDiscovery.OnvifClientDeviceSearch(t_ProbeMatchesType);

DeviceList.device_num = t_ProbeMatchesType.__sizeProbeMatch;

if (t_ProbeMatchesType.__sizeProbeMatch > 0)

{

pDeviceInfo = (DeviceInfo*)malloc(sizeof(DeviceInfo) * (t_ProbeMatchesType.__sizeProbeMatch));

if (!pDeviceInfo)

{

printf("malloc DeviceList is failed ");

return 0;

}

DeviceList.pDeviceInfoList = pDeviceInfo;

}

for (int i = 0; i < t_ProbeMatchesType.__sizeProbeMatch; i++)

{

strcpy(pDeviceInfo[i].uuid, t_ProbeMatchesType.ProbeMatch[i].wsa__EndpointReference.Address);

strcpy(pDeviceInfo[i].deviceURL, t_ProbeMatchesType.ProbeMatch[i].XAddrs);

}

ListDevideInfo(DeviceList);

//查找媒體URL

string user(argv[1]);

string pass(argv[2]);

for (int i = 0; i < t_ProbeMatchesType.__sizeProbeMatch; i++)

{

string url(DeviceList.pDeviceInfoList[i].deviceURL);

OnvifClientDevice* ponvifDevice = new OnvifClientDevice(url, user, pass);

if (!ponvifDevice)

{

printf("malloc OnvifClientDevice is failed");

return 0;

}

_tds__GetCapabilitiesResponse pcapabilitiesResponse;

if (ponvifDevice)

{

ponvifDevice->GetCapabilities(pcapabilitiesResponse);

}

string MediaUri = GetMidaStreamUrl(*ponvifDevice, 0);

printf("url is %s\n", MediaUri.c_str());

}

return 0

}

編譯後運行該程序

 

 

該demo地址如下:

https://download.csdn.net/download/fengliang191/12391306

該demo可以作爲一個工具,可以用來發現支持onvif協議的IPC的IP地址,獲取媒體RTSP的URL。因爲不同廠家IPC的RTSP的URL不一樣,該工具可以自動查找攝像頭的RTSP的URL。目前SDK提供了設備發現,獲取媒體URL,雲臺控制,接收事件,錄製管理等等,代碼框架清楚直白,支持Linux /windows ,很容易二次開發。SDK 下載地址請關注公衆號:AV_Chat

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