Onvif开发之服务端成功对接Rtsp视频流篇
2014-01-07 19:05
477 查看
前面篇介绍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的一些基本信息是需要填写的
2 __tds__GetServices函数的一些基本信息的填写
3 __trt__GetProfiles获取设备的配置信息
4 视频源已经视频编码必须填充的一些基本需要填写的一些关键信息
(1)__trt__GetVideoEncoderConfiguration函数接口一些主要信息
5 __trt__GetStreamUri后去设备的URi,通过RTSP获取视频流
设备端通过Onvif协议来实现RTSP预览的代码已经基本写完,现在可以看看效果,首先确定设备端能够通过vlc正确预览图像, 也就是说设备端需要支持RTSP协议,
可能通过Live555来实现。然后就可以通过onvif的工具 Onvif Deviece Manager 来查看效果了!
先看看Live Video的效果
z
再看看Video Stream的效果图
最后看看token的一些显示的基本信息
里面因为是自己的一些token和name信息,所以我就打了码,这是都是可以根据自己的设备自己来定的,所以对对接视频没有响,只要在请求的时候对应自己的设备的能力值获取的时候对应起来就可以的!onvif设备端对接视频流也就完成!
这个过程中还是有很多不不懂的地方,可能上面的开发过程很多不够完善的地方,如果有懂的更多这方面知识的开发者,
希望能指出我的不足或者提出自己的观点,大家相互促进学习。
在这个之前必须确定几个简单的条件
1 设备端能被发现
2 设备端支持RTSP协议,并且能够通过VLC进行正常的预览
通过onvif协议设备需要做的几个基本事情:
1 __tds__GetCapabilities获取设备能力
2 __trt__GetProfiles获取设备的配置信息
3 获取前段设备的视频编码和视频源的一些基本需要的信息
4 __trt__GetStreamUri后去设备的URi,通过RTSP获取视频流
接口函数有了,实现的时候当然也需要注意匹配,需要把设备的一些主要信息对应匹配到Onvif协议中,下面一个函数一个函数的具体实现如下,在需要注意的地方我都加上了对应的注释,如果还有不清楚的地方可以留言,我会尽量尽我所知道的告诉大家
1 __tds__GetCapabilities,此函数是获取设备端的能力的函数,在这里需要预览,所以基本的media和device的一些基本信息是需要填写的
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函数的一些基本信息的填写
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获取设备的配置信息
// 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函数接口一些主要信息
//请求的时候需要匹配的一些基本信息 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函数接口一些主要信息
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)); // 请求的视频的分辨率,对应前端设备填写对应的值,我这是1280 * 720 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需要填写的一些基本信息
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需要填写的一些基本信息
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获取视频流
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的效果
z
再看看Video Stream的效果图
最后看看token的一些显示的基本信息
里面因为是自己的一些token和name信息,所以我就打了码,这是都是可以根据自己的设备自己来定的,所以对对接视频没有响,只要在请求的时候对应自己的设备的能力值获取的时候对应起来就可以的!onvif设备端对接视频流也就完成!
这个过程中还是有很多不不懂的地方,可能上面的开发过程很多不够完善的地方,如果有懂的更多这方面知识的开发者,
希望能指出我的不足或者提出自己的观点,大家相互促进学习。
相关文章推荐
- Onvif开发之服务端成功对接Rtsp视频流篇
- Onvif开发之服务端成功对接Rtsp视频流篇
- onvif规范的实现:成功实现ONVIF协议RTSP-Video-Stream与OnvifDeviceManager的视频对接
- onvif规范的实现:成功实现ONVIF协议RTSP-Video-Stream与OnvifDeviceManager的视频对接
- onvif规范的实现:成功实现ONVIF协议RTSP-Video-Stream与OnvifDeviceManager的视频对接
- onvif规范的实现:成功实现ONVIF协议RTSP-Video-Stream与OnvifDeviceManager的视频对接
- onvif规范的实现:成功实现ONVIF协议RTSP-Video-Stream与OnvifDeviceManager的视频对接
- onvif规范的实现:成功实现ONVIF协议RTSP-Video-Stream与OnvifDeviceManager的视频对接
- onvif规范的实现:成功实现ONVIF协议RTSP-Video-Stream与OnvifDeviceManager的视频对接
- onvif规范的实现:成功实现ONVIF协议RTSP-Video-Stream与OnvifDeviceManager的视频对接
- onvif规范的实现:成功实现ONVIF协议RTSP-Video-Stream与OnvifDeviceManager的视频对接
- onvif轨范的实现:成功实现ONVIF协议RTSP-Video-Stream与OnvifDeviceManager的视频对接
- onvif规范的实现:成功实现ONVIF协议RTSP-Video-Stream与OnvifDeviceManager的视频对接
- onvif规范的实现:成功实现ONVIF协议RTSP-Video-Stream与OnvifDeviceManager的视频对接
- onvif规范的实现:成功实现ONVIF协议RTSP-Video-Stream与OnvifDeviceManager的视频对接
- 【视频开发】ONVIF、RTSP/RTP、FFMPEG的开发实录
- 自行实现 Onvif 对接开发模式
- Onvif开发之服务端发现篇