国网B接口之录像回放

        之前写过两篇关于B接口以及GB28181的文章,近期遇到一个客户需求,需要通过B接口实现录像回放。我们先看下B接口2014部分的描述

在2014版本中,回放采用的是RTSP协议。我们再看看2019与2014的区别

在2019中,录像废除了RTSP协议,这个其实也是像GB28181看齐了,所以我说两个协议是相互借鉴学习的。当然在2014中,这个RTSP流协议,实际上也存在不合理之处,有点突兀,前面视频直播都是SIP+RTP,到回放时则变成了RTSP,所以2019废除也是明智之选。

本篇主要介绍2014版本的视频回放,这个功能用的少,所以最早我是直接编译了live555,这个已经涵盖了rtsp的流媒体点播服务,在给客户测试或者演示时,选择了RTP+裸h264的方式就可以了。只需要返回录像的RTSP地址,播流时交给live555即可。但是现在的客户是只支持ps+h264,这个live555就没法搞定了。

        第一个方案,基于live555修改,开始研读live555的源代码,不读不知道,一读吓一跳,里面的继承关系十分复杂,且成员变量赋值也是有多处操作,比如存视频数据的fTo,看的头昏脑胀的。折腾了一两天,改了一下,不太容易改。就放弃了。

        第二个方案,本来我自己的视频封装也包含了ps+264以及裸的264。无非就是缺少RTSP的信令解析,RTSP内部视频传输协议仍然是RTP/RTCP。我们只需要一个RTSP信令解析的功能就可以了,自己实现这个信令解析呢,其实也不难,花点时间。但是我们还是那个观点,站在巨人的肩膀上,经搜索,发现这个开源库很适用,稍微改造下即可。

        https://gitcode.com/gh_mirrors/rt/RtspServer.git

        在RTSP交互中,SETUP是含有了客户端接受的RTP流端口,报文示例如下

        

        此处描述了rtp端口是4602,rtcp是4603

        紧接着,我们会回复一个

        此处我们将要传输流的端口是9228和9229,到此步骤为止,双方以及开始做传输准备了,只待下发PLAY指令即可。此处对应RtspServer的代码如下


/// RtspConnection.cpp
void RtspConnection::HandleCmdSetup()
{
	if (auth_info_ != nullptr && !HandleAuthentication()) {
		return;
	}

	int size = 0;
	std::shared_ptr<char> res(new char[4096], std::default_delete<char[]>());
	MediaChannelId channel_id = rtsp_request_->GetChannelId();
	MediaSession::Ptr media_session = nullptr;

	auto rtsp = rtsp_.lock();
	if (rtsp) {
		media_session = rtsp->LookMediaSession(session_id_);
	}

	if(!rtsp || !media_session)  {
		goto server_error;
	}

	if(media_session->IsMulticast())  {
		std::string multicast_ip = media_session->GetMulticastIp();
		if(rtsp_request_->GetTransportMode() == RTP_OVER_MULTICAST) {
			uint16_t port = media_session->GetMulticastPort(channel_id);
			uint16_t session_id = rtp_conn_->GetRtpSessionId();
			if (!rtp_conn_->SetupRtpOverMulticast(channel_id, multicast_ip.c_str(), port)) {
				goto server_error;
			}

			size = rtsp_request_->BuildSetupMulticastRes(res.get(), 4096, multicast_ip.c_str(), port, session_id);
		}
		else {
			goto transport_unsupport;
		}
	}
	else {
		int rtpPort, rtcpPort;
		uint16_t session_id = rtp_conn_->GetRtpSessionId();
        /// TCP部分暂不考虑
		if
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值