onvif客户端

前言

作开发有8年时间了,ffmpeg和onvif与我是特别有缘的了(说着玩的,我更认为是由于他们确实强大^_^)。 ffmpeg在毕业设计时就有用到,5年后作windows、linux播放库时又有用到,因而又从新研究!!! onvif是我在毕业第二年的时候,有从0开始写过一个onvif服务端NVT,没想到6年后,项目中的客户端又须要用到它!!!其实原本不想开发它的,可是由于客户端依赖的onvif部分是别人的库,咱们须要onvif抓图功能,结果对方没时间作,也不肯意把代码开放给咱们,我特郁闷,这个又没什么技术含量,不必当个宝藏着吧! 因而花了一周时间开发了本身的onvif客户端(这里不是从0开发,而是基于现有的开源onvif客户端开发的)。linux

onvif客户端开发过程

开发这类东西通常有两条路可选择,要么从0开始编码(固然,也不全是从0开始,能够基于onvif的wsdl来生成一些调用类,这样至少不用本身实现底层通信及协议封装了,更多的只是为上层接口具体功能作封装,填充结构成员,调用对应的方法等),要么基于现有的开源代码进行改进,完善(开源的代码通常也是经过从wsdl生成的代码为基础而作的封装)。我一般会先尝试后者,没有合适的开源代码可参考时,才会从0开始编码,不必发明轮子。下面记录下个人开发过程。c++

首先,用搜索引擎搜索onvif客户端,去github或者gitlab上搜索onvif客户端,从找到的结果中刷选出一些可能合适的,我最开始得出如下可能:git

我主要的过滤条件包括:github

  1. 咱们项目是C++的,我但愿是onvif客户端库也是c/c++开发的
  2. 我但愿该onvif库的最后维护时间尽量新,由于onvif有不少版本,不一样版本的wsdl生成的最终文件包含的功能有很大不一样
  3. 可以在1天内编译经过该开源的代码,由于不少开源的项目不够完善,别人很难很快的将其用起来
  4. 代码写的尽可能的标准、规范,换句话说,要写的好看

通过以上几个过滤实施后,我选择了 rapidonvif,它是c++开发的,并且和最新的onvif几乎同步,也是一次就编译经过了,经过简单的代码阅读,以为代码写的挺漂亮的^_^windows

进一步了解代码后,发现rapidonvif所提供的开源部分只是包含了onvif客户端的开发框架,不少功能都没有彻底实现,可是很容易的进行完善,这得益于它漂亮的代码编写!这里简单的描述下我二次开发的过程,目录结构图以下: rapidonvif结构图api

onvif客户端功能的核心部分都是在onvifgen目录里面实现的(固然,不少都没写完,可是很容易补充全),它对应了onvifcpplib工程,生成onvifclient.lib静态库 example\client\onvifclientwin32里面包含了一个onvifclient.lib静态库对应的测试demo框架

分析出以上两部分以后,就能够得出二次开发的方案了,我采用的修改example\client\onvifclientwin32,将它变成本身onvif客户端对外的导出层,将编译生成exe改为生成dll,而后根据需求完善onvifcpplib。gitlab

举例说明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客户端实现是很是适合的。

相关文章
相关标签/搜索