1 SEI 性能简介
在音视频流媒体利用中,除了能够流媒体通道推拉音视频内容外,还能够应用流 SEI(Supplemental Enhancement Information,媒体补充加强信息)通过流媒体通道将文本信息与音视频内容打包在一起,从主播端(推流端)推出,并从观众端(拉流端)接管,以此实现文本数据与音视频内容的精准同步的目标。
个别可用于视频画面的精准布局、远端歌词同步、直播答题等利用场景。
SEI 的相干概念及原理请参考 如何了解和应用 SEI(媒体补充加强信息)。
适宜对音讯发送有较高频率和实时性要求,且音讯失落不会影响业务逻辑时,举荐应用 SEI(Supplemental Enhancement Information,媒体补充加强信息)。
2 SEI 示例源码下载
请参考 下载示例源码 获取源码。
相干源码请查看“/ZegoExpressExample/Examples/Others/SupplementalEnhancementInformation”目录下的文件。
3 实现 SEI 之前的前提条件
在实现 SEI 性能之前,请确保:
- 已在我的项目中集成 ZEGO Express SDK,实现根本的实时音视频性能,详情请参考 疾速开始 – 集成 和 疾速开始 – 实现视频通话。
- 已在 ZEGO 控制台 创立我的项目,并申请无效的 AppID 和 AppSign,详情请参考 控制台 – 项目管理 中的“我的项目信息”。
4 SEI 接口应用步骤
发送与接管 SEI 信息性能须要推流和拉流端配对应用能力展现成果,即须要在推流端发送 SEI 信息,拉流端接管 SEI 信息。以下内容将介绍各端如何应用发送与接管 SEI 信息性能。
主播推流发送 SEI 音讯调用流程如下:
- 调用
createEngine
接口创立 engine 对象。 - 调用
loginRoom
接口登录房间。 - 调用
startPublishingStream
接口推流。 - 在推流胜利后,调用
sendSEI
接口发送 SEI 信息。
观众拉流接管 SEI 音讯调用流程如下:
- 调用
createEngine
接口创立 engine 对象。 - 创立
IZegoEventHandler
对象,并重写接管 SEI 信息的onPlayerRecvSEI
办法,调用setEventHandler
接口传入创立的IZegoEventHandler
监听onPlayerRecvSEI
的回调。 - 调用
loginRoom
接口登录房间。 - 调用
startPlayingStream
接口拉流。 - 在拉流胜利后,接管到推流端发送的 SEI 信息之后触发
onPlayerRecvSEI
回调。
拉流时,如果开发者通过调用 `mutePlayStreamVideo` 或 `muteAllPlayStreamVideo` 接口,设置了只拉音频流时,将无奈接管 SEI 信息。
4.1(可选)设置 SEI 类型
设置 SEI 类型
因为 SDK 默认应用 ZEGO 自行定义的 SEI(nalu type = 6, payload type = 243)类型打包,且此类型是 SEI 规范未规定的类型,因而跟视频编码器或者视频文件中的 SEI 不存在抵触。但当开发者须要应用第三方解码器解码时(如 FFmpeg),会导致解不出正确的 SEI,此时须要在推流前调用 setSEIConfig
接口更换 SDK 发送 SEI 的类型,应用 UserUnregister 的 SEI(nalu type = 6, payload type = 5)类型打包。
仅当开发者应用第三方解码器解码 SEI 时须要执行该步骤。
-
接口原型
/** * 设置媒体加强补充信息(SEI)类型 * * 必须在推流之前设置。* * @param config SEI 配置属性。默认应用 ZEGO 定义的 SEI 类型。*/ public void setSEIConfig(ZegoSEIConfig config);
-
调用示例
ZegoSEIConfig seiConfig = new ZegoSEIConfig(); // 采纳 H.264 的 SEI (nalu type = 6,payload type = 5) 类型打包,因为视频编码器本身会产生 payload type 为 5 的 SEI,或者应用视频文件推流时,视频文件中也可能存在这样的 SEI,所以应用此类型时,用户须要把 uuid + content 当作 buffer 塞给 SEI 发送接口;此时为了区别视频编码器本身产生的 SEI,App 在发送此类型 SEI 时,能够填写业务特定的 uuid(uuid 长度为 16 字节),接管方应用 SDK 解析 payload type 为 5 的 SEI 时,会依据设置的过滤字符串过滤出 uuid 相符的 SEI 抛给业务,如果没有设置过滤字符串,SDK 会把所有收到的 SEI 都抛给开发者。seiConfig.type = ZegoSEIType.USER_UNREGISTER; engine.setSEIConfig(seiConfig); // 通过 advancedConfig 设置 uuid 过滤字段,设置之后 SDK 只会抛出前 12 个字节为开发者所设置 uuid 的 SEI ZegoEngineConfig engineConfig = new ZegoEngineConfig(); // 其余用户通过 [onPlayerRecvSEI] 收到的 SEI 信息前 12 个字节肯定是 zegozegozego,其余会被过滤 engineConfig.advancedConfig.put("unregister_sei_filter", "zegozegozego"); ZegoExpressEngine.setEngineConfig(engineConfig); // 开始推流 engine.startPublishingStream("STREAM_ID");
4.2 直播推流方
发送 SEI 信息的接口须要在推流胜利之后调用,接口原型如下:
-
接口原型
/** * 发送媒体加强补充信息 * * 此接口可在开发者推流传输音视频流数据同时,发送流媒体加强补充信息来同步一些其余附加信息。* 个别如同步音乐歌词或视频画面精准布局等场景,可抉择应用发送 SEI。* 当推流方发送 SEI 后,拉流方可通过监听 [onPlayerRecvSEI] 的回调获取 SEI 内容。* 因为 SEI 信息追随视频帧或音频帧,因为网络问题有可能丢帧,因而 SEI 信息也有可能丢,为解决这种状况,应该在限度频率内多发几次。* 限度频率:1 秒钟不要超过 30 次。* SEI 数据长度限度为 4096 字节。* @param data SEI 内容 */ public void sendSEI(byte[] data)
-
调用示例
/** 定义 SDK 引擎对象 */ ZegoExpressEngine engine; ZegoEngineProfile profile = new ZegoEngineProfile(); /** 请通过官网注册获取,格局为 123456789L */ profile.appID = appID; /** 请通过官网注册获取,格局为:@"0123456789012345678901234567890123456789012345678901234567890123"(共 64 个字符)*/ profile.appSign = appSign; /** 通用场景接入 */ profile.scenario = ZegoScenario.GENERAL; /** 设置 app 的 application 对象 */ profile.application = getApplication(); /** 创立引擎 */ engine = ZegoExpressEngine.createEngine(profile, null); // 登录房间 engine.loginRoom("roomid", new ZegoUser("userid_1")); // 推流 engine.startPublishingStream("streamid"); // 开发者的其余业务逻辑 ...; // 在业务场景须要的机会发送 SEI 信息 engine.sendSEI("12345".getBytes());
4.3 直播拉流方
接管 SEI 信息的回调接口须要在拉流胜利之后触发,接口原型如下:
-
接口原型
/** * 收到远端流的 SEI 内容 * * 拉流胜利后,当远端流调用 sendSEI 后,本端会收到此回调。* 若只拉纯音频流,将收不到推流端发送的 SEI 信息。* @param streamID 拉流的流 ID * @param data SEI 内容 */ public void onPlayerRecvSEI(String streamID, byte[] data){}
-
调用示例
/** 定义 SDK 引擎对象 */ ZegoExpressEngine engine; ZegoEngineProfile profile = new ZegoEngineProfile(); /** 请通过官网注册获取,格局为 123456789L */ profile.appID = appID; /** 请通过官网注册获取,格局为:@"0123456789012345678901234567890123456789012345678901234567890123"(共 64 个字符)*/ profile.appSign = appSign; /** 通用场景接入 */ profile.scenario = ZegoScenario.GENERAL; /** 设置 app 的 application 对象 */ profile.application = getApplication(); /** 创立引擎 */ engine = ZegoExpressEngine.createEngine(profile, null); // 创立 IZegoEventHandler 对象, 并重写 onPlayerRecvSEI 办法 IZegoEventHandler handler = new IZegoEventHandler(){ // 监听其余回调 ...; // 监听接管 SEI 信息的回调, 当发送端调用 sendSEI 发送信息时会触发此回调 public void onPlayerRecvSEI(String streamID, byte[] data) { // 在这里实现业务场景相干的逻辑, 例如展示相干的 UI 等 ...; } } // 增加监听的回调对象 engine.setEventHandler(handler); // 登录房间 engine.loginRoom("roomid", new ZegoUser("userid_2")); // 拉流, canvas 为 ZegoCanvas 类型的索引 UI 渲染控件的对象 engine.startPlayingStream("streamid", canvas); // 开发者的其余业务逻辑 ...;
5 获取 SEI 更多帮忙
获取本文 SEI(Supplemental Enhancement Information,媒体补充加强信息)的开发文档、技术支持,拜访即构文档核心开发文档页,适宜对音讯发送有较高频率和实时性要求,且音讯失落不会影响业务逻辑的开发场景,例直播答题、歌词同步、单流自定义音浪,混流视频画面布局更换的精准管制。
近期有开发布局的开发者可上即构官网查看,恰逢即构七周年全线音视频产品 1 折的优惠,分割商务获取产品优惠;