当开发者需要在主播端和观众端传送音视频流数据的同时,同步一些其他信息,例如视频画面的精准布局等,可以使用本文中的发送、接收媒体次要信息接口来实现。
如果推流端播放音乐,并且让拉流端同步显示歌词,可以使用媒体次要信息通道发送音乐播放进度时间戳,拉流端播放音乐的同时,可以收到对应的时间戳信息,展示对应音乐播放进度的歌词。
即构混流服务支持传输开发者的自定义信息,比如混流输入视频的布局信息。自定义信息通过媒体次要信息通道下发,拉流端收到这些信息后,可以知道混流的精准布局信息,从而可以定位到混流画面中的某个小画面。
相关功能的 Demo 源码,请联系 ZEGO 技术支持获取。
媒体次要信息功能需要推流和拉流端配对使用才能展示效果,即需要在推流端发送媒体次要信息,拉流端接收媒体次要信息。以下内容将介绍各端如何使用媒体次要信息功能。
主播推流发送媒体次要消息调用流程如下:
如何初始化请查看文档:快速开始-初始化
成功初始化 SDK
后调用 zego-api-media-side-info.h
中的 SetMediaSideFlags
来开启媒体次要信息功能,才能在推流时发送自定义信息,此接口支持发送 SEI。
请注意:
- 如无特殊要求,建议开启发送媒体次要信息开关时
nMediaInfoType
参数设置为SEI_ZEGO_DEFINED
,也就是采用 SEIpayload type = 243
打包, SEI 的发送方式设置为SEI_SEND_IN_VIDEO_FRAME
,也就是随视频帧发送,因为 SEI 单帧发送的时候,ffmpeg 解码会产生类似“此帧无视频”的警告,可能导致一些 CDN 的兼容性问题,例如转码失败等。- 为了便于后续可以兼容 H.265 视频编码格式,建议开发者采用 SEI 方式。
接口原型:
ZEGOAVKIT_API void SetMediaSideFlags(bool bStart, bool bOnlyAudioPublish, PublishChnIdx nChannel = PUBLISH_CHN_MAIN, int nMediaInfoType = SEI_ZEGO_DEFINED, int nSeiInfoType = SEI_SEND_IN_VIDEO_FRAME)
参数:
bStart
:开启/关闭媒体次要信息传输,true 表示开启媒体次要信息传输,false 表示关闭媒体次要信息传输。bStart 为 true 时,bOnlyAudioPublish 参数才有效。
bOnlyAudioPublish
:是否为纯音频直播,true 表示纯音频直播,不传输视频数据;false 表示音视频直播,传输音频和视频数据;默认为 false。
nChannel
:推流通道 index,请参考 ZEGO::AV::PublishChannelIndex 定义,默认为主推流通道。
nMediaInfoType
:媒体次要信息类型,请参考 ZEGO::AV::MediaInfoType 定义,默认是 SEI_ZEGO_DEFINED,需要发送 SEI 时也建议使用 SEI_ZEGO_DEFINED 类型。
nSeiInfoType
:SEI 发送类型,请参考 ZEGO::AV::SeiSendType 定义,默认为 SEI_SEND_IN_VIDEO_FRAME,此参数只对发送 SEI 时有效,当 nMediaInfoType 参数为 SIDE_INFO_ZEGO_DEFINED 时此参数无效,当发送 SEI 时建议使用 SEI_SEND_IN_VIDEO_FRAME 类型。
MediaInfoType
类型如下:
enum MediaInfoType
{
/**
* ZEGO 定义的打包类型,跟视频编码器产生的信息不存兼容性问题。
*/
SIDE_INFO_ZEGO_DEFINED = 0,
/**
* 采用 SEI (nalu type = 6,payload type = 243) 类型打包,此类型是 SEI 标准未规定的类型,跟视频编码器或者视频文件中的 SEI 不存在冲突性,用户不需要根据 SEI 的内容做过滤。
* 若需要发送 SEI 推荐采用此种类型。
*/
SEI_ZEGO_DEFINED,
/**
* 采用 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过滤字符串。
*/
SEI_USER_UNREGISTED
};
SEI
发送类型如下:
enum SEIInfoSendType
{
/**
* SEI 单帧发送,此种发送方式下,ffmpeg 解码会产生类似“此帧无视频”的警告,可能会导致一些 CDN 兼容性问题,例如转码失败等。
*/
SEI_SEND_SINGLE_FRAME = 0,
/**
* SEI 随视频帧发送,推荐采用此类型。
*/
SEI_SEND_IN_VIDEO_FRAME
};
备注:
打包类型的区别请查看 3.1 发送媒体次要信息-打包格式说明
如何推流请查看文档:快速开始-推流
开始推流且推流成功后
调用 zego-api-media-side-info.h
中的 SendMediaSideInfo
发送媒体次要信息。
请注意:
SetMediaSideFlags
设置为音视频直播时,关闭摄像头将导致无法发送媒体次要信息。- 不需要发送媒体次要信息时,可调用
SetMediaSideFlags
来关闭媒体次要信息传输,第一个参数填 false 就代表关闭,关闭后即使调用SendMediaSideInfo
也不能再发送媒体次要信息。可参考SetMediaSideFlags(false,false,AV::PUBLISH_CHN_MAIN,SEI_ZEGO_DEFINED,SEI_SEND_IN_VIDEO_FRAME)
调用方法。SendMediaSideInfo
的调用频率不能超过帧率,假设推流采用默认帧率15 fps,即调用频率不能超过 1000/15=66.7 ms/次。
接口原型:
ZEGOAVKIT_API void SendMediaSideInfo(const unsigned char *inData, int dataLen, bool bPacket, AV::PublishChannelIndex idx = AV::PUBLISH_CHN_MAIN)
参数:
inData
:需要传输的音视频次要信息数据。
dataLen
:数据长度,不能超过 4096 bytes
bPacket
:是否外部已经打包好包头,填写 false。
idx
:推流通道 index,请参考 ZEGO::AV::PublishChannelIndex 定义,默认为主推流通道。
观众拉流接收媒体次要消息调用流程如下:
如何初始化请查看文档:快速开始-初始化
请注意:
- 此 API 需要在
成功初始化 SDK 之后,开始拉流前
调用,观众端在此 API 设置的回调中获取主播端发送的媒体次要信息,要求主播端已开启发送媒体次要信息开关,并调用SendMediaSideInfo
发送媒体次要信息。- 主播端采用音视频直播驱动媒体次要信息传输时,拉流时使用
activateVedioPlayStream(String streamId, boolean active)
接口设置了只拉音频时,将无法接收媒体次要信息。
接口原型:
ZEGOAVKIT_API void SetMediaSideCallback(IZegoMediaSideCallback* pCB)
参数:
pCB
:回调函数指针。
如何拉流请查看文档:快速开始-拉流
接收媒体次要信息需要先调用 SetMediaSideCallback(IZegoMediaSideCallback* pCB)
监听媒体次要信息回调,再实现 IZegoMediaSideCallback
接口并处理回调数据。
请注意:当不需要接收信息时,需将
SetZegoMediaSideCallback
的 callback 参数置空,避免内存泄漏。
接口原型:
virtual void onRecvMediaSideInfo(const char * pszStreamID, const unsigned char *pBuf, int dataLen) = 0
参数:
pszStreamID
:流ID,标记当前回调的信息属于哪条流。
pBuf
:数据缓冲区,存储流媒体次要信息。
dataLen
:缓冲区长度
备注:
如何解析接收的媒体次要信息请查看 3.2-接收媒体次要信息-解析格式说明
- 次媒体方式由 SDK 处理,外部无需关注其中细节,即开启发送媒体次要信息开关时
nMediaInfoType
参数设置为SIDE_INFO_ZEGO_DEFINED
。- 此种打包方式跟视频编码器产生的信息不存在兼容性问题,但是在其它 CDN 上转码视频的时候,其它 CDN 基本上不支持提取这种方式打包的信息数据,转码完成后再从其它 CDN 拉流时,可能就丢失了这些次媒体信息。
- ZEGO CDN 转码支持提取此种方式打包的信息数据。
- SDK 采用 H.264 的 SEI 进行打包,部分支持的 CDN 在转码的时候会提取原有码流中的 SEI 信息编码到新的码流中。
- SEI 打包类型--
SEI_ZEGO_DEFINED
或者SEI_USER_UNREGISTED
,在其它 CDN 转码视频的时候,某些 CDN 不一定支持提取这种方式打包的信息数据,转码完成后再从其它 CDN 拉流时,可能就丢失了这些次媒体信息。- ZEGO CDN 转码支持提取此种方式打包的信息数据。
注意,推荐采用 SEI 方式。
接收端在 onRecvMediaSideInfo
中收到发送端发送的媒体次要信息,其中的入参 unsigned char* 类型的 pBuf 即为信息数据,以下称为 buf,格式说明为:
buf 的前 4 个字节是媒体信息类型 MediaType,MediaType = buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3];
当 MediaType = 1001 时,表示接收到的是 SDK 采用 次媒体方式
打包或是 SEI 中 payload type = 243
的信息(即开启发送媒体次要信息开关时 nMediaInfoType
参数设置为 SEI_ZEGO_DEFINED
的媒体信息),buf[4] 和其后的为 DATA,buf 组成如下:
payload type = 5
的信息,即开启发送媒体次要信息开关时 nMediaInfoType
参数设置为 SEI_USER_UNREGISTED
,buf[4] 和其后的为 DATA,buf 组成如下:如果开发者使用 App 拉流(非SDK提供的拉流 API)并解析媒体次要信息,有两种情况:
接收端收到媒体次要消息时,buf 格式如下:
请注意:
- DATA 是发送端传入的 inData 内容
- LEN = buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3],LEN 的值等于 DATA 长度 + 5 字节(NALTYPE 和 MediaType 的长度)
请采用 H.264 的 SEI 使用方法处理媒体信息。
方法 | 描述 |
---|---|
ZEGO::MEDIASIDEINFO::SetMediaSideFlags | 发送媒体次要信息开关,支持发送 SEI |
ZEGO::MEDIASIDEINFO::SendMediaSideInfo | 发送媒体次要信息 |
ZEGO::MEDIASIDEINFO::SetMediaSideCallback | 设置流媒体次要信息回调接口 |
ZEGO::MEDIASIDEINFO::IZegoMediaSideCallback::onRecvMediaSideInfo | 接收媒体次要信息 |
联系我们
文档反馈