Onvif协议客户端开发(6)--获取实时预览的Url地址

获取实时预览的Url地址

一、介绍

Onvif协议对前端摄像头的取流是通过标准Rtsp协议,因此我们就需要通过Onvif协议获取到需要预览摄像头的Rtsp的地址,将拿到的RTSP通过VLC或者其他的RTSP客户端取流预览前端摄像头。

通过Onvif协议获取到前端摄像头的Rtsp地址,需要两个步骤:

  • 1、获取到实时预览RTSP的地址的Token
  • 2、根据获取到的token调用对应的接口获取到RTSP地址

注:获取的token包含了主码流、辅码流的token已经各种配置的token,可以根据自己需要自取;根据主、辅码流的toekn获取到的是对应主、辅码流的RTSP地址。主、辅码流的RTSP地址不同,但是差异可能不大。

二、代码实现

1、获取实时预览RTSP的地址token

struct soap *stSoapNew = soap_new();
if (stSoapNew == nullptr)
{
	return ;
}
soap_set_namespaces(stSoapNew, namespaces);                                 // 设置soap的namespaces
stSoapNew->recv_timeout = 5;                                           					 // 设置超时5秒(超过指定时间没有数据就退出)
stSoapNew->send_timeout = 5;
stSoapNew->connect_timeout = 5;
soap_set_mode(stSoapNew, SOAP_C_UTFSTRING);                          // 设置为UTF-8编码,否则叠加中文OSD会乱码
if (stSoapNew == nullptr)
{
	printf( "Onvif New Soap error!");			
	return;
}

// 如果服务要求鉴权,则以下接口就需要加上用户名密码进行鉴权
soap_wsse_add_UsernameTokenDigest(stSoapNew, NULL, pUserName, pPassWord);//对用户名密码进行加密			

struct _trt__GetProfiles            stProfiles;
struct _trt__GetProfilesResponse    stProfilesResponse;
memset(&stProfiles, 0x00, sizeof(stProfiles));
memset(&stProfilesResponse, 0x00, sizeof(stProfilesResponse));
// pProfilesAddr 是soap_call___tds__GetCapabilities接口获取到的media地址,具体实现参见:[获取设备能力](https://blog.csdn.net/u013566528/article/details/102070372)
nRet = soap_call___trt__GetProfiles(stSoapNew, pProfilesAddr, nullptr, &stProfiles, &stProfilesResponse);
if (nRet != SOAP_OK || stProfilesResponse.__sizeProfiles == 0)
{
	printf("Get profiles num is %d,error code is %d,labbuf is %s", stProfilesResponse.__sizeProfiles, nRet,stSoapInfo->labbuf);
	return;
}

stProfilesResponse.Profiles[i].token;		// 后面获取RTSP地址的token
stProfilesResponse.Profiles[i].name;		// 是对当前profiles的介绍

2、获取实时预览RTSP的地址

struct soap *stSoapNew = soap_new();
if (stSoapNew == nullptr)
{
	return ;
}
soap_set_namespaces(stSoapNew, namespaces);                                 // 设置soap的namespaces
stSoapNew->recv_timeout = 5;                                           					 // 设置超时5秒(超过指定时间没有数据就退出)
stSoapNew->send_timeout = 5;
stSoapNew->connect_timeout = 5;
soap_set_mode(stSoapNew, SOAP_C_UTFSTRING);                          // 设置为UTF-8编码,否则叠加中文OSD会乱码
if (stSoapNew == nullptr)
{
	printf( "Onvif New Soap error!");			
	return;
}

// 构建请求的结构体
struct tt__StreamSetup              ttStreamSetup;
struct tt__Transport                ttTransport;
struct _trt__GetStreamUri           stStreamUri;
struct _trt__GetStreamUriResponse   stStreamUriResp;
memset(&stStreamUri, 0x00, sizeof(stStreamUri));
memset(&stStreamUriResp, 0x00, sizeof(stStreamUriResp));
memset(&ttStreamSetup, 0x00, sizeof(ttStreamSetup));
memset(&ttTransport, 0x00, sizeof(ttTransport));

ttStreamSetup.Stream = tt__StreamType__RTP_Unicast;
ttStreamSetup.Transport = &ttTransport;
ttStreamSetup.Transport->Protocol = tt__TransportProtocol__RTSP;
ttStreamSetup.Transport->Tunnel = NULL;
stStreamUri.StreamSetup = &ttStreamSetup;
stStreamUri.ProfileToken = pMainStreamToken;		// 上面获取到的token

// 如果服务要求鉴权,则以下接口就需要加上用户名密码进行鉴权
soap_wsse_add_UsernameTokenDigest(stSoapNew, NULL, pUserName, pPassWord);//对用户名密码进行加密			

// pProfilesAddr 是soap_call___tds__GetCapabilities接口获取到的media地址,具体实现参见:[获取设备能力](https://blog.csdn.net/u013566528/article/details/102070372)
int nRet = soap_call___trt__GetStreamUri(stSoapNew , pProfilesAddr, NULL, &stStreamUri, &stStreamUriResp);
if (nRet != ONVIFSDK_NOERROR || stSoapInfo->error != SOAP_OK)
{
	printf("Dev ip is %s,ChannelIndex is %d Gsoap return is %d labbuf is %s", m_pIpInfo, nChannelIndex, nRet, stSoapInfo->labbuf);
	return;
}
stStreamUriResp.MediaUri->Uri; 			// 这个就是获取到的摄像头实时预览的RTSP地址

至此,通过Onvif协议获取到了RTSP地址,通过RTSP客户端就可以预览前端摄像头的实时视频了。

你可能感兴趣的:(Onvif协议)