GetCapabilities是向下兼容的接口只能获取到设备支持的最基本功能。GetServices接口能获取到设备支持的所有功能,H265格式的RTSP地址的获取必须通过该接口获得。
原文:
以获取H265的为例,需要onvif开发框架支持265,该环境搭建看参考6.1
void GetProfileUsedMedia2()
{
char media_addr2[] = "http://172.16.41.64/onvif/Media2"; //GetServices得到的地址
struct SOAP_ENV__Header header;
struct soap* soap = ONVIF_Initsoap(&header, NULL, NULL, 5);
struct _tr2__GetProfiles tr2__GetProfiles;
struct _tr2__GetProfilesResponse tr2__GetProfilesResponse;
tr2__GetProfiles.__sizeType = 1;
tr2__GetProfiles.Token = NULL;
char* type[1] = {"VideoEncoder"};
tr2__GetProfiles.Type = type;
ONVIF_SetAuthInfo(soap,user_name,passwd); //鉴权
soap_call___tr2__GetProfiles(soap, media_addr2, NULL, &tr2__GetProfiles, &tr2__GetProfilesResponse);
if(soap->error)
{
cout << "soap_call___tr2__GetProfiles main soap error:"<< soap->error << *soap_faultcode(soap) <<
*soap_faultstring(soap) << endl;
}
else
{
if(tr2__GetProfilesResponse.Profiles == NULL)
{
ret = -2;
}
else
{
//循环输出文件信息
for(int i = 0;i < tr2__GetProfilesResponse.__sizeProfiles;i++,tr2__GetProfilesResponse.Profiles++)
{
if(strstr(tr2__GetProfilesResponse.Profiles->Name,"test"))
continue;
string video_type = tr2__GetProfilesResponse.Profiles->Configurations->VideoEncoder->Encoding;
transform(video_type.begin(), video_type.end(), video_type.begin(), ::tolower);
cout << "===== 265 profile name " << tr2__GetProfilesResponse.Profiles->Name << " token " << tr2__GetProfilesResponse.Profiles->token
<< " video type " << video_type << endl;
}
}
}
ONVIF_soap_delete(soap);
}
以获取H265的为例,需要onvif开发框架支持265,该环境搭建看参考6.1, 同时也需要对应的IPC设备支持H265获取RTSP,大概是2018年年底之后的IPC固件才支持,如果IPC不支持是获取不到media2的
char media_addr2[] = "http://172.16.41.64/onvif/Media2"; //GetServices得到的地址
char taken[] = "Profile_1"; //get_profiles获取
struct SOAP_ENV__Header header;
struct soap* soap = ONVIF_Initsoap(&header, NULL, NULL, 5);
struct _tr2__GetStreamUri tr2__GetStreamUri;
struct _tr2__GetStreamUriResponse tr2__GetStreamUriResponse;
tr2__GetStreamUri.Protocol = (char *)soap_malloc(soap, 128*sizeof(char));
if (NULL == tr2__GetStreamUri.Protocol)
{
printf("soap_malloc is error\n");
ret = -1;
}
tr2__GetStreamUri.ProfileToken = (char *)soap_malloc(soap, 128*sizeof(char ));
if (NULL == tr2__GetStreamUri.ProfileToken)
{
printf("soap_malloc is error\n");
ret = -1;
}
strcpy(tr2__GetStreamUri.Protocol, "tcp");
strcpy(tr2__GetStreamUri.ProfileToken, taken);
ONVIF_SetAuthInfo(soap,user_name,passwd); //鉴权
soap_call___tr2__GetStreamUri(soap, media_addr2, NULL, &tr2__GetStreamUri, &tr2__GetStreamUriResponse);
if(soap->error)
{
cout << "soap_call___tr2__GetStreamUri main soap error:"<< soap->error << *soap_faultcode(soap) <<
*soap_faultstring(soap) << endl;
}
else
{
cout << "media2 MediaUri->Uri=" << tr2__GetStreamUriResponse.Uri << endl;
}
ONVIF_soap_delete(soap);
void ptzContinueMove(int cmd , int speed)
{
if(ptzurl.empty())
{
printf("ptzContinueMove ptzurl is empty \n");
return;
}
struct SOAP_ENV__Header header;
struct soap* soap = ONVIF_Initsoap(&header, NULL, NULL, 5);
const int RECV_MAX_TIME = 2;
soap->recv_timeout = RECV_MAX_TIME;
soap->send_timeout = RECV_MAX_TIME;
soap->connect_timeout = RECV_MAX_TIME;
int speed_x=0;
int speed_y=0;
int speed_z=0;
struct _tptz__ContinuousMove continuousMove;
struct _tptz__ContinuousMoveResponse continuousMoveresponse;
LONG64 timeout = 2;
continuousMove.Timeout = &timeout;
char ProfileToken[32] = {0};
strncpy(ProfileToken, "MainProfileToken", sizeof(ProfileToken));
continuousMove.ProfileToken = ProfileToken;
struct tt__PTZSpeed* velocity = (struct tt__PTZSpeed*)soap_malloc(soap, sizeof(struct tt__PTZSpeed));
continuousMove.Velocity = velocity;
struct tt__Vector2D* panTilt = (struct tt__Vector2D*)soap_malloc(soap, sizeof(struct tt__Vector2D));
continuousMove.Velocity->PanTilt = panTilt;
continuousMove.Velocity->PanTilt->space = NULL;
if(cmd >= PTZ_CMD_ZOOM_NEAR)
{
struct tt__Vector1D* zoom = (struct tt__Vector1D*)soap_malloc(soap, sizeof(struct tt__Vector1D));
continuousMove.Velocity->Zoom = zoom;
continuousMove.Velocity->PanTilt->x = (float)speed_x / 100;
continuousMove.Velocity->PanTilt->y = (float) speed_y / 100;
continuousMove.Velocity->Zoom->x = (float)speed_z / 100;
continuousMove.Velocity->Zoom->space = NULL;
}
switch (cmd)
{
case PTZ_CMD_LEFT:
continuousMove.Velocity->PanTilt->x = -((float)speed / 100);
break;
case PTZ_CMD_RIGHT:
continuousMove.Velocity->PanTilt->x = (float)speed / 100;
//continuousMove.Velocity->PanTilt->y = 0;
break;
case PTZ_CMD_UP:
//continuousMove.Velocity->PanTilt->x = 0;
continuousMove.Velocity->PanTilt->y = (float)speed / 100;
break;
case PTZ_CMD_DOWN:
//continuousMove.Velocity->PanTilt->x = 0;
continuousMove.Velocity->PanTilt->y = -((float)speed / 100);
break;
// 缩小
case PTZ_CMD_ZOOM_NEAR:
continuousMove.Velocity->Zoom->x = -((float)speed / 100);
break;
// 放大
case PTZ_CMD_ZOOM_FAR:
continuousMove.Velocity->Zoom->x = (float)speed / 100;
break;
default:
break;
}
char soap_endpoint[64] = {0};
sprintf(soap_endpoint, "%s", ptzurl.c_str());
printf("ptz_url: %s \n", soap_endpoint);
ONVIF_SetAuthInfo(soap, user_name, passwd); //鉴权
if(soap_call___tptz__ContinuousMove(soap, soap_endpoint, NULL, &continuousMove, &continuousMoveresponse) == SOAP_OK)
{
printf("======SetPTZcontinuous_move is success!!!=======\n");
}
else
{
printf("======SetPTZcontinuous_move is faile!!!=======\n");
printf("soap_call___tptz__ContinuousMove soap error: %d, %s, %s\n", soap->error, *soap_faultcode(soap), *soap_faultstring(soap));
}
ONVIF_soap_delete(soap);
}
《1》、Linux下onvi支持h264、h265环境的的搭建:gsoap的安装及生产.c .h文件
《2》、Linux下onvif客户端获取h265 IPC摄像头的RTSP地址
《3》、ONVIF Core Specification