当前位置: 首页 > 流媒体学习 > 正文

onvif学习笔记8:最近写的一个ONVIF客户端的心得小结

最近,利用业余时间编写一个简单的ONVIF客户端MFC程序,这里记录一下过程。

语言选择

在之前调查过,有用QT实现的,有用python实现的,虽然正在学python,无奈才看了3天的书,没自信去搞。最后还是使用自己熟悉了好多年的MFC,但没有找到MFC的代码,只好自己写一个了。

onvif客户端架构代码

从2013年首次接触onvif的恐惧,到去年对onvif熟知,都是服务端的代码。而客户端的代码却没接触过。不过用gsoap生成框架代码也简单。由于自己的求知欲较强,最后生成了面向对象的版本(即每种服务分别作为不同类)和不面向对象的版本(即所有接口均实现在一个文件),在两者难取舍情况下,不得已,做了2个版本。在Linux下使用面向对象的,而在MFC中使用C版本的。

VS2010搭建环境

onvif的鉴权,要使用到openssl,一开始我使用mingw编译openssl,但放到vs2010编译,出现很多未定义引用的错误,包括如_chkstk、___umoddi3这些没见过的函数,还搜索VS配置的/MD、/MDd、/MT、/MTd的资料,但还是一筹莫展。最后用vs编译器来编译openssl,结果一切正常了。
但是,gsoap生成的代码有部分是用linux的接口,如usleep,根据错误来修改,也不是十分困难的事。在MFC中使用,要将所有.c文件改为.cpp,还得在每个实现文件包含stdafx.h。

ONVIF鉴权

ONVIF的鉴权功能,网上资料比较少,大部分是基于WS-Username token的方式,而http digest较少。后来无意间搜索代码才找到使用方式。

ONVIF中文乱码

在实现OSD叠加功能时,发现中文有乱码,即使我将字符转换成UTF8但还是不行。后面跟踪soap结构体,发现xml协议中的内容是正常的UTF8(我使用hexdump同样的字符来对比二进制)。但到反序列化转换成结构体时,就出现乱码了,于是确认ONVIF代码本身编码存在问题。后来上网查了好久,发现可以将ONVIF设置为UTF编码,调用soap_set_mode(m_soap, SOAP_C_UTFSTRING); 即可。

下面简单描述从设备发现到叠加OSD的过程:
组播搜索设备(或者直接指定IP发probe);
获取设备提供的service——主要知道media的地址;
获取profile;
获取OSDOptions,知道设备OSD提供的特性及限制,不过我发现有个OSD选项被VS优化掉了,但在Linux下却没问题;
调用CreateOSD创建一个OSD,设备会返回一个OSD token,这个token就是下面要使用的;
使用SetOSD修改OSD内容、坐标;
调用DeleteOSD删除OSD。

ONVIF编码十分繁琐,需要一定的耐心和平常心对待。
建议参考gsoap生成的代码,比如soapstub.h头文件就定义了各种结构(类)。另外也要参考官网标准手册,里面对命令功能、返回值均有说明。至于每个结构体详细定义,可以参考官网提供的WSDL信息文档:http://www.onvif.org/onvif/ver10/device/wsdl/devicemgmt.wsdlhttp://www.onvif.org/onvif/ver10/media/wsdl/media.wsdl
最后,抓包分析也是一个很好的方法,特别有且于了解未鉴权、鉴权的细节。
下一步计划:参考onvif测试工具界面、功能,做一个比较完善的ONVIF客户端(最好能集调试、视频查看为一体的程序)。以便深入学习ONVIF。

李迟 2016.6.7 周二 夜

本文固定链接: http://www.latelee.org/multistream/onvif-note8-onvif-client-note.html

目前暂无评论

发表评论

*

快捷键:Ctrl+Enter