ONVIF获取265的rtsp地址,ptz控制记录

1、获取url、ptz或imaging的一般流程

ONVIF获取265的rtsp地址,ptz控制记录_第1张图片

《1》、注意

  GetCapabilities是向下兼容的接口只能获取到设备支持的最基本功能。GetServices接口能获取到设备支持的所有功能,H265格式的RTSP地址的获取必须通过该接口获得。
原文:
ONVIF获取265的rtsp地址,ptz控制记录_第2张图片

《2》、onvif test工具的对比

ONVIF获取265的rtsp地址,ptz控制记录_第3张图片
ONVIF获取265的rtsp地址,ptz控制记录_第4张图片

2、获取profiles

  以获取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);
}

3、获取rtsp地址

  以获取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);

4、PTZ持续移动

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);

}

5、完整demo

6、参考

《1》、Linux下onvi支持h264、h265环境的的搭建:gsoap的安装及生产.c .h文件
《2》、Linux下onvif客户端获取h265 IPC摄像头的RTSP地址
《3》、ONVIF Core Specification

你可能感兴趣的:(onvif,流媒体)