欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

如何在RTSP/RTMP直播过程中加入SEI扩展数据发送和接收解析

程序员文章站 2022-07-14 19:48:22
...

在直播系统中,除了直播音视频之外,有时候还想从主播端发布文本信息等,这些信息可以不通过视频传输通道发送给用户播放端,但如果传输的数据想和视频保持精准同步,那最好的办法就是这些信息和视频数据打包在一起传输,并通过h264 sei方式就可以把数据放入h264 Access Unit中传输。

扩展SEI有使用场景:

1、公告广播:推送将相对/绝对时间戳/时间/公告内容发到播放端,播放端实时接收消息并做相应的逻辑处理;

2、冲顶大会:推流端实时将题目分发到播放端,借助于大牛直播SDK低延迟特性,轻松实现“音-画-题”同步接收;

3、直播:推流端将歌词/字幕分发到播放端,播放端实时绘制出歌词;

4、应急指挥/单兵:推送端将GIS信息/现场采集到的数据实时写入并分发到播放端;

5、在线教育:推流端将激光笔涂鸦操作分发到播放端,播放端实时划圈划线,实现特定特效。

扩展SEI调用demo(以Windows平台为例):

 1. 启动推送端软件: SmartPublisherDemo.exe,可到 Github 下载大牛直播SDK的相关测试软件或demo源码。

 2. 做如下配置:

如何在RTSP/RTMP直播过程中加入SEI扩展数据发送和接收解析

3. 可以点击自动发送文本按钮;

4. 打开播放端SmartPlayer.exe查看数据传输播放效果:

如何在RTSP/RTMP直播过程中加入SEI扩展数据发送和接收解析

扩展SEI调用demo代码说明:

1. 推送端(对应工程:WIN-PublisherSDK-CPP-Demo):

		/*++++发送用户自定义数据相关接口++++*/
		/*
		* 1. 目前使用sei机制发送用户自定数据到播放端
		* 2. 这种机制有可能会丢失数据, 所以这种方式不保证接收端一定能收到
		* 3. 优势:能和视频保持同步,虽然有可能丢失,但一般的需求都满足了
		* 4. 目前提供两种发送方式 第一种发送二进制数据, 第二种发送 utf8字符串
		*/

		/*
		* 设置发送队列大小,为保证实时性,默认大小为3, 必须设置一个大于0的数
		* 如果数据超过队列大小,将丢掉队头数据
		* 这个接口请在 StartPublisher 之前调用
		*/
		NT_UINT32(NT_API *SetPostUserDataQueueMaxSize)(NT_HANDLE handle, NT_INT32 max_size, NT_INT32 reserve);


		/*
		* 清空用户数据队列, 有些情况可能会用到,比如发送队列里面有4条消息再等待发送,又想把最新的消息快速发出去, 可以 
		* 先清除掉正在排队消息, 再调用PostUserXXX  
		*
		*/
		NT_UINT32(NT_API *ClearPostUserDataQueue)(NT_HANDLE handle);

		/*
		* 发送二进制数据
		* data: 二进制数据
		* size:数据大小
		* 注意: 1.目前数据大小限制在256个字节以内,太大可能会影响视频传输,如果有特殊需求,需要增大限制,请联系我们
		* 2. 如果积累的数据超过了设置的队列大小,之前的队头数据将被丢弃
		* 3. 必须再调用StartPublisher之后再发送数据
		*/
		NT_UINT32(NT_API *PostUserData)(NT_HANDLE handle, const NT_BYTE* data, NT_UINT32 size, NT_INT32 reserve);

		/*
		* 发送utf8字符串
		* utf8_str: utf8字符串
		* 注意: 1. 字符串长度不能超过256, 太大可能会影响视频传输,如果有特殊需求,需要增大限制,请联系我们
		* 2. 如果积累的数据超过了设置的队列大小,之前的队头数据将被丢弃
		* 3. 必须再调用StartPublisher之后再发送数据
		*/
		NT_UINT32(NT_API *PostUserUTF8StringData)(NT_HANDLE handle, NT_PCSTR utf8_str, NT_INT32 reserve);


		/*----发送用户自定义数据相关接口----*/

2. 播放端(对应工程:WIN-PlayerSDK-CPP-Demo):

		/*
		设置用户数据回调
		*/
		NT_UINT32(NT_API *SetUserDataCallBack)(NT_HANDLE handle,
			NT_PVOID call_back_data, NT_SP_SDKUserDataCallBack call_back);


		/*
		设置视频sei数据回调
		*/
		NT_UINT32(NT_API *SetSEIDataCallBack)(NT_HANDLE handle,
			NT_PVOID call_back_data, NT_SP_SDKSEIDataCallBack call_back);
/*
*
* 用户数据回调,目前是推送端发送过来的
* data_type: 数据类型,1:表示二进制字节类型. 2:表示utf8字符串 
* data:实际数据, 如果data_type是1的话,data类型是const NT_BYTE*, 如果data_type是2的话,data类型是 const NT_CHAR*
* size: 数据大小
* timestamp: 视频时间戳
* reserve1: 保留
* reserve2: 保留
* reserve3: 保留
*/
typedef NT_VOID(NT_CALLBACK* NT_SP_SDKUserDataCallBack)(NT_HANDLE handle, NT_PVOID user_data,
	NT_INT32  data_type,
	NT_PVOID  data,
	NT_UINT32 size,
	NT_UINT64 timestamp,
	NT_UINT64 reserve1,
	NT_INT64  reserve2,
	NT_PVOID  reserve3
	);


/*
*
* 视频的sei数据回调
* data: sei 数据
* size: sei 数据大小
* timestamp:视频时间戳
* reserve1: 保留
* reserve2: 保留
* reserve3: 保留
* 注意: 目前测试发现有些视频有好几个sei nal, 为了方便用户处理,我们把解析到的所有sei都吐出来,sei nal之间还是用 00 00 00 01 分隔, 这样方便解析
* 吐出来的sei数据目前加了 00 00 00 01 前缀
*/
typedef NT_VOID(NT_CALLBACK* NT_SP_SDKSEIDataCallBack)(NT_HANDLE handle, NT_PVOID user_data,
	NT_BYTE*  data,
	NT_UINT32 size,
	NT_UINT64 timestamp,
	NT_UINT64 reserve1,
	NT_INT64  reserve2,
	NT_PVOID  reserve3
	);

SEI优势

1. 不依赖于相关协议,rtsp和rtmp都可以,其他协议只要播放端支持SEI解析的都可以使用;

2.  兼容性很好,如果播放端不支持自定义SEI数据解析,把SEI数据丢给H264解码器,解码器只是忽略掉,并不影响正常播放,上述操作也可以用VLC来播放,播放正常,只是不显示SEI消息;

3. 在视频帧携带,完全和视频保持同步,这个是其他传输通道无法做到的。