音视频进阶教程-SEI直播补充增强信息实现
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折的优惠,联系商务获取产品优惠;
音视频进阶教程-SEI直播补充增强信息实现的更多相关文章
- RTMP协议发送H.264编码及AAC编码的音视频,实现摄像头直播
RTMP(Real Time Messaging Protocol)是专门用来传输音视频数据的流媒体协议,最初由Macromedia 公司创建,后来归Adobe公司所有,是一种私有协议,主要用来联系F ...
- 手机Android音视频採集与直播推送,实现单兵、移动监控类应用
最新手机採集推送直播监控以及EasyDarwin开源流媒体平台的版本号及代码: EasyDarwin 开源流媒体云平台:https://github.com/easydarwin EasyClient ...
- 音视频处理之H264编码标准20170906
一. H264基础概念 1.名词解释 场和帧 : 视频的一场或一帧可用来产生一个编码图像.在电视中,为减少大面积闪烁现象,把一帧分成两个隔行的场. 片: 每个图象中,若干 ...
- 音视频通讯QoS技术及其演进
利用多种算法和策略进行网络传输控制,最大限度满足弱网场景下的音视频用户体验. 良逸|技术作者 01 什么是QoS?音视频通讯QoS是哪一类? QoS(Quality of Service)是服务质量的 ...
- [工具]利用EasyRTSPClient工具检查摄像机RTSP流不能播放原因以及排查音视频数据无法播放问题
出现问题 我们在做流媒体开发的过程中,进程会出现摄像机RTSP流莫名其妙无法播放的问题,而我们常用的vlc经常是直接弹出一个无法播放的提示框就完事了,没有说明出错的原因,或者在vlc的消息里面能看到日 ...
- ffmpeg解码音视频过程(附代码)
0. 引言 最近一直在使用和学习ffmpeg. 工作中需要拉流解码, 获取音频和视频数据. 这些都是使用ffmpeg处理. 因为对ffmpeg接触不多, 用的不深, 在使用的过程中经常遇到不太懂的地方 ...
- Python音视频剪辑库MoviePy1.0.3中文教程导览及可执行工具下载
☞ ░ 前往老猿Python博文目录 ░ 一.简介 MoviePy是一个用于视频编辑的Python模块,可用于进行视频的基本操作(如剪切.拼接.标题插入).视频合成(也称非线性编辑).视频处理或创建高 ...
- flex4+fms3.5+cs4开发实时音视频直播及点播详解
开发工具及环境: 1)flash builder4 2)flash cs4 3)flash media server3.5 fms部分 fms是adobe的流媒体服务器,不过是收费的,价格大概是ora ...
- 堪称教科书级别的Android音视频入门进阶学习手册,开源分享!
概述 随着整个互联网的崛起,数据传递的形式也在不断升级变化,总的流行趋势如下: 纯文本的短信,QQ -> 空间,微博,朋友圈的图片文字结合 -> 微信语音 -> 各大直播软件 -&g ...
- android音视频点/直播模块开发
音视频 版权声明:本文为博主原创文章,未经博主允许不得转载. 前言 随着音视频领域的火热,在很多领域(教育,游戏,娱乐,体育,跑步,餐饮,音乐等)尝试做音视频直播/点播功能,那么作为开发一个小白, ...
随机推荐
- 数据库迁移的艺术:FastAPI生产环境中的灰度发布与回滚策略
title: 数据库迁移的艺术:FastAPI生产环境中的灰度发布与回滚策略 date: 2025/05/17 21:06:56 updated: 2025/05/17 21:06:56 author ...
- 阅读类元服务开发笔记---week3
.markdown-body { line-height: 1.75; font-weight: 400; font-size: 16px; overflow-x: hidden; color: rg ...
- RAG越来越不准?从Dify和ima知识库看元数据与标签如何让大模型更懂你
你是否有这样的经历:"知识库文档越来越多,知识库问答却越来越不靠谱,RAG检索到的都是一堆不相关的内容." 在这个信息爆炸的时代,我们不缺资料,缺的是找到"对的资料&qu ...
- Spring Boot项目基于POI框架导出Excel表格
1. 依赖 我的项目是基于Spring Boot的,这里只贴出POI框架需要依赖的两个包,其他的都无所谓,只要能提供Controller让浏览器访问即可.在pom.xml配置文件中增加如下两个包 ...
- C#获得项目最后编译时间
C#获得项目最后编译时间 效果 具体格式可以自定义 核心代码 string GetCompileVersion() { string OriginVersion = "" + Sy ...
- 十步,做一个基于Claw Cloud的天气推送
作者:故事我忘了¢ 个人微信公众号:程序猿的月光宝盒 目录 前言 步骤分解 步骤一 步骤二 步骤三 步骤四 步骤五 步骤六 步骤七 步骤八 步骤九 步骤十 对应的节点,鼠标移上去点三个小点,点rena ...
- 【服务器备份方案】基于Duplicati+Alist+阿里云盘的备份方案
服务器备份方案 该博文转载自我的个人博客:小树 | 服务器备份方案 前言 在我们实际的生产环境中,由于云服务存在很多的不稳定性,因此对服务器进行定时备份就很有必要了. 虽然部分服务器厂商提供了快照备份 ...
- PVE折腾笔记 (3) 在原QNAP使用的硬盘上创建ZFS
前言 在经过一番研究后,我决定使用ZFS作为俩机械硬盘的文件系统,本来也可以和QNAP一样直接ext4的,但ZFS比较安全,有自愈功能,可以处理比特位翻转的问题,总之就是好用. 如果追求灵活性可以使用 ...
- [CF1672G]Cross Xor
G - Cross Xor 对于\((n\&1)\&\&(m\&1)\)的情况,所有行.列的异或和的必须相等(异或和指当前行/列中所有元素的异或和) 每次修改的点\(( ...
- 低版本.net ueditor结合cshtml getshell
ueditor版本.net 1.3.x,不是.net 1.4.3的getshell 上传页面是这样的需要开启flash,添加照片抓包.先正常上传 改后缀提示不允许的文件类型 注意到fileNameFo ...