Linux下onvif客户端获取h265 IPC摄像头的RTSP地址

onvif:ONVIF的目标是为了实现完全标准化的、可互操作性的网络视频服务,即使是由不同的网络视频供应商组成的产品。规范描述了网络视频模型,接口,数据类型和数据交换模式。ONVIF规范中设备管理和控制部分所定义的接口均以Web Services的形式提供。为了引进网络视频服务,ONVIF规范包含了所有的XML及WSDL(Wed Service Description Language)的定义。

为了达到完全的即插即用的操作性能,该标准定义了设备发现的规范。ONVIF中设备发现机制可看作是WS-Discovery的延伸。ONVIF规范不仅具有设备的发现,配置和控制功能,而且在IP网络方面,ONVIF也为媒体和元数据流定义了严格的格式。

该框架涵盖不同网络视频环境下的各个阶段,从网络视频设备部署和配置阶段到实时流处理阶段。

这个规范涵盖了设备发现、设备配置、事件、PTZ控制、视频分析和实时流媒体直播功能,以及搜索,回放和录像录音管理功能。所有的服务使用同一种的XML schema(XML文档的结构),所用到的数据类型都在“ONVIF schema”中定义。

从onvif中获取RTSP地址一般流程:

  • 摄像头ipc的搜索输入摄像头ip地址,获取ipc web的服务地址,如:http://172.168.0.216/onvif/device_service
  • GetCapabilities输入pc web的服务地址,获取摄像头ipc的媒体地址,如:http://172.168.0.216/onvif/media_service
  • GetServices输入ipc web的服务地址,获取完整的摄像头ipc的媒体地址,这步会直接获得两个媒体地址,其中一个是GetCapabilities已经获取到的,一般是h264的地址,另外一个是h265的媒体地址。如:http://172.168.0.216/onvif/media_service、ttp://172.168.0.216/onvif/media2_service
  • GetProfiles输入ipc的媒体地址,获取一个token值,如:Profile000
  • GetStreamUri输入一个token值,得到rtsp地址

ps:当我们在获取h265的rtsp地址时,有些h265的摄像头在获取GetServices,得到1个h264的媒体地址和一个h265媒体地址,一般我们用h265的媒体地址,就可以获取到rtsp地址。但是有些摄像头比较奇葩,h265的媒体地址虽然获取到了,但是用h265的相应的 tr2 接口是获取不到信息的,比如在获取token值和获取uri值的,这个时候要用h264的 trt 接口才能获取的到。

1. 设备搜索,去获取webserver 的地址 demo:https://blog.csdn.net/weixin_42432281/article/details/88698723

2. GetCapabilities获取能力demo:https://blog.csdn.net/weixin_42432281/article/details/88715196

从 Response结构体中取得媒体地址:如果GetCapabilities获取能力失败,soap error 4 或者 52的话,可以参考一下以下链接:   https://blog.csdn.net/weixin_42432281/article/details/85158378

    char sercer_addr[] = "http://172.168.0.211/onvif/device_service";//设备搜索获取到的地址
    struct SOAP_ENV__Header header;
    struct soap* soap = ONVIF_Initsoap(&header, NULL, NULL, 5);
    struct _tds__GetCapabilities *req;
    struct _tds__GetCapabilitiesResponse *Response;

    req->__sizeCategory = 1;
    req->Category = (enum tt__CapabilityCategory *)soap_malloc(soap, sizeof(int));
    *(req->Category) = (enum tt__CapabilityCategory)5; //5表示:tt__CapabilityCategory__Media

    ONVIF_SetAuthInfo(soap,"admin","123456");  //鉴权,输入摄像头的用户名、密码
    ret = soap_call___tds__GetCapabilities(soap, sercer_addr, NULL,req, Response);

3 .GetServices获取多个媒体地址 demo:https://blog.csdn.net/weixin_42432281/article/details/88717321

要是在获取GetProfiles时,用第二步的媒体地址不支持h265,那么你就需要调用这个接口。在这个接口的tds__GetServicesResponse结构体中可以获取两个媒体地址  。要是之前没有安装h265的gsoap环境,这边也是只能获取一个媒体地址,安装h265的环境请查看上一篇的文章 :Linux下onvi支持h265环境的的搭建 ,“https://blog.csdn.net/weixin_42432281/article/details/84818575”

    char secvre_addr[] = "http://172.168.0.211/onvif/device_service"; //设备搜索获取得到的服务地址
    struct SOAP_ENV__Header header;
    struct _tds__GetServices *tds__GetServices;
    struct _tds__GetServicesResponse *tds__GetServicesResponse;
 
    struct soap* soap = ONVIF_Initsoap(&header, NULL, NULL, 5);
    
    tds__GetServices->IncludeCapability = 0;
 
    ONVIF_SetAuthInfo(soap,"admin","123456");  //鉴权
    soap_call___tds__GetServices(soap,secvre_addr,NULL, tds__GetServices, tds__GetServicesResponse);

4. GetProfiles 获取媒体信息文件 demo:https://blog.csdn.net/weixin_42432281/article/details/88718090

从tr2__GetProfilesResponse结构体获取媒体信息文件,soap_call___tr2__GetProfiles接口是安装h265的环境时,gsoap框架所生成的接口。(ps:当然这个GetProfiles接口很有可能会出现soap error: 52, (null), (null)的问题,尤其是大华的摄像头,后面会更新怎么解决它。)

    char media_addr2[] = "http://172.168.0.211/onvif/media2_service"; //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;  
    tr2__GetProfiles.Type = NULL;
    ONVIF_SetAuthInfo(soap,"admin","123456");  //鉴权
    soap_call___tr2__GetProfiles(soap, media_addr2, NULL, &tr2__GetProfiles, &tr2__GetProfilesResponse);   

5. GetStreamUri 获取RTSP地址 demo:https://blog.csdn.net/weixin_42432281/article/details/88725790

从tr2__GetStreamUriResponse结构体中获取h265的RTSP地址,soap_call___tr2__GetStreamUri接口是安装h265的环境时,gsoap框架所生成的接口。

    char media_addr2[] = "http://172.168.0.211/onvif/media2_service"; //GetServices得到的地址
    char taken[] = "Profile000";   //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,"admin","123456");  //鉴权
	soap_call___tr2__GetStreamUri(soap, media_addr2, NULL, &tr2__GetStreamUri, &tr2__GetStreamUriResponse); 
 

 

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