天天看點

Onvif開發之服務端成功對接Rtsp視訊流篇

前面篇介紹onvif服務端的發現功能,繼續在之前的代碼基礎上完成一個RTSP流的工作,也就是用戶端通過ONVIF協定來預覽裝置端

在這個之前必須确定幾個簡單的條件

1 裝置端能被發現

2 裝置端支援RTSP協定,并且能夠通過VLC進行正常的預覽

通過onvif協定裝置需要做的幾個基本事情:

1  __tds__GetCapabilities擷取裝置能力

2  __trt__GetProfiles擷取裝置的配置資訊

3  擷取前段裝置的視訊編碼和視訊源的一些基本需要的資訊

4 __trt__GetStreamUri後去裝置的URi,通過RTSP擷取視訊流

接口函數有了,實作的時候當然也需要注意比對,需要把裝置的一些主要資訊對應比對到Onvif協定中,下面一個函數一個函數的具體實作如下,在需要注意的地方我都加上了對應的注釋,如果還有不清楚的地方可以留言,我會盡量盡我所知道的告訴大家

1 __tds__GetCapabilities,此函數是擷取裝置端的能力的函數,在這裡需要預覽,是以基本的media和device的一些基本資訊是需要填寫的

Onvif開發之服務端成功對接Rtsp視訊流篇

Capabilities__Device_Choice:  

    tds__GetCapabilitiesResponse->Capabilities->Device = (struct tt__DeviceCapabilities *)soap_malloc(soap,sizeof(struct tt__DeviceCapabilities));  

    memset(tds__GetCapabilitiesResponse->Capabilities->Device, 0, sizeof(struct tt__DeviceCapabilities));  

    tds__GetCapabilitiesResponse->Capabilities->Device->XAddr = (char *)soap_malloc(soap, sizeof(char) * MAX_64_LEN );  

    memset(tds__GetCapabilitiesResponse->Capabilities->Device->XAddr, 0, sizeof(char) * MAX_64_LEN);  

     //填寫裝置的ip位址以及需要通過onvif協定通信的端口号  

    sprintf(tds__GetCapabilitiesResponse->Capabilities->Device->XAddr, "%s/onvif/device_service", "192.168.12.135:8899");  

    //裝置的一些基本能力值,是否支援那些功能,如果在開發的時候,如果前段裝置支援這些功能的話,就可以直接填寫true,否則填寫false  

    tds__GetCapabilitiesResponse->Capabilities->Device->Network = (struct tt__NetworkCapabilities *)soap_malloc(soap, sizeof(struct tt__NetworkCapabilities ));  

    memset(tds__GetCapabilitiesResponse->Capabilities->Device->Network, 0, sizeof(struct tt__NetworkCapabilities ));  

    tds__GetCapabilitiesResponse->Capabilities->Device->Network->IPFilter = (enum xsd__boolean *)soap_malloc(soap, sizeof(enum xsd__boolean));  

    *(tds__GetCapabilitiesResponse->Capabilities->Device->Network->IPFilter) = xsd__boolean__false_; // xsd__boolean__true_   

    tds__GetCapabilitiesResponse->Capabilities->Device->Network->ZeroConfiguration= (enum xsd__boolean *)soap_malloc(soap, sizeof(enum xsd__boolean));  

    *(tds__GetCapabilitiesResponse->Capabilities->Device->Network->ZeroConfiguration) = xsd__boolean__true_; // xsd__boolean__false_   

    tds__GetCapabilitiesResponse->Capabilities->Device->Network->IPVersion6 = (enum xsd__boolean *)soap_malloc(soap, sizeof(enum xsd__boolean));  

    *(tds__GetCapabilitiesResponse->Capabilities->Device->Network->IPVersion6) = xsd__boolean__false_; // xsd__boolean__true_   

    tds__GetCapabilitiesResponse->Capabilities->Device->Network->DynDNS = (enum xsd__boolean *)soap_malloc(soap, sizeof(enum xsd__boolean));  

    *(tds__GetCapabilitiesResponse->Capabilities->Device->Network->DynDNS) = xsd__boolean__true_; // xsd__boolean__false_   

    tds__GetCapabilitiesResponse->Capabilities->Device->System = (struct tt__SystemCapabilities *)soap_malloc(soap, sizeof(struct tt__SystemCapabilities));  

    memset( tds__GetCapabilitiesResponse->Capabilities->Device->System, 0, sizeof(struct tt__SystemCapabilities));  

    tds__GetCapabilitiesResponse->Capabilities->Device->System->DiscoveryResolve = xsd__boolean__true_;   

    tds__GetCapabilitiesResponse->Capabilities->Device->System->DiscoveryBye     = xsd__boolean__true_;   

    tds__GetCapabilitiesResponse->Capabilities->Device->System->RemoteDiscovery  = xsd__boolean__false_;   

    tds__GetCapabilitiesResponse->Capabilities->Device->System->SystemBackup     = xsd__boolean__false_;   

    tds__GetCapabilitiesResponse->Capabilities->Device->System->SystemLogging    = xsd__boolean__false_;   

    tds__GetCapabilitiesResponse->Capabilities->Device->System->FirmwareUpgrade  = xsd__boolean__false_;   

    tds__GetCapabilitiesResponse->Capabilities->Device->System->__sizeSupportedVersions = 1;   

    tds__GetCapabilitiesResponse->Capabilities->Device->System->SupportedVersions = (struct tt__OnvifVersion *)soap_malloc(soap, sizeof(struct tt__OnvifVersion));    

    tds__GetCapabilitiesResponse->Capabilities->Device->System->SupportedVersions->Major = 2;   

    tds__GetCapabilitiesResponse->Capabilities->Device->System->SupportedVersions->Minor = 0;   

      // 裝置IO的一些支援  

    tds__GetCapabilitiesResponse->Capabilities->Device->IO = (struct tt__IOCapabilities *)soap_malloc(soap, sizeof(struct tt__IOCapabilities));  

    memset(tds__GetCapabilitiesResponse->Capabilities->Device->IO, 0, sizeof(struct tt__IOCapabilities));  

    tds__GetCapabilitiesResponse->Capabilities->Device->IO->InputConnectors = (int *)soap_malloc(soap, sizeof(int));   

    *(tds__GetCapabilitiesResponse->Capabilities->Device->IO->InputConnectors) = 1;   

    tds__GetCapabilitiesResponse->Capabilities->Device->IO->RelayOutputs = (int *)soap_malloc(soap, sizeof(int));   

    *(tds__GetCapabilitiesResponse->Capabilities->Device->IO->RelayOutputs) = 1;   

    tds__GetCapabilitiesResponse->Capabilities->Device->Security = (struct tt__SecurityCapabilities *)soap_malloc(soap, sizeof(struct tt__SecurityCapabilities));  

    memset(tds__GetCapabilitiesResponse->Capabilities->Device->Security, 0, sizeof(struct tt__SecurityCapabilities));  

    tds__GetCapabilitiesResponse->Capabilities->Device->Security->TLS1_x002e1          = xsd__boolean__false_;  

    tds__GetCapabilitiesResponse->Capabilities->Device->Security->TLS1_x002e2          = xsd__boolean__false_;  

    tds__GetCapabilitiesResponse->Capabilities->Device->Security->OnboardKeyGeneration = xsd__boolean__false_;  

    tds__GetCapabilitiesResponse->Capabilities->Device->Security->AccessPolicyConfig   = xsd__boolean__false_;  

    tds__GetCapabilitiesResponse->Capabilities->Device->Security->X_x002e509Token      = xsd__boolean__false_;  

    tds__GetCapabilitiesResponse->Capabilities->Device->Security->SAMLToken            = xsd__boolean__false_;  

    tds__GetCapabilitiesResponse->Capabilities->Device->Security->KerberosToken        = xsd__boolean__false_;  

    tds__GetCapabilitiesResponse->Capabilities->Device->Security->RELToken             = xsd__boolean__false_;  

Capabilities__Imaging_Choice:  

     //Imaging的一些基本資訊,關于視訊顔色,IRCut的一些基本資訊  

    tds__GetCapabilitiesResponse->Capabilities->Imaging = (struct tt__ImagingCapabilities *)soap_malloc(soap,sizeof(struct tt__ImagingCapabilities));  

    memset(tds__GetCapabilitiesResponse->Capabilities->Imaging, 0, sizeof(struct tt__ImagingCapabilities));  

    tds__GetCapabilitiesResponse->Capabilities->Imaging->XAddr = (char *)soap_malloc(soap, sizeof(char) * MAX_64_LEN );  

    memset(tds__GetCapabilitiesResponse->Capabilities->Imaging->XAddr, '\0', sizeof(char) * MAX_64_LEN);  

    sprintf(tds__GetCapabilitiesResponse->Capabilities->Imaging->XAddr, "%s/onvif/imaging_service","192.168.12.135:8899");  

Capabilities__Media__Choice:  

    tds__GetCapabilitiesResponse->Capabilities->Media = (struct tt__MediaCapabilities *)soap_malloc(soap,sizeof(struct tt__MediaCapabilities));  

    memset(tds__GetCapabilitiesResponse->Capabilities->Media, 0, sizeof(struct tt__MediaCapabilities));  

    tds__GetCapabilitiesResponse->Capabilities->Media->XAddr = (char *)soap_malloc(soap, sizeof(char) * MAX_64_LEN );  

    memset(tds__GetCapabilitiesResponse->Capabilities->Media->XAddr, 0, sizeof(char) * MAX_64_LEN);  

    sprintf(tds__GetCapabilitiesResponse->Capabilities->Media->XAddr, "%s/onvif/media_service", "192.168.12.135:8899");  

    tds__GetCapabilitiesResponse->Capabilities->Media->StreamingCapabilities = (struct tt__RealTimeStreamingCapabilities *)soap_malloc(soap,   

            sizeof(struct tt__RealTimeStreamingCapabilities));  

    memset(tds__GetCapabilitiesResponse->Capabilities->Media->StreamingCapabilities, 0, sizeof(struct tt__RealTimeStreamingCapabilities));  

    tds__GetCapabilitiesResponse->Capabilities->Media->StreamingCapabilities->RTPMulticast   = (enum xsd__boolean *)soap_malloc(soap,sizeof(int));  

    *tds__GetCapabilitiesResponse->Capabilities->Media->StreamingCapabilities->RTPMulticast  = xsd__boolean__false_;  

    tds__GetCapabilitiesResponse->Capabilities->Media->StreamingCapabilities->RTP_USCORETCP  = (enum xsd__boolean*)soap_malloc(soap,sizeof(int));  

    *tds__GetCapabilitiesResponse->Capabilities->Media->StreamingCapabilities->RTP_USCORETCP = xsd__boolean__true_;  

    tds__GetCapabilitiesResponse->Capabilities->Media->StreamingCapabilities->RTP_USCORERTSP_USCORETCP = (enum xsd__boolean*)soap_malloc(soap,sizeof(int));  

    *tds__GetCapabilitiesResponse->Capabilities->Media->StreamingCapabilities->RTP_USCORERTSP_USCORETCP = xsd__boolean__true_;  

2 __tds__GetServices函數的一些基本資訊的填寫

Onvif開發之服務端成功對接Rtsp視訊流篇

tds__GetServicesResponse->__sizeService = 1;  

tds__GetServicesResponse->Service = (struct tds__Service *)soap_malloc(soap, sizeof(struct tds__Service));  

tds__GetServicesResponse->Service[0].Namespace = (char *)soap_malloc(soap, sizeof(char)* INFO_LENGTH);  

strcpy(tds__GetServicesResponse->Service[0].Namespace, "http://www.onvif.org/ver10/events/wsdl");  

tds__GetServicesResponse->Service[0].XAddr     = (char *)soap_malloc(soap, sizeof(char)* INFO_LENGTH);  

strcpy(tds__GetServicesResponse->Service[0].XAddr, "http://192.168.12.135/onvif/services");  

tds__GetServicesResponse->Service[0].Capabilities = NULL;  

tds__GetServicesResponse->Service[0].Version = (struct tt__OnvifVersion *)soap_malloc(soap, sizeof(struct tt__OnvifVersion));  

tds__GetServicesResponse->Service[0].Version->Major = 0;  

tds__GetServicesResponse->Service[0].Version->Minor = 3;  

tds__GetServicesResponse->Service[0].__size = 0;  

tds__GetServicesResponse->Service[0].__any = NULL;  

tds__GetServicesResponse->Service[0].__anyAttribute = NULL;  

3  __trt__GetProfiles擷取裝置的配置資訊

Onvif開發之服務端成功對接Rtsp視訊流篇

        // VideoSourceConfiguration   

        trt__GetProfilesResponse->Profiles[i].Name = (char *)soap_malloc(soap, sizeof(char)*MAX_PROF_TOKEN);  

        memset(trt__GetProfilesResponse->Profiles[i].Name, '\0', sizeof(char)*MAX_PROF_TOKEN);  

        //profiles的名字,和token不同,實際請求的時候都是需要對應的token值來擷取的  

        strcpy(trt__GetProfilesResponse->Profiles[i].Name, "test_profile");  

        trt__GetProfilesResponse->Profiles[i].token = (char *)soap_malloc(soap, sizeof(char)*MAX_PROF_TOKEN);  

        memset(trt__GetProfilesResponse->Profiles[i].token, '\0', sizeof(char)*MAX_PROF_TOKEN);  

        //此token也就是每次需要擷取對應profiles的一些資訊的時候,就需要在請求的時候填寫此對應的token來,來進行驗證判斷   

        strcpy(trt__GetProfilesResponse->Profiles[i].token, "test_token");  

        trt__GetProfilesResponse->Profiles[i].fixed = (enum xsd__boolean *)soap_malloc(soap, sizeof(int));  

        memset(trt__GetProfilesResponse->Profiles[i].fixed, 0, sizeof(int));  

        *(trt__GetProfilesResponse->Profiles[i].fixed) = (enum xsd__boolean )0;  

        trt__GetProfilesResponse->Profiles[i].__anyAttribute = NULL;  

        trt__GetProfilesResponse->Profiles[i].VideoSourceConfiguration = (struct tt__VideoSourceConfiguration *)soap_malloc(soap,sizeof(struct tt__VideoSourceConfiguration));  

        memset(trt__GetProfilesResponse->Profiles[i].VideoSourceConfiguration, 0, sizeof(struct tt__VideoSourceConfiguration));  

        trt__GetProfilesResponse->Profiles[i].VideoSourceConfiguration->Name = (char *)soap_malloc(soap,sizeof(char) * MAX_PROF_TOKEN);  

        memset(trt__GetProfilesResponse->Profiles[i].VideoSourceConfiguration->Name, '\0', sizeof(char) * MAX_PROF_TOKEN);  

        // 類似與上面,VideoSource Name,  

        strcpy(trt__GetProfilesResponse->Profiles[i].VideoSourceConfiguration->Name, "test_vsname");  

        trt__GetProfilesResponse->Profiles[i].VideoSourceConfiguration->token = (char *)soap_malloc(soap,sizeof(char) * MAX_PROF_TOKEN);  

        memset(trt__GetProfilesResponse->Profiles[i].VideoSourceConfiguration->token, '\0', sizeof(char) * MAX_PROF_TOKEN);  

        //求不同碼流的視訊源資訊需要此token值比對  

        strcpy(trt__GetProfilesResponse->Profiles[i].VideoSourceConfiguration->token, "test_vsoken");  

        trt__GetProfilesResponse->Profiles[i].VideoSourceConfiguration->SourceToken = (char *)soap_malloc(soap,sizeof(char) * MAX_PROF_TOKEN);  

        memset(trt__GetProfilesResponse->Profiles[i].VideoSourceConfiguration->SourceToken, '\0', sizeof(char) * MAX_PROF_TOKEN);  

        strcpy(trt__GetProfilesResponse->Profiles[i].VideoSourceConfiguration->SourceToken, "test_vstoken");   

        trt__GetProfilesResponse->Profiles[i].VideoSourceConfiguration->UseCount = 1;   

        trt__GetProfilesResponse->Profiles[i].VideoSourceConfiguration->Bounds = (struct tt__IntRectangle *)soap_malloc(soap, sizeof(struct tt__IntRectangle));   

        memset(trt__GetProfilesResponse->Profiles[i].VideoSourceConfiguration->Bounds, 0, sizeof(struct tt__IntRectangle));   

        trt__GetProfilesResponse->Profiles[i].VideoSourceConfiguration->Bounds->x = 0;   

        trt__GetProfilesResponse->Profiles[i].VideoSourceConfiguration->Bounds->y = 0;   

        trt__GetProfilesResponse->Profiles[i].VideoSourceConfiguration->Bounds->width = 1280;   

        trt__GetProfilesResponse->Profiles[i].VideoSourceConfiguration->Bounds->height = 720;   

        // VideoEncoderConfiguration   

        trt__GetProfilesResponse->Profiles[i].VideoEncoderConfiguration = (struct tt__VideoEncoderConfiguration *)soap_malloc(soap, sizeof(struct tt__VideoEncoderConfiguration)) ;  

        memset(trt__GetProfilesResponse->Profiles[i].VideoEncoderConfiguration, '\0', sizeof(struct tt__VideoEncoderConfiguration));   

        trt__GetProfilesResponse->Profiles[i].VideoEncoderConfiguration->Name = (char *)soap_malloc(soap, sizeof(char)*MAX_PROF_TOKEN);   

        memset(trt__GetProfilesResponse->Profiles[i].VideoEncoderConfiguration->Name, '\0', sizeof(char)*MAX_PROF_TOKEN);   

        strcpy(trt__GetProfilesResponse->Profiles[i].VideoEncoderConfiguration->Name, "test_vename");   

        trt__GetProfilesResponse->Profiles[i].VideoEncoderConfiguration->token = (char *)soap_malloc(soap, sizeof(char)*MAX_PROF_TOKEN);   

        memset(trt__GetProfilesResponse->Profiles[i].VideoEncoderConfiguration->token, '\0', sizeof(char)*MAX_PROF_TOKEN);   

        strcpy(trt__GetProfilesResponse->Profiles[i].VideoEncoderConfiguration->token, "test_vstoken");   

        trt__GetProfilesResponse->Profiles[i].VideoEncoderConfiguration->UseCount = 1;   

       //當然在實際開發的過程中最好把單個也實作了,也就是__trt__GetProfile函數接口,此接口是根據對應的請求的token來擷取對應的資訊的!  

4  視訊源已經視訊編碼必須填充的一些基本需要填寫的一些關鍵資訊

     (1)__trt__GetVideoEncoderConfiguration函數接口一些主要資訊

Onvif開發之服務端成功對接Rtsp視訊流篇

//請求的時候需要比對的一些基本資訊  

trt__GetVideoEncoderConfigurationResponse->Configuration->Name = (char *)soap_malloc(soap, sizeof(char)*MAX_PROF_TOKEN);  

memset(trt__GetVideoEncoderConfigurationResponse->Configuration->Name, '\0', sizeof(char)*MAX_PROF_TOKEN);  

strcpy(trt__GetVideoEncoderConfigurationResponse->Configuration->Name, "test_vsname");  

trt__GetVideoEncoderConfigurationResponse->Configuration->token = (char *)soap_malloc(soap, sizeof(char)*MAX_PROF_TOKEN);  

memset(trt__GetVideoEncoderConfigurationResponse->Configuration->token, '\0', sizeof(char)*MAX_PROF_TOKEN);  

strcpy(trt__GetVideoEncoderConfigurationResponse->Configuration->token, "test_vstoken");  

trt__GetVideoEncoderConfigurationResponse->Configuration->UseCount = 1;  

trt__GetVideoEncoderConfigurationResponse->Configuration->Quality = 100;  

//根據前端裝置時間支援的編碼格式選擇對應的值,因為我測試的是裝置隻支援H264 ,是以選了2  

trt__GetVideoEncoderConfigurationResponse->Configuration->Encoding = (enum tt__VideoEncoding) 2;   // JPEG = 0 , MPEG = 1, H264 = 2;   

trt__GetVideoEncoderConfigurationResponse->Configuration->Resolution = (struct tt__VideoResolution *)soap_malloc(soap,sizeof(struct tt__VideoResolution));  

memset(trt__GetVideoEncoderConfigurationResponse->Configuration->Resolution, 0 , sizeof(struct tt__VideoResolution));  

// 請求的視訊的分辨率,對應前端裝置填寫對應的值,我這是1280 * 720  

trt__GetVideoEncoderConfigurationResponse->Configuration->Resolution->Width  = 1280;  

trt__GetVideoEncoderConfigurationResponse->Configuration->Resolution->Height = 720;  

trt__GetVideoEncoderConfigurationResponse->Configuration->RateControl = (struct tt__VideoRateControl *)soap_malloc(soap, sizeof(struct tt__VideoRateControl));  

memset(trt__GetVideoEncoderConfigurationResponse->Configuration->RateControl, 0, sizeof(struct tt__VideoRateControl));  

//請求的對應的編碼資訊.各個意思參考上面說明  

trt__GetVideoEncoderConfigurationResponse->Configuration->RateControl->FrameRateLimit   = 30;  

trt__GetVideoEncoderConfigurationResponse->Configuration->RateControl->EncodingInterval = 1;  

trt__GetVideoEncoderConfigurationResponse->Configuration->RateControl->BitrateLimit     =2048;  

trt__GetVideoEncoderConfigurationResponse->Configuration->H264 = (struct tt__H264Configuration *)soap_malloc(soap, sizeof(struct tt__H264Configuration));  

memset(trt__GetVideoEncoderConfigurationResponse->Configuration->H264, 0, sizeof(struct tt__H264Configuration));  

trt__GetVideoEncoderConfigurationResponse->Configuration->H264->GovLength  = 30;  

trt__GetVideoEncoderConfigurationResponse->Configuration->H264->H264Profile = (enum tt__H264Profile)3;  

  (2)__trt__GetVideoEncoderConfigurations函數接口一些主要資訊   

Onvif開發之服務端成功對接Rtsp視訊流篇

trt__GetVideoEncoderConfigurationsResponse->Configurations[0].Name = (char *)soap_malloc(soap, sizeof(char)*MAX_PROF_TOKEN);           

memset(trt__GetVideoEncoderConfigurationsResponse->Configurations[0].Name, '\0', sizeof(char)*MAX_PROF_TOKEN);  

strcpy(trt__GetVideoEncoderConfigurationsResponse->Configurations[0].Name, "test_vsname");  

trt__GetVideoEncoderConfigurationsResponse->Configurations[0].token = (char *)soap_malloc(soap, sizeof(char)*MAX_PROF_TOKEN);  

memset(trt__GetVideoEncoderConfigurationsResponse->Configurations[0].token, '\0', sizeof(char)*MAX_PROF_TOKEN);   

//請求的token值  

strcpy(trt__GetVideoEncoderConfigurationsResponse->Configurations[0].token, "test_vstoken");  

trt__GetVideoEncoderConfigurationsResponse->Configurations[0].UseCount = 1;  

trt__GetVideoEncoderConfigurationsResponse->Configurations[0].Quality = 100;  

trt__GetVideoEncoderConfigurationsResponse->Configurations[0].Encoding = (enum tt__VideoEncoding) 2;   // JPEG = 0 , MPEG = 1, H264 = 2;        

trt__GetVideoEncoderConfigurationsResponse->Configurations[0].Resolution = (struct tt__VideoResolution *)soap_malloc(soap,sizeof(struct tt__VideoResolution));  

memset(trt__GetVideoEncoderConfigurationsResponse->Configurations[0].Resolution, 0 , sizeof(struct tt__VideoResolution));  

trt__GetVideoEncoderConfigurationsResponse->Configurations[0].Resolution->Width  = 1280;  

trt__GetVideoEncoderConfigurationsResponse->Configurations[0].Resolution->Height = 720;  

trt__GetVideoEncoderConfigurationsResponse->Configurations[0].RateControl = (struct tt__VideoRateControl *)soap_malloc(soap, sizeof(struct tt__VideoRateControl));  

memset(trt__GetVideoEncoderConfigurationsResponse->Configurations[0].RateControl, 0, sizeof(struct tt__VideoRateControl));  

//請求的視訊資料的一些編碼資訊  

trt__GetVideoEncoderConfigurationsResponse->Configurations[0].RateControl->FrameRateLimit   = 30;  

trt__GetVideoEncoderConfigurationsResponse->Configurations[0].RateControl->EncodingInterval = 1;  

trt__GetVideoEncoderConfigurationsResponse->Configurations[0].RateControl->BitrateLimit     = 2048;  

trt__GetVideoEncoderConfigurationsResponse->Configurations[0].H264 = (struct tt__H264Configuration *)soap_malloc(soap, sizeof(struct tt__H264Configuration));  

memset(trt__GetVideoEncoderConfigurationsResponse->Configurations[0].H264, 0, sizeof(struct tt__H264Configuration));  

trt__GetVideoEncoderConfigurationsResponse->Configurations[0].H264->GovLength  = 30;  

trt__GetVideoEncoderConfigurationsResponse->Configurations[0].H264->H264Profile = (enum tt__H264Profile)3;  

   (3)__trt__GetVideoSourceConfiguration需要填寫的一些基本資訊  

Onvif開發之服務端成功對接Rtsp視訊流篇

trt__GetVideoSourceConfigurationResponse->Configuration->UseCount = 1;  

trt__GetVideoSourceConfigurationResponse->Configuration->Name = (char*)soap_malloc(soap, sizeof(char) * MAX_PROF_TOKEN);  

memset(trt__GetVideoSourceConfigurationResponse->Configuration->Name, '\0', sizeof(char) * MAX_PROF_TOKEN);  

strcpy(trt__GetVideoSourceConfigurationResponse->Configuration->Name, "test_vsname");  

trt__GetVideoSourceConfigurationResponse->Configuration->token = (char*)soap_malloc(soap, sizeof(char) * MAX_PROF_TOKEN);  

memset(trt__GetVideoSourceConfigurationResponse->Configuration->token, '\0', sizeof(char) * MAX_PROF_TOKEN);  

strcpy(trt__GetVideoSourceConfigurationResponse->Configuration->token, "test_vstoken");  

trt__GetVideoSourceConfigurationResponse->Configuration->SourceToken = (char*)soap_malloc(soap, sizeof(char) * MAX_PROF_TOKEN);  

memset(trt__GetVideoSourceConfigurationResponse->Configuration->SourceToken, '\0', sizeof(char) * MAX_PROF_TOKEN);  

strcpy(trt__GetVideoSourceConfigurationResponse->Configuration->SourceToken, "test_vstoken");  

trt__GetVideoSourceConfigurationResponse->Configuration->Bounds = (struct tt__IntRectangle *)soap_malloc(soap, sizeof(struct tt__IntRectangle));  

memset(trt__GetVideoSourceConfigurationResponse->Configuration->Bounds, 0, sizeof(struct tt__IntRectangle));  

trt__GetVideoSourceConfigurationResponse->Configuration->Bounds->x      = 0;  

trt__GetVideoSourceConfigurationResponse->Configuration->Bounds->y      = 0;  

trt__GetVideoSourceConfigurationResponse->Configuration->Bounds->width  = 1280;  

trt__GetVideoSourceConfigurationResponse->Configuration->Bounds->height = 720;  

    (4)__trt__GetVideoSourceConfigurations需要填寫的一些基本資訊

Onvif開發之服務端成功對接Rtsp視訊流篇

trt__GetVideoSourceConfigurationsResponse->Configurations[0].UseCount = 1;  

trt__GetVideoSourceConfigurationsResponse->Configurations[0].Name = (char*)soap_malloc(soap, sizeof(char) * MAX_PROF_TOKEN);  

memset(trt__GetVideoSourceConfigurationsResponse->Configurations[0].Name, '\0', sizeof(char) * MAX_PROF_TOKEN);  

strcpy(trt__GetVideoSourceConfigurationsResponse->Configurations[0].Name, "test_vsname");  

trt__GetVideoSourceConfigurationsResponse->Configurations[0].token = (char*)soap_malloc(soap, sizeof(char) * MAX_PROF_TOKEN);  

memset(trt__GetVideoSourceConfigurationsResponse->Configurations[0].token, '\0', sizeof(char) * MAX_PROF_TOKEN);  

strcpy(trt__GetVideoSourceConfigurationsResponse->Configurations[0].token, "test_vstoken");  

trt__GetVideoSourceConfigurationsResponse->Configurations[0].SourceToken = (char*)soap_malloc(soap, sizeof(char) * MAX_PROF_TOKEN);  

memset(trt__GetVideoSourceConfigurationsResponse->Configurations[0].SourceToken, '\0', sizeof(char) * MAX_PROF_TOKEN);  

strcpy(trt__GetVideoSourceConfigurationsResponse->Configurations[0].SourceToken, "test_vstoken");  

trt__GetVideoSourceConfigurationsResponse->Configurations[0].Bounds = (struct tt__IntRectangle *)soap_malloc(soap, sizeof(struct tt__IntRectangle));  

memset(trt__GetVideoSourceConfigurationsResponse->Configurations[0].Bounds, 0, sizeof(struct tt__IntRectangle));  

trt__GetVideoSourceConfigurationsResponse->Configurations[0].Bounds->x      = 0;  

trt__GetVideoSourceConfigurationsResponse->Configurations[0].Bounds->y      = 0;  

trt__GetVideoSourceConfigurationsResponse->Configurations[0].Bounds->width  = 1280;  

trt__GetVideoSourceConfigurationsResponse->Configurations[0].Bounds->height = 720;  

這裡裡面本來都是一些個不相同的,通過對應不同的Token值來擷取不同的視訊源以及視訊編碼的一些資訊的,因為這裡我隻是一個簡單的測試,是以都是對單一的視訊碼流填寫的相關資訊,可能大家看到很多地方類似的,但是當不同的token值過來的時候,需要對應填寫不同的相關資訊的, 每次擷取的時候都需要對應的判斷token值是否正确,我這裡都作了一些簡化,在實際開發的時候都需要填充進去

5 __trt__GetStreamUri後去裝置的URi,通過RTSP擷取視訊流

Onvif開發之服務端成功對接Rtsp視訊流篇

trt__GetStreamUriResponse->MediaUri = (struct tt__MediaUri *)soap_malloc(soap, sizeof(struct tt__MediaUri));  

memset(trt__GetStreamUriResponse->MediaUri, 0, sizeof(struct tt__MediaUri));  

trt__GetStreamUriResponse->MediaUri->Uri = (char *)soap_malloc(soap, sizeof(char) * MAX_64_LEN);  

memset(trt__GetStreamUriResponse->MediaUri->Uri, '\0', sizeof(char) * MAX_64_LEN);  

//根據各個裝置的rtsp協定的uri不同填寫對應的值  

strncpy(trt__GetStreamUriResponse->MediaUri->Uri, "rtsp://192.168.12.135:554/livestream", MAX_64_LEN);  

trt__GetStreamUriResponse->MediaUri->InvalidAfterConnect = (enum xsd__boolean)0;  

trt__GetStreamUriResponse->MediaUri->InvalidAfterReboot  = (enum xsd__boolean)0;  

//逾時時間  

trt__GetStreamUriResponse->MediaUri->Timeout = 200;  

裝置端通過Onvif協定來實作RTSP預覽的代碼已經基本寫完,現在可以看看效果,首先确定裝置端能夠通過vlc正确預覽圖像, 也就是說裝置端需要支援RTSP協定,

可能通過Live555來實作。然後就可以通過onvif的工具 Onvif  Deviece Manager 來檢視效果了!

 先看看Live Video的效果

Onvif開發之服務端成功對接Rtsp視訊流篇

z

再看看Video Stream的效果圖

Onvif開發之服務端成功對接Rtsp視訊流篇

 最後看看token的一些顯示的基本資訊

Onvif開發之服務端成功對接Rtsp視訊流篇

裡面因為是自己的一些token和name資訊,是以我就打了碼,這是都是可以根據自己的裝置自己來定的,是以對對接視訊沒有響,隻要在請求的時候對應自己的裝置的能力值擷取的時候對應起來就可以的!onvif裝置端對接視訊流也就完成!

這個過程中還是有很多不不懂的地方,可能上面的開發過程很多不夠完善的地方,如果有懂的更多這方面知識的開發者,

希望能指出我的不足或者提出自己的觀點,大家互相促進學習。

繼續閱讀