注: 本文提供的参考代码其实网上都可以找到,这里做一个整理,供大家交流学习,共同提高。
搜索:Probe : 发现网络摄像头,获取 webserver 地址 。例如:http://192.168.15.240/onvif/device_service
能力获取:GetCapabilities :获取设备能力文件,从中识别出媒体信息地址 URI。 例如:http://192.168.15.240/onvif/Media
媒体信息获取:GetProfiles : 获取媒体信息文件,识别主通道、子通道的视频编码分辨率
RTSP地址获取:GetStreamUri :获取指定通道的流媒体地址 例如:rtsp://192.168.15.240:554/Streaming/Channels/2?transportmode=unicast
在基于onvif规范的视频监控系统客户端(二)中,我们已经搭建好了onvif框架,创建了一个名为onvif_new的文件夹,搜索设备的代码我们也添加在这个文件夹下面。
具体代码如下:
能力获取函数
char* UserGetCapabilities(struct __wsdd__ProbeMatches *resp,struct _tds__GetCapabilitiesResponse *capa_resp)
{ struct soap* soap; struct SOAP_ENV__Header header; struct _tds__GetCapabilities capa_req; struct _trt__GetProfilesResponse getProfilesResponse; struct _trt__GetStreamUriResponse getStreamUriResponse;
soap = ONVIF_Initsoap(&header, NULL, NULL, 10);
capa_req.Category = (enum tt__CapabilityCategory *)soap_malloc(soap, sizeof(int));
capa_req.__sizeCategory = 1; *(capa_req.Category) = (enum tt__CapabilityCategory)(tt__CapabilityCategory__Media);
const char *soap_action = "http://www.onvif.org/ver10/device/wsdl/GetCapabilities";
int result = soap_call___tds__GetCapabilities(soap, resp->wsdd__ProbeMatches->ProbeMatch->XAddrs, soap_action, &capa_req, capa_resp);
//int result = soap_call___tds__GetCapabilities(soap, "http://192.168.1.51/onvif/device_service", NULL, &capa_req, capa_resp);
if (soap->error){
printf("[%d]--->>> soap error: %d, %s, %s\n", __LINE__, soap->error, *soap_faultcode(soap), *soap_faultstring(soap)); int retval = soap->error; exit(-1) ; }else{ if(capa_resp->Capabilities==NULL){ printf(" GetCapabilities failed! result=%d \n",result); }else{ return(UserGetProfiles(&getProfilesResponse,capa_resp)); } }
soap_destroy(soap);
soap_end(soap); soap_free(soap); } |
媒体信息获取
char* UserGetProfiles(struct _trt__GetProfilesResponse *getProfilesResponse ,struct _tds__GetCapabilitiesResponse *capa_resp)
{ int result=0 ;
struct soap* soap;
struct SOAP_ENV__Header header; struct _trt__GetProfiles getProfiles; struct _trt__GetStreamUriResponse getStreamUriResponse;
soap = ONVIF_Initsoap(&header, NULL, NULL, 10);
//soap_wsse_add_UsernameTokenDigest(soap,"user", ONVIF_USER, ONVIF_PASSWORD);
result = soap_call___trt__GetProfiles(soap, capa_resp->Capabilities->Media->XAddr, NULL, &getProfiles, getProfilesResponse); if (result==-1){ printf("soap error: %d, %s, %s\n", soap->error, *soap_faultcode(soap), *soap_faultstring(soap)); result = soap->error; exit(-1); }else{ if(getProfilesResponse->Profiles!=NULL) { if(getProfilesResponse->Profiles->Name!=NULL){ printf("Profiles Name:%s \n",getProfilesResponse->Profiles->Name);
}
if(getProfilesResponse->Profiles->token!=NULL){ printf("Profiles Taken:%s\n",getProfilesResponse->Profiles->token); } return(UserGetUri(&getStreamUriResponse,getProfilesResponse,capa_resp)); }else{ printf("Profiles Get inner Error\n"); } }
soap_destroy(soap);
soap_end(soap); soap_free(soap); } |
rtsp地址获取:
char* UserGetUri(struct _trt__GetStreamUriResponse *trt__GetStreamUriResponse,struct _trt__GetProfilesResponse *trt__GetProfilesResponse,struct _tds__GetCapabilitiesResponse *capa_resp)
{ int result=0 ; struct soap* soap; struct SOAP_ENV__Header header; struct _trt__GetStreamUri getStreamUri; soap = ONVIF_Initsoap(&header, NULL, NULL, 10); soap->socket = 3; getStreamUri.StreamSetup = (struct tt__StreamSetup*)soap_malloc(soap, sizeof(struct tt__StreamSetup));//初始化,分配空间 getStreamUri.StreamSetup->Stream = tt__StreamType__RTP_Unicast;//0;//stream type getStreamUri.StreamSetup->Transport = (struct tt__Transport *)soap_malloc(soap, sizeof(struct tt__Transport));//初始化,分配空间 getStreamUri.StreamSetup->Transport->Protocol = tt__TransportProtocol__UDP;//0; getStreamUri.StreamSetup->Transport->Tunnel = NULL; getStreamUri.StreamSetup->__size = 1; getStreamUri.StreamSetup->__any = NULL; getStreamUri.StreamSetup->__anyAttribute =NULL; getStreamUri.ProfileToken = (char*)soap_malloc(soap,1024); strcpy(getStreamUri.ProfileToken, trt__GetProfilesResponse->Profiles->token);
// getStreamUri.ProfileToken = trt__GetProfilesResponse->Profiles->token ;
//soap_wsse_add_UsernameTokenDigest(soap,"user", ONVIF_USER, ONVIF_PASSWORD); soap_call___trt__GetStreamUri(soap, capa_resp->Capabilities->Media->XAddr, NULL, &getStreamUri, trt__GetStreamUriResponse); if (soap->error) { printf("soap error: %d, %s, %s\n", soap->error, *soap_faultcode(soap), *soap_faultstring(soap)); result = soap->error; } return trt__GetStreamUriResponse->MediaUri->Uri; soap_destroy(soap); soap_end(soap); soap_free(soap); } |
完整代码下载地址:
编译步骤:
make
g++ main.c -L这个文件的绝对路径 -LDisC