在之前很长时间对于GB28181协议的研究过后,发现很多国际品牌摄像头在对接过程中不支持GB28181协议,对于这些品牌大多数还是支持一个国际化的设备发现协议--------Onvif协议。那么今天就过来谈一谈自己对Onvif协议的初见解。
首先,我们来看一下什么是web service:
Web Services初学者,gSOAP可能是他们入手的最开始的工具,这样就不用我们重复的实现别人已经造好的轮子。对于众多的概念,我们先放在一边,从总体上面了解一下:
1、Web Services是一种网络服务,它对外提供了一系列远程调用接口(RPC),你可以像本地调用一样去调用这些远程调用接口。
2、Web Services常用的框架有多种,ONVIF标准中的Web Service采用的是SOAP方式。
3、WSDL文档是采用SOAP方式实现的Web Services的接口描述文档,就像动态库的.h文件一样。同时也展示了WSDL语言转化为C语言的对比效果。
其次,我们要知道我们通过Onvif协议可以干什么:
在很多工程中,我感觉最实用的应该是设备发现、鉴权、获取rtspUri这么三个功能,因为对于监控项目中,最关心的环节莫过于如何取流,以及如何进行在网络环境中发现设备。
那我们首先看一下设备发现是如何做到的:
开启线程:
void probeCallback(DEVICE_BINFO * p_res, void * p_data)
{
ONVIF_DEVICE_EX * p_dev = NULL;
ONVIF_DEVICE_EX device;
memset(&device, 0, sizeof(ONVIF_DEVICE_EX));
memcpy(&device.onvif_device.binfo, p_res, sizeof(DEVICE_BINFO));
device.state = 1;
p_dev = findDevice(&device);
if (p_dev == NULL)
{
printf("Found device. ip : %s, port : %d\n", p_res->XAddr.host, p_res->XAddr.port);
p_dev = addDevice(&device);
if (p_dev)
{
p_dev->thread_handler = sys_os_create_thread((void *)getDevInfoThread, p_dev);
}
}
else
{
if (p_dev->no_res_nums >= 2 && 0 == p_dev->thread_handler)
{
p_dev->thread_handler = sys_os_create_thread((void *)getDevInfoThread, p_dev);
}
p_dev->no_res_nums = 0;
p_dev->state = 1;
}
}
处理信令交互的内容:
void * getDevInfoThread(void * argv)
{
char profileToken[ONVIF_TOKEN_LEN];
ONVIF_Profile * p_profile = NULL;
ONVIF_DEVICE_EX * p_device = (ONVIF_DEVICE_EX *) argv;
GetCapabilities(&p_device->onvif_device);
GetServices(&p_device->onvif_device);
GetDeviceInformation(&p_device->onvif_device);
GetVideoSources(&p_device->onvif_device);
GetImagingSettings(&p_device->onvif_device);
GetVideoSourceConfigurations(&p_device->onvif_device);
GetVideoEncoderConfigurations(&p_device->onvif_device);
if (GetAudioSources(&p_device->onvif_device))
{
GetAudioSourceConfigurations(&p_device->onvif_device);
GetAudioEncoderConfigurations(&p_device->onvif_device);
}
/* save currrent profile token */
if (p_device->onvif_device.curProfile)
{
strcpy(profileToken, p_device->onvif_device.curProfile->token);
}
else
{
memset(profileToken, 0, sizeof(profileToken));
}
GetProfiles(&p_device->onvif_device);
GetStreamUris(&p_device->onvif_device);
ONVIF_Profile *temp = p_device->onvif_device.profiles;
//获取到他所有码流
//while (temp) {
printf("name:%s-----stream_uri:%s\n", temp->name, temp->stream_uri);
// temp = temp->next;
//}
/* resume current profile */
printf("Token is----------->:%s\n",profileToken);
if (profileToken[0] != '\0')
{
p_profile = onvif_find_Profile(&p_device->onvif_device, profileToken);
}
if (NULL == p_profile)
{
p_profile = p_device->onvif_device.profiles;
}
p_device->onvif_device.curProfile = p_profile;
if (p_device->onvif_device.Capabilities.ptz.support)
{
GetNodes(&p_device->onvif_device);
GetConfigurations(&p_device->onvif_device);
}
if (p_device->onvif_device.Capabilities.media.SnapshotUri == 1 && p_profile)
{
int len;
unsigned char * p_buff;
if (GetSnapshot(&p_device->onvif_device, p_profile->token, &p_buff, &len))
{
if (p_device->p_snapshot)
{
FreeSnapshotBuff(p_device->p_snapshot);
p_device->p_snapshot = NULL;
p_device->snapshot_len = 0;
}
p_device->p_snapshot = p_buff;
p_device->snapshot_len = len;
}
}
if (p_device->onvif_device.Capabilities.events.support == 1 &&
p_device->onvif_device.events.subscribe == FALSE)
{
// the caller should call Unsubscribe when free this device
Subscribe(&p_device->onvif_device, pps_get_index(m_dev_ul, p_device));
}
onvifUserTest(p_device);
if (p_device->onvif_device.Capabilities.image.support)
{
onvifImageTest(p_device);
}
if (p_device->onvif_device.Capabilities.media2.support)
{
onvifMedia2Test(p_device);
}
if (p_device->onvif_device.Capabilities.accesscontrol.support)
{
onvifAccessControlTest(p_device);
}
if (p_device->onvif_device.Capabilities.doorcontrol.support)
{
onvifDoorControlTest(p_device);
}
if (p_device->onvif_device.Capabilities.recording.support)
{
onvifRecordingTest(p_device);
}
p_device->thread_handler = 0;
return NULL;
}
然后里面就可以发现到设备,并且鉴权通过,并且最终获取到每个设备中的主码流、子码流的rtsp地址了。
配合程序测试连接:http://download.csdn.net/download/qq_24798461/9984271
最后:
如果有想联系我做技术交流的,可以联系我qq: 1015787417