1 背景
在前文中获取到了媒体信息URI http://192.168.15.240/onvif/Media, 本文将向这个地址查询设备的具体媒体配置信息,将返回视频源分辨率、编码器分辨率、编码格式、帧率、码率、多播地址等信息。
2 GetProfiles
获取媒体信息函数是GetProfiles,在我的版本中实际名称是:
SOAP_FMAC5 int SOAP_FMAC6 soap_call___ns8__GetProfiles(struct soap *soap, const char *soap_endpoint, const char *soap_action, struct _ns8__GetProfiles *ns8__GetProfiles, struct _ns8__GetProfilesResponse *ns8__GetProfilesResponse)
我只研究了关于Media类别的配置信息,其它类别没有尝试过。
事实上,一个摄像头一般都有2个通道,一个是主通道,提供高清视频,用于本地查看及录像;另一个是子通道,提供普通视频,用于远程查看(例如手机访问、远程PC访问)。这两个通道各有一份配置文件,因此,该函数应答包中包含两份数据。
3 我的代码实例:
/******************************************************************************
* Name: MyGetProfiles
*
* Desc: 获取指定设备节点的媒体信息
struct soap *soap,
int index, 设备节点序号
* Return: BOOL, TRUE: success, FALSE: fail
* Global:
* Note:
* Author: Tom-hongtao.gao
* -------------------------------------
* Log: 2013/07/24, Create this function by Tom-hongtao.gao
******************************************************************************/
BOOL MyGetProfiles(struct soap *soap, int index)
{
BOOL bret=FALSE;
int result = 0;
DEVICENODE * deviceode = DLFindbyIndex(index);
if(!deviceode)
{
printf("--Error: DLFindbyIndex(%d) return NULL! \n", index);
return FALSE;
}
if(deviceode->mediauri==NULL || strlen(deviceode->mediauri)==0)
{
printf("--Error: deviceode->mediauri is NULL! \n");
return FALSE;
}
struct _ns8__GetProfiles getProfilesReq;
struct _ns8__GetProfilesResponse getProfilesResponse={0};
result = soap_call___ns8__GetProfiles(soap, deviceode->mediauri, NULL, &getProfilesReq, &getProfilesResponse);
if(result==-1)
{
printf("soap error: %d, %s, %s\n", soap->error, *soap_faultcode(soap), *soap_faultstring(soap));
result = soap->error;
bret = FALSE;
}
else
{
if(getProfilesResponse.__sizeProfiles<=0)
{
printf(" GetProfiles failed! result=%d \n",result);
bret = FALSE;
}
else
{
printf(" GetProfiles OK! result=%d \n",result);
int i;
int count = getProfilesResponse.__sizeProfiles;
//printf(" getProfilesResponse.__sizeProfiles=%d \n", count);
for(i=0;i<2;i++)
{
#if 0
printf(" Profiles[%d]->Name=%s \n", i,getProfilesResponse.Profiles->Name);
printf(" Profiles[%d]->token=%s \n",i,getProfilesResponse.Profiles->token);
printf(" Profiles[%d]->fixed=%s \n", i,getProfilesResponse.Profiles->fixed);
printf(" Profiles[%d]->VideoEncoderConfiguration->Name=%s \n", i,getProfilesResponse.Profiles->VideoEncoderConfiguration->Name);
printf(" Profiles[%d]->VideoEncoderConfiguration->token=%s \n", i,getProfilesResponse.Profiles->VideoEncoderConfiguration->token);
printf(" Profiles[%d]->VideoEncoderConfiguration->Encoding=%d \n", i,getProfilesResponse.Profiles->VideoEncoderConfiguration->Encoding);
printf(" Profiles[%d]->VideoEncoderConfiguration->Resolution->Width=%d \n", i,getProfilesResponse.Profiles->VideoEncoderConfiguration->Resolution->Width);
printf(" Profiles[%d]->VideoEncoderConfiguration->Resolution->Height=%d \n", i,getProfilesResponse.Profiles->VideoEncoderConfiguration->Resolution->Height);
printf(" Profiles[%d]->VideoEncoderConfiguration->RateControl->FrameRateLimit=%d \n", i,getProfilesResponse.Profiles->VideoEncoderConfiguration->RateControl->FrameRateLimit);
printf(" Profiles[%d]->VideoEncoderConfiguration->RateControl->BitrateLimit=%d \n", i,getProfilesResponse.Profiles->VideoEncoderConfiguration->RateControl->BitrateLimit);
printf(" Profiles[%d]->VideoEncoderConfiguration->H264->H264Profile=%d \n", i,getProfilesResponse.Profiles->VideoEncoderConfiguration->H264->H264Profile);
#endif
PROFILE profile;
memset(&profile, 0, sizeof(PROFILE));
strncpy(profile.Name, getProfilesResponse.Profiles->Name, MAXSTRLEN);
strncpy(profile.token,getProfilesResponse.Profiles->token, MAXSTRLEN);
strncpy(profile.VideoEncoderConfigurationtoken,getProfilesResponse.Profiles->VideoEncoderConfiguration->token, MAXSTRLEN);
profile.Encoding = getProfilesResponse.Profiles->VideoEncoderConfiguration->Encoding;
profile.H264Profile = getProfilesResponse.Profiles->VideoEncoderConfiguration->H264->H264Profile;
profile.Width = getProfilesResponse.Profiles->VideoEncoderConfiguration->Resolution->Width;
profile.Height = getProfilesResponse.Profiles->VideoEncoderConfiguration->Resolution->Height;
profile.FrameRateLimit = getProfilesResponse.Profiles->VideoEncoderConfiguration->RateControl->FrameRateLimit;
profile.BitrateLimit = getProfilesResponse.Profiles->VideoEncoderConfiguration->RateControl->BitrateLimit;
profile.support = 0;
DLSetProfile(index, i, &profile);
//PrintfNodebyIndex(index);
getProfilesResponse.Profiles++; //???ò??????profile
}
bret = TRUE;
}
}
soap_end(soap);
return bret;
}
4 实际报文包
电脑IP 192.168.0.75,发出GetProfiles命令,网络摄像头应答。
略