基于onvif规范的视频监控系统客户端(三):自动搜索设备,获得连接在局域网内的摄像头的rtsp地址


注: 本文提供的参考代码其实网上都可以找到,这里做一个整理,供大家交流学习,共同提高。

搜索: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

你可能感兴趣的:(视频监控)