当开发者需要在主播端和观众端传送音视频流数据的同时,同步一些其他信息,例如视频画面的精准布局等,可以使用本文中的发送、接收媒体次要信息接口来实现。
如果推流端播放音乐,并且让拉流端同步显示歌词,可以使用媒体次要信息通道发送音乐播放进度时间戳,拉流端播放音乐的同时,可以收到对应的时间戳信息,展示对应音乐播放进度的歌词。
即构混流服务支持传输开发者的自定义信息,比如混流输入视频的布局信息。自定义信息通过媒体次要信息通道下发,拉流端收到这些信息后,可以知道混流的精准布局信息,从而可以定位到混流画面中的某个小画面。
相关功能的 Demo 源码,请联系 ZEGO 技术支持获取。
媒体次要信息功能需要推流和拉流端配对使用才能展示效果,即需要在推流端发送媒体次要信息,拉流端接收媒体次要信息。以下内容将介绍各端如何使用媒体次要信息功能。
主播推流发送媒体次要消息调用流程如下:
如何初始化请查看文档:快速开始-初始化
成功初始化 SDK
后调用 com.zego.zegoavkit2.mediaside.ZegoMediaSideInfo
包下的 setMediaSideFlags
来开启媒体次要信息功能,才能在推流时发送自定义信息,此接口支持发送 SEI。
请注意:
- 如果无特殊要求,建议开启发送媒体次要信息开关时
mediaInfoType
参数设置为ZegoConstants.MediaInfoType.SeiZegoDefined
,也就是采用 SEIpayload type = 243
打包, SEI 的发送方式设置为ZegoConstants.SeiSendType.SeiSendInVideoFrame
,也就是随视频帧发送,因为 SEI 单帧发送的时候,ffmpeg 解码会产生类似“此帧无视频”的警告,可能导致一些 CDN 的兼容性问题,例如转码失败等。- 为了便于后续可以兼容 H.265 视频编码格式,建议开发者采用 SEI 方式。
接口原型:
public void setMediaSideFlags(boolean start, boolean onlyAudioPublish, int mediaInfoType, int seiSendType, int channelIndex)
参数:
start
:开启/关闭媒体次要信息传输,true 表示开启媒体次要信息传输,false 表示关闭媒体次要信息传输。start 为 true 时,onlyAudioPublish 参数开关才有效。
onlyAudioPublish
:是否为纯音频直播,true 表示纯音频直播,不传输视频数据;false 表示音视频直播,传输音频和视频数据;默认为 false。
mediaInfoType
:媒体次要信息类型,请参考 ZegoConstants.MediaInfoType 定义,需要发送 SEI 时建议使用 ZegoConstants.MediaInfoType.SeiZegoDefined 类型。
seiSendType
:SEI 发送类型,请参考 ZegoConstants.SeiSendType 定义,此参数只对发送 SEI 时有效,当 mediaInfoType 参数为 ZegoConstants.MediaInfoType.SideInfoZegoDefined 时此参数无效,当发送 SEI 时建议使用 ZegoConstants.SeiSendType.SeiSendInVideoFrame 类型。
channelIndex
:推流通道 index,请参考 ZegoConstants.PublishChannelIndex
MediaInfoType
类型如下:
final public static class MediaInfoType {
/**
* ZEGO 定义的打包类型,跟视频编码器产生的信息不存兼容性问题。
*/
final static public int SideInfoZegoDefined = 0;
/**
* 采用 SEI (nalu type = 6,payload type = 243) 类型打包,此类型是 SEI 标准未规定的类型,跟视频编码器或者视频文件中的 SEI 不存在冲突性,用户不需要根据 SEI 的内容做过滤。
* 若需要发送 SEI 推荐采用此种类型。
*/
final static public int SeiZegoDefined = 1;
/**
* 采用 SEI (nalu type = 6,payload type = 5) 类型打包,H.264 标准对于此类型有规定的格式:startcode + nalu type(6) + payload type(5) + len + pay load(uuid + context)+ trailing bits;
*
* 由于视频编码器自身会产生 payload type 为 5 的 SEI,或者使用视频文件推流时,视频文件中也可能存在这样的 SEI,所以使用此类型时,用户需要把 uuid + context 当作一段 buffer 塞给次媒体的发送接口;
*
* 此时为了区别视频编码器自身产生的 SEI, App 在发送此类型 SEI 时,可以填写业务特定的uuid(uuid长度为16字节),接收方使用SDK 解析payload type为 5的SEI时,会根据设置的过滤字符串过滤出 uuid相符的 SEI 抛给业务,如果没有设置过滤字符串,SDK会把所有收到的SEI都抛给业务方;
*
* uuid过滤字符串设置接口,SetConfig("unregister_sei_filter=XXXXXX"),其中unregister_sei_filter为 key,XXXXX为需要设置的uuid过滤字符串。
*/
final static public int SeiUserUnregisted = 2;
}
SEI
发送类型如下:
final public static class SeiSendType {
/**
* SEI 单帧发送,此种发送方式下,ffmpeg 解码会产生类似“此帧无视频”的警告,可能会导致一些 CDN 兼容性问题,例如转码失败等。
*/
final static public int SeiSendSingleFrame = 0;
/**
* SEI 随视频帧发送,推荐采用此类型。
*/
final static public int SeiSendInVideoFrame = 1;
}
备注:
打包类型的区别请查看 3.1 发送媒体次要信息-打包格式说明
如何登录房间请查看文档:快速开始-登录房间
如何推流请查看文档:快速开始-推流
开始推流且推流成功后
调用 com.zego.zegoavkit2.mediaside.ZegoMediaSideInfo
包下的 sendMediaSideInfo
发送媒体次要信息。
请注意:
setMediaSideFlags
设置为音视频直播时,关闭摄像头将导致无法发送媒体次要信息。- 不需要发送媒体次要信息时,可调用
setMediaSideFlags
来关闭媒体次要信息传输,第一个参数填 false 就代表关闭,关闭后即使调用sendMediaSideInfo
也不能再发送媒体次要信息。可参考setMediaSideFlags(false,false,1,1,0)
调用方法。sendMediaSideInfo
的调用频率不能超过帧率,假设推流采用默认帧率15 fps,即调用频率不能超过 1000/15=66.7 ms/次。
接口原型:
public void sendMediaSideInfo(ByteBuffer inData, int dataLen, boolean packet, int channelIndex)
参数:
inData
:需要传输的音视频次要信息数据,外部输入,必须使用ByteBuffer.allocateDirect(int型length)创建,否则数据无法传递给 SDK,观众端收不到媒体次要信息回调。
dataLen
:传入的 inData 总长度,不能大于 4096 Bytes。
packet
:是否采用外部打包好的包头,填写 false。
channelIndex
:推流通道 index,请参考 ZegoConstants.PublishChannelIndex
观众拉流接收媒体次要消息调用流程如下:
如何初始化请查看文档:快速开始-初始化
请注意:
- 此 API 需要在
成功初始化 SDK 之后,开始拉流前
调用,观众端在此 API 设置的回调中获取主播端发送的媒体次要信息,要求主播端已开启发送媒体次要信息开关,并调用sendMediaSideInfo
发送媒体次要信息。- 主播端采用音视频直播驱动媒体次要信息传输时,拉流时使用
activateVedioPlayStream(String streamId, boolean active)
接口设置了只拉音频时,将无法接收媒体次要信息。
接口原型:
public void setZegoMediaSideCallback(IZegoMediaSideCallback callback)
参数:
callback
:媒体次要信息回调。
如何登录房间请查看文档:快速开始-登录房间
如何拉流请查看文档:快速开始-拉流
接收媒体次要信息需要先调用 setZegoMediaSideCallback(IZegoMediaSideCallback callback)
监听媒体次要信息回调,再实现 IZegoMediaSideCallback
回调并处理回调数据。
请注意: 当不需要接收信息时,需将
setZegoMediaSideCallback
的 callback 参数置空,避免内存泄漏。
接口原型:
public void onRecvMediaSideInfo(String streamID, ByteBuffer inData, int dataLen)
参数:
streamID
:当前流ID信息。
inData
:接收到的媒体数据。
dataLen
:数据总长度。
备注:
如何解析接收的媒体次要信息请查看 3.2-接收媒体次要信息-解析格式说明
- 次媒体方式由 SDK 处理,外部无需关注其中细节,即开启发送媒体次要信息开关时
mediaInfoType
参数设置为ZegoConstants.MediaInfoType.SideInfoZegoDefined
。- 此种打包方式跟视频编码器产生的信息不存在兼容性问题,但是在其它 CDN 上转码视频的时候,其它 CDN 基本上不支持提取这种方式打包的信息数据,转码完成后再从其它 CDN 拉流时,可能就丢失了这些次媒体信息。
- ZEGO CDN 转码支持提取此种方式打包的信息数据。
- SDK 采用 H.264 的 SEI 进行打包,部分支持的 CDN 在转码的时候会提取原有码流中的 SEI 信息编码到新的码流中。
- SEI 打包类型--
SeiZegoDefined
或者SeiUserUnregisted
,在其它 CDN 转码视频的时候,某些 CDN 不一定支持提取这种方式打包的信息数据,转码完成后再从其它 CDN 拉流时,可能就丢失了这些次媒体信息。- ZEGO CDN 转码支持提取此种方式打包的信息数据。
注意,推荐采用 SEI 方式。
接收端在 onRecvMediaSideInfo
中收到发送端发送的媒体次要信息,其中的入参 ByteBuffer 类型的 inData 即为信息数据,以下称为 buf,格式说明为:
buf 的前 4 个字节是媒体信息类型 MediaType,int MediaType = (buf.get(0) & 0xFF) << 24 | (buf.get(1) & 0xFF) << 16 | (buf.get(2) & 0xFF) << 8 | (buf.get(3) & 0xFF);
当 MediaType = 1001 时,表示接收到的是 SDK 采用 次媒体方式
打包或是 SEI 中 payload type = 243
的信息,buf[4] 和其后的为 DATA(即开启发送媒体次要信息开关时 mediaInfoType
参数设置为 SeiZegoDefined
),buf 组成如下:
payload type = 5
的信息,即开启发送媒体次要信息开关时 mediaInfoType
参数设置为 ZegoConstants.MediaInfoType.SeiUserUnregisted
,buf[4] 和其后的为 DATA,buf 组成如下:如果开发者使用 App 拉流(非SDK提供的拉流 API)并解析媒体次要信息,有两种情况:
接收端收到媒体次要消息时,buf 格式如下:
请注意:
- DATA 是发送端传入的 inData 内容
- int MediaType = (buf.get(0) & 0xFF) << 24 | (buf.get(1) & 0xFF) << 16 | (buf.get(2) & 0xFF) << 8 | (buf.get(3) & 0xFF),LEN 的值等于 DATA 长度 + 5 字节(NALTYPE 和 MediaType 的长度)
请采用 H.264 的 SEI 使用方法处理媒体信息。
方法 | 描述 |
---|---|
setMediaSideFlags | 发送媒体次要信息开关,支持发送 SEI |
setZegoMediaSideCallback | 设置流媒体次要信息回调接口 |
sendMediaSideInfo | 发送媒体次要信息 |
IZegoMediaSideCallback.onRecvMediaSideInfo | 接收媒体次要信息 |
联系我们
文档反馈