音视频进阶教程-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音视频点/直播模块开发
音视频 版权声明:本文为博主原创文章,未经博主允许不得转载. 前言 随着音视频领域的火热,在很多领域(教育,游戏,娱乐,体育,跑步,餐饮,音乐等)尝试做音视频直播/点播功能,那么作为开发一个小白, ...
随机推荐
- codeup之有序插入
Description 有一个已排好序的数组,要求输入一个数后,按原来排序的规律将它插入到数组中. 假设数组长度为10,数组中前9个数(这9个数要求从键盘上输入,输入时要满足自小到大的输入顺序)已经按 ...
- to查完成绩的夏夏
虽然不知道你现在看到的成绩是310还是340,抑或预估值域外的其他成绩,此刻我都想对你说你真的很棒! 还记得吗,一个人拖着个行李箱,来到陌生的城市二战,只有要去更大的世界的决心和傻气.有的时候会怀疑自 ...
- 题目集8~9总结性Blog
一.前言 对这两次题目集的总结: 这两次题目集相较于上次迭代作业来说,在题目量和难度上都做了下调.但要求我们在理解题目意思.设计好程序结构.掌握并运用知识这三方面有一定的要求.涉及到类的继承与多态,抽 ...
- Intellij Idea 通过svn或者git提交代码时速度慢的解决办法
问题分析:在使用 IntelliJ IDEA 操作Git的时候,Git响应速度特别满,等待差不多10秒.甚至更长时间才完成操作,真是等的花儿都谢了. 解决方案:更改IntelliJ IDE ...
- 如何在 .NET 中构建一个好用的动态查询生成器
前言 自从.NET Framework 3.5提供了LINQ之后,集合数据查询基本被LINQ统一了.这大幅提高了编写数据查询代码的效率和质量,但是在需要编写动态查询的时候反而很困难,特别是最常用的wh ...
- helmfile使用
说明 使用helmfile时,我们首先得了解helm的使用,以及如何开发一个helm chart. helm是kubernetes的包管理工具.在实际的使用场景中我们涉及同时部署多个chart.区分不 ...
- 鸿蒙Next仓颉语言开发实战教程:懒加载
今天要分享的是仓颉开发语言中的懒加载. 先和初学者朋友们解释一下什么是懒加载.懒加载在代码中叫做LazyForEach,看到名字你一定能猜到它和ForEach的功能类似.只不过和ForEach的一次性 ...
- HyperWorks卫星惯性释放分析(OptiStruct)
Step01:读取模型,并设置求解器模板为 OptiStruct. (1) 读入 IGES 格式的几何模型 Exercise_9a.iges. 在绝大多数 CAE 分析中,都将从一个导入的 CAD 模 ...
- 工程师都喜欢的一款自动生成网格的仿真软件——Hyperworks到底好不好用?
HyperWorks是一款广泛应用于工程仿真和优化的软件平台,其中包括了许多强大的工具和功能.其中的网格自动生成工具是其重要组成部分之一,对于工程仿真和优化来说具有重要的意义.那么,HyperWork ...
- Docker + CentOS 部署 Zookeeper 集群 + Kubernetes Operator 自动化运维方案
环境说明 主机 IP 主机名 节点角色 数据目录 Kubernetes 节点标签 192.168.10.100 zk1 Master /opt/zookeeper/data zk-cluster=tr ...