互动视频
  • iOS
  • Android : Java
  • macOS
  • Windows
  • Linux
  • Web
  • 小程序
  • Electron
  • 概述
  • 限制说明
  • SDK 下载
  • 快速开始
  • 常用功能
  • 推拉流进阶
  • 视频进阶
  • 音频进阶
  • 其他功能
  • 废弃接口
  • API 文档
  • 常见错误码
  • 常见问题
  • AI教育
  • KTV 合唱
  • 视频直播
  • 视频通话
  • 游戏直播
  • 直播答题
  • 娃娃机

媒体次要信息

更新时间:2022-10-11 15:33

1 功能简介

当开发者需要在主播端和观众端传送音视频流数据的同时,同步一些其他信息,例如视频画面的精准布局等,可以使用本文中的发送、接收媒体次要信息接口来实现。

1.1 常用场景

  1. 同步音乐歌词

如果推流端播放音乐,并且让拉流端同步显示歌词,可以使用媒体次要信息通道发送音乐播放进度时间戳,拉流端播放音乐的同时,可以收到对应的时间戳信息,展示对应音乐播放进度的歌词。

  1. 混流视频画面的精准布局

即构混流服务支持传输开发者的自定义信息,比如混流输入视频的布局信息。自定义信息通过媒体次要信息通道下发,拉流端收到这些信息后,可以知道混流的精准布局信息,从而可以定位到混流画面中的某个小画面。

2 使用步骤

相关功能的 Demo 源码,请联系 ZEGO 技术支持获取。

媒体次要信息功能需要推流和拉流端配对使用才能展示效果,即需要在推流端发送媒体次要信息,拉流端接收媒体次要信息。以下内容将介绍各端如何使用媒体次要信息功能。

2.1 推流端发送媒体次要信息

主播推流发送媒体次要消息调用流程如下:

2.1.1 初始化 SDK

如何初始化请查看文档:快速开始-初始化

2.1.2 开启媒体次要信息功能

成功初始化 SDK 后调用 com.zego.zegoavkit2.mediaside.ZegoMediaSideInfo 包下的 setMediaSideFlags 来开启媒体次要信息功能,才能在推流时发送自定义信息,此接口支持发送 SEI。

请注意:

  1. 如果无特殊要求,建议开启发送媒体次要信息开关时 mediaInfoType 参数设置为 ZegoConstants.MediaInfoType.SeiZegoDefined,也就是采用 SEI payload type = 243 打包, SEI 的发送方式设置为 ZegoConstants.SeiSendType.SeiSendInVideoFrame,也就是随视频帧发送,因为 SEI 单帧发送的时候,ffmpeg 解码会产生类似“此帧无视频”的警告,可能导致一些 CDN 的兼容性问题,例如转码失败等。
  2. 为了便于后续可以兼容 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 发送媒体次要信息-打包格式说明

2.1.3 登录房间

如何登录房间请查看文档:快速开始-登录房间

2.1.4 推流

如何推流请查看文档:快速开始-推流

2.1.5 发送媒体次要信息

开始推流且推流成功后调用 com.zego.zegoavkit2.mediaside.ZegoMediaSideInfo 包下的 sendMediaSideInfo 发送媒体次要信息。

请注意:

  1. setMediaSideFlags 设置为音视频直播时,关闭摄像头将导致无法发送媒体次要信息。
  2. 不需要发送媒体次要信息时,可调用 setMediaSideFlags 来关闭媒体次要信息传输,第一个参数填 false 就代表关闭,关闭后即使调用 sendMediaSideInfo 也不能再发送媒体次要信息。可参考 setMediaSideFlags(false,false,1,1,0) 调用方法。
  3. 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

2.2 拉流端接收媒体次要信息

观众拉流接收媒体次要消息调用流程如下:

2.2.1 初始化 SDK

如何初始化请查看文档:快速开始-初始化

2.2.2 监听媒体次要信息回调

请注意:

  1. 此 API 需要在 成功初始化 SDK 之后,开始拉流前调用,观众端在此 API 设置的回调中获取主播端发送的媒体次要信息,要求主播端已开启发送媒体次要信息开关,并调用 sendMediaSideInfo 发送媒体次要信息。
  2. 主播端采用音视频直播驱动媒体次要信息传输时,拉流时使用 activateVedioPlayStream(String streamId, boolean active) 接口设置了只拉音频时,将无法接收媒体次要信息。
  • 接口原型:

    public void setZegoMediaSideCallback(IZegoMediaSideCallback callback)

  • 参数:

    callback:媒体次要信息回调。

2.2.3 登录房间

如何登录房间请查看文档:快速开始-登录房间

2.2.4 拉流

如何拉流请查看文档:快速开始-拉流

2.2.5 接收媒体次要信息

接收媒体次要信息需要先调用 setZegoMediaSideCallback(IZegoMediaSideCallback callback) 监听媒体次要信息回调,再实现 IZegoMediaSideCallback 回调并处理回调数据。

请注意: 当不需要接收信息时,需将 setZegoMediaSideCallback 的 callback 参数置空,避免内存泄漏。

  • 接口原型:

    public void onRecvMediaSideInfo(String streamID, ByteBuffer inData, int dataLen)

  • 参数:

    streamID:当前流ID信息。

    inData:接收到的媒体数据。

    dataLen:数据总长度。

  • 备注:

    如何解析接收的媒体次要信息请查看 3.2-接收媒体次要信息-解析格式说明

3 格式说明

3.1 发送媒体次要信息-打包格式说明

3.1.1 次媒体方式

  1. 次媒体方式由 SDK 处理,外部无需关注其中细节,即开启发送媒体次要信息开关时 mediaInfoType 参数设置为 ZegoConstants.MediaInfoType.SideInfoZegoDefined
  2. 此种打包方式跟视频编码器产生的信息不存在兼容性问题,但是在其它 CDN 上转码视频的时候,其它 CDN 基本上不支持提取这种方式打包的信息数据,转码完成后再从其它 CDN 拉流时,可能就丢失了这些次媒体信息。
  3. ZEGO CDN 转码支持提取此种方式打包的信息数据。

3.1.2 SEI 方式

  1. SDK 采用 H.264 的 SEI 进行打包,部分支持的 CDN 在转码的时候会提取原有码流中的 SEI 信息编码到新的码流中。
  2. SEI 打包类型--SeiZegoDefined 或者 SeiUserUnregisted,在其它 CDN 转码视频的时候,某些 CDN 不一定支持提取这种方式打包的信息数据,转码完成后再从其它 CDN 拉流时,可能就丢失了这些次媒体信息。
  3. ZEGO CDN 转码支持提取此种方式打包的信息数据。

注意,推荐采用 SEI 方式。

3.2 接收媒体次要信息-解析格式说明

3.2.1 采用 SDK 拉流并解析(内部解析)

接收端在 onRecvMediaSideInfo 中收到发送端发送的媒体次要信息,其中的入参 ByteBuffer 类型的 inData 即为信息数据,以下称为 buf,格式说明为:

  • buf 的前 4 个字节是媒体信息类型 MediaType,MediaType = buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3];

  • 当 MediaType = 1001 时,表示接收到的是 SDK 采用 次媒体方式 打包或是 SEI 中 payload type = 243 的信息,buf[4] 和其后的为 DATA(即开启发送媒体次要信息开关时 mediaInfoType 参数设置为 SeiZegoDefined ),buf 组成如下:

  • 当 MediaType = 1002 时,表示接收到的是混流服务器打包的音浪信息,buf[4] 和其后的为 DATA,buf 组成如下:

  • 当 MediaType = 1003 时,表示接收到的是混流服务器打包的 Layout 信息,buf[4] 和其后的为 DATA,buf 组成如下:

  • 当 MediaType = 1004 时,表示接收到的是 SEI 中 payload type = 5 的信息,即开启发送媒体次要信息开关时 mediaInfoType 参数设置为 ZegoConstants.MediaInfoType.SeiUserUnregisted ,buf[4] 和其后的为 DATA,buf 组成如下:

3.2.2 App 拉流并解析(外部解析)

如果开发者使用 App 拉流(非SDK提供的拉流 API)并解析媒体次要信息,有两种情况:

  1. 解析 SDK 采用次媒体方式打包的媒体次要信息。
  2. 解析 SDK 采用 SEI 方式打包的媒体次要信息。
解析 SDK 采用次媒体方式打包的信息

接收端收到媒体次要消息时,buf 格式如下:

请注意:

  1. DATA 是发送端传入的 inData 内容
  2. LEN = buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3],LEN 的值等于 DATA 长度 + 5 字节(NALTYPE 和 MediaType 的长度)
解析 SDK 采用 SEI 方式打包的信息

请采用 H.264 的 SEI 使用方法处理媒体信息。

4 API 参考列表

方法 描述
setMediaSideFlags 发送媒体次要信息开关,支持发送 SEI
setZegoMediaSideCallback 设置流媒体次要信息回调接口
sendMediaSideInfo 发送媒体次要信息
IZegoMediaSideCallback.onRecvMediaSideInfo 接收媒体次要信息

5 相关文档

  1. 使用混音输入时带上媒体次要信息,请参考 音频进阶-混音中带媒体次要信息
  2. 在发起混流时带上开发者自定义信息,请参考 常用功能-多路混流