對應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