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

猜你喜欢

转载自blog.csdn.net/fengliang191/article/details/106032868