1 自定义视频渲染的功能简介

自定义视频渲染指的是 SDK 向外部提供本地预览及远端拉流的视频帧数据,供用户自行渲染。

当开发者业务中出现以下情况时,推荐使用 即构实时音视频SDK 的自定义视频渲染功能:

  • App 使用了跨平台界面框架(例如 Qt 需要有复杂层级关系的界面以实现高体验的交互)或游戏引擎(例如 Unity3D、Cocos2d-x 等)。
  • App 需要获取 SDK 采集或拉流的视频帧数据进行特殊处理。

2 自定义视频渲染示例源码下载

请参考 下载示例源码 获取源码。

相关源码请查看 “/ZegoExpressExample/AdvancedVideoProcessing/src/main/java/im/zego/customrender” 目录下的文件。

3 自定义视频渲染前提条件

在实现自定义视频渲染功能之前,请确保:

  • 已在项目中集成 ZEGO Express SDK,实现基本的实时音视频功能,详情请参考 快速开始 - 集成 和 快速开始 - 实现视频通话。
  • 已在 ZEGO 控制台 创建项目,并申请有效的 AppID 和 AppSign,详情请参考 控制台 - 项目管理 中的“项目信息”。

4 自定义视频渲染使用步骤

自定义视频渲染的使用流程如下:

  1. 设置自定义视频渲染配置。
  2. 创建 ZegoExpressEngine 引擎。
  3. 设置自定义视频渲染器对象并实现回调方法。
  4. 登录房间后推/拉流,收到自定义视频渲染视频帧数据回调。

API 接口调用的时序图如下

4.1 设置自定义视频渲染配置

4.1.1 创建 ZegoCustomVideoRenderConfig 对象并配置参数

“bufferType” 参数是枚举 ZegoVideoBufferType,可指定开发者需要的自定义视频渲染视频帧数据类型。

“frameFormatSeries” 参数是枚举 ZegoVideoFrameFormatSeries,可指定开发者需要的自定义视频渲染视频帧数据格式,此参数只能指定 RGB 或 YUV 颜色空间大类,具体的数据格式不同平台间不一致,以回调中的参数为准。

“enableEngineRender” 表示是否在要自定义视频渲染的同时,SDK 内部也渲染。设置为 “false” 时,引擎不会在预览接口 startPreview 和拉流接口 startPlayingStream 设置的 View 上渲染。

  • 接口原型

    /*** 自定义视频渲染配置** 当需要使用自定义渲染功能时需要将该类的实例作为参数设置给 [ZegoEngineConfig] 实例的对应参数。*/
    public class ZegoCustomVideoRenderConfig {/** 自定义视频渲染视频帧数据类型 */public ZegoVideoBufferType bufferType;/** 自定义视频渲染视频帧数据格式 */public ZegoVideoFrameFormatSeries frameFormatSeries;/** 是否在自定义视频渲染的同时,引擎也渲染 */public boolean enableEngineRender;}
  • 调用示例

    ZegoCustomVideoRenderConfig videoRenderConfig = new ZegoCustomVideoRenderConfig();
    // 选择 RAW_DATA 类型视频帧数据
    videoRenderConfig.bufferType = ZegoVideoBufferType.RAW_DATA;
    // 选择 RGB 色系数据格式
    videoRenderConfig.frameFormatSeries = ZegoVideoFrameFormatSeries.RGB;
    // 指定在自定义视频渲染的同时引擎也渲染
    videoRenderConfig.enableEngineRender = true;
    

4.1.2 调用 enableCustomVideoRender 接口设置引擎进阶配置 videoRenderConfig

  • 接口原型

    /*** 开始或停止自定义视频渲染** 必须在引擎启动前设置,即在调用 [startPreview]、[startPublishing]、[startPlayingStream] 之前设置;且在引擎停止之后才能修改配置* 当开发者开启自定义渲染时,通过调用 [setCustomVideoRenderHandler] 可设置接收本地以及远端的视频帧数据以用于自定义渲染** @param enable 是否开启* @param config 自定义渲染配置*/
    public void enableCustomVideoRender(boolean enable, ZegoCustomVideoRenderConfig config);
    
  • 调用示例

    ZegoCustomVideoRenderConfig videoRenderConfig = new ZegoCustomVideoRenderConfig();
    // 选择 RAW_DATA 类型视频帧数据
    videoRenderConfig.bufferType = ZegoVideoBufferType.RAW_DATA;
    // 选择 RGB 色系数据格式
    videoRenderConfig.frameFormatSeries = ZegoVideoFrameFormatSeries.RGB;
    // 指定在自定义视频渲染的同时引擎也渲染
    videoRenderConfig.enableEngineRender = true;
    engine.enableCustomVideoRender(true, videoRenderConfig);
    

4.2 设置自定义视频渲染器对象并实现回调方法

调用 setCustomVideoRenderHandler 接口设置自定义视频渲染回调。

  • 接口原型

    /*** 设置外部渲染器对象, 用户传入自己构造的渲染器对象 IZegoCustomVideoRenderHandler** @param handler 渲染器对象, 开发者须自行实现渲染器对象须实现的方法并自行渲染视频到UI上*/
    public void setCustomVideoRenderHandler(IZegoCustomVideoRenderHandler handler)
    

    其中的自定义视频渲染回调接口 IZegoCustomVideoRenderHandler 定义如下:

    public abstract class IZegoCustomVideoRenderHandler {/*** 本地预览视频帧裸数据回调** @param data 视频帧的裸数据(例:RGBA 只需考虑 data[0],I420 需考虑 data[0,1,2])* @param dataLength 数据的长度(例:RGBA 只需考虑 dataLength[0],I420 需考虑 dataLength[0,1,2])* @param param 视频帧参数* @param flipMode 视频帧翻转模式* @param channel 推流通道*/public void onCapturedVideoFrameRawData(ByteBuffer[] data, int[] dataLength, ZegoVideoFrameParam param, ZegoVideoFlipMode flipMode, ZegoPublishChannel channel){}/*** 远端拉流视频帧裸数据回调,通过 streamID 区分不同的流** @param data 视频帧的裸数据(例:RGBA 只需考虑 data[0],I420 需考虑 data[0,1,2])* @param dataLength 数据的长度(例:RGBA 只需考虑 dataLength[0],I420 需考虑 dataLength[0,1,2])* @param param 视频帧参数* @param streamID 拉流的流 ID*/public void onRemoteVideoFrameRawData(ByteBuffer[] data, int[] dataLength, ZegoVideoFrameParam param, String streamID){}}
    
  • 调用示例

    // 设置自定义视频渲染回调并实现抛出视频数据的方法engine.setCustomVideoRenderHandler(new IZegoCustomVideoRenderHandler(){public void onCapturedVideoFrameRawData(ByteBuffer[] data, int[] dataLength, ZegoVideoFrameParam param, ZegoVideoFlipMode flipMode, ZegoPublishChannel channel){// 在采集端的回调里通过 data, dataLength, param 等参数实现将本地采集的视频数据渲染到View的逻辑, 所抛出的数据格式参考 param.format...;}public void onRemoteVideoFrameRawData(ByteBuffer[] data, int[] dataLength, ZegoVideoFrameParam param, String streamID){// 在拉流端的回调里通过 data, dataLength, param 等参数实现将所拉的流的视频数据渲染到View的逻辑, 所抛出的数据格式参考 param.format...;}
    });
    

本地预览采集视频帧回调方法中的 flipMode 参数与镜像有关,通知开发者是否需要自行将视频帧画面做翻转,以使画面符合 setVideoMirrorMode 中设置的 ZegoVideoMirrorMode 枚举值的描述.

以上回调方法中的 “param” 参数(ZegoVideoFrameParam 对象)描述了该视频帧的一些参数,定义如下:

/*** 视频帧的参数对象** 包括视频帧的格式、宽高等*/
public class ZegoVideoFrameParam {/** 视频帧的格式 */public ZegoVideoFrameFormat format;/** 每个平面一行字节数(此参数为 int 数组,数组长度为4,RGBA 只需考虑 strides[0],I420 需考虑 strides[0,1,2]) */final public int[] strides = new int[4];/** 视频帧的画面宽 */public int width;/** 视频帧的画面高 */public int height;}

其中 “format” 标识了该视频帧的具体数据格式,“strides” 为数组,描述每个平面一行字节数,“size” 描述视频帧的画面尺寸。“strides” 和图像之间的关系如图:

4.3 自定义视频渲染视频帧数据回调

4.3.1 推流预览渲染

推流方首先需要调用启动预览接口,才能收到自定义视频渲染视频帧数据回调,如果 ZegoCustomVideoRenderConfig 自定义视频渲染配置的 “enableEngineRender” 参数为 “false”,启动预览的 “canvas” 参数可以传空,启动预览后即可开始推流。

// 如需在自定义视频渲染同时内部也渲染,可将 `ZegoCustomVideoRenderConfig` 的 `enableEngineRender` 参数设为 `true`,然后在预览时传入内部渲染的 View
ZegoCanvas previewCanvas = new ZegoCanvas(textureViewLocalPreview);// textureViewLocalPreview为UI界面上的 TextureView 对象
ZegoExpressEngine.getEngine().startPreview(previewCanvas);// 如仅需自定义视频渲染,可将 `ZegoCustomVideoRenderConfig` 的 `enableEngineRender` 参数设为 `false`,`canvas` 参数传空即可,但也必须调用此接口,否则自定义视频渲染将不会回调预览视频帧数据
ZegoExpressEngine.getEngine().startPreview(null);// 开始预览后,此时将会收到自定义视频渲染预览视频帧数据回调// 开始推流
ZegoExpressEngine.getEngine().startPublishingStream(streamid);// streamid为开发者定义的流id

4.3.2 视频拉流渲染

// 如需在自定义视频渲染同时内部也渲染,可将 `ZegoCustomVideoRenderConfig` 的 `enableEngineRender` 参数设为 `true`,然后在拉流时传入内部渲染的 View
ZegoCanvas playCanvas = new ZegoCanvas(textureViewLocalPreview);// textureViewLocalPreview为UI界面上的 TextureView 对象
ZegoExpressEngine.getEngine().startPlayingStream(streamID, playCanvas);// 如仅需自定义视频渲染,可将 `ZegoCustomVideoRenderConfig` 的 `enableEngineRender` 参数设为 `false`,`canvas` 参数传空即可
egoExpressEngine.getEngine().startPlayingStream(streamID, null);// 开始拉流后,此时将会收到拉的这条流的自定义视频渲染视频帧数据回调

至此,App 成功获得 SDK 回调的视频帧数据,用于实际的渲染动作或者进行深加工操作。

5 获取 实时音视频SDK-自定义视频渲染 功能的更多帮助

获取本文实时音视频SDK-自定义视频渲染的开发文档、技术支持,访问即构文档中心开发文档页

音视频进阶教程|实现直播间的自定义视频渲染相关推荐

  1. 音视频进阶:浅谈Android 开发音视频入门之路

    很多开发者都知道Android音视频开发这个概念,音视频开发不仅需要掌握图像.音频.视频的基础知识,并且还需要掌握如何对它们进行采集.渲染.处理.传输等一系列的开发和应用,因此,音视频开发是一门涉及到 ...

  2. 首席新媒体黎想教程:直播间流量低?试试这几招!

    直播间没人,应该是困扰99%主播最大的问题.没人就没有转化,关键是直播间没人的时候,主播的情绪也会大受影响. 今天这篇文章纯干货,价值巨大.也是我们在抖音直播带货半年的一些心得总结和体会. 先自我介绍 ...

  3. 抖音uv价值怎么计算?直播间如何提高uv价值?

    在抖音上面存在一些专业的术语,想做好抖音视频的达人们,务必要去了解.今天的文章就跟大家全方面聊一下抖音uv价值的问题,感兴趣的朋友,不妨一看. 抖音uv价值怎么计算 UV价值=销售额/访客数,销售额= ...

  4. 青岛新媒体运营教程:直播间封面,以及直播标题创作方法

    直播封面是用户进入直播间的一个桥梁,其实,除了直播封面之外,直播标题也是影响观众是否会进入直播间的关键因素. 根据相关统计,设置了封面的直播间,比使用默认头像的直播间观看人数要多得多. 青岛艺形艺意文 ...

  5. 新媒体运营教程:直播间高转化活动如何策划!

    一.私域直播的逻辑和作用 如今,直播似乎已经成为企业曝光品牌提销量的标配,这些都让越来越多的商家见识到了直播的威力. 但是,并不是每一个商家都请得起李佳琦.薇娅这样的大主播为自己带货的.一方面,稍微红 ...

  6. uniapp微信支付宝小程序跳转视频号财富号直播间

    项目背景:uniapp开发多端小程序,分别为微信和支付宝,要求在微信环境进入视频号直播间,在支付宝环境跳转到财富号直播间. 视频号直播 | 微信开放文档 (qq.com) // 注意需要在真机调试查看 ...

  7. Redis进阶教程—基础篇-叶向阳-专题视频课程

    Redis进阶教程-基础篇-217人已学习 课程介绍         该系列教程涵盖了redis的方方面面,大亮点是实战经验分享总结.系列视频包含Redis基础篇.Redis提升篇.从零编写Redis ...

  8. 【直播教程】直播间没人看?5大技巧教你提升!

    直播是连接店铺.品牌.产品和消费者之间的桥梁.人是视觉动物,店铺的产品.团队和服务是后端的内容,产品再好,团队再强大,前端的消费者看不到,背后的努力都是徒然.所以,在粉丝对店铺.对品牌不熟悉的情况下, ...

  9. 新媒体运营胡耀文教程:直播间10大话术总结,互动话术不冷场

    不知道说什么,不知道怎么说,直播间没人,直播间冷场,这是很多新手主播都会遇到的问题.总结了直播间的10大话术,希望对大家有所帮助. 很多主播,尤其是新人主播,开始和陌生人聊天的时候会感觉到害羞.紧张, ...

最新文章

  1. 4springboot:日志(上)
  2. wxWidgets编程笔记二(samples使用设置)
  3. Linux桌面极速文件浏览器PCMan
  4. jQuery.extend()方法
  5. css动画定义,CSS3中Animation动画的定义和调用
  6. 网络工程师交换试验手册之二十五:详细讲授利用xmodem来恢复IOS
  7. 用Entlib的配置程序块遇到的问题
  8. 智慧、智能图书馆管理平台系统+web端业务数据管理平台+Axure通用web端高保真交互业务数据管理平台+铭牌管理+设备监控+系统管理+内容管理+机构列表管理+用户权限管理+专题管理+服务包管理
  9. android卸载弹出窗口,卸载Android app弹出浏览器的一种实现
  10. JAVA中Unicode输出_java输出全部unicode字符
  11. linux结课考试试题,Linux认证考试课后基础试题及答案
  12. 招银网络-信息科技风险管理工程师-笔试-安全
  13. Unity Compute Shader入门(大量对象随机赋值颜色实验)
  14. Cesium为3dTile模型添加气泡框
  15. android 即时通讯技术,基于Android即时通讯系统的设计与实现
  16. 阿里二面一问MySQL就开始野了,抓着底层原理不撒手啊!
  17. UML选择题复习题库
  18. 手势识别:使用EfficientNet模型迁移、VGG16模型迁移
  19. 由于应用程序的配置不正确,应用程序未能启动,重新安装应用程序可能会纠正这个问题
  20. 关于MYSQL:什么是MySQL?为什么用MySQL?

热门文章

  1. Java实现高数的收敛级数和不定积分求圆周率
  2. 使用多个icon 字体图标库样式冲突问题
  3. ElasticSearch - 玩转搜索之花式查询
  4. vue停止指令_一个微小的Vue指令,当到达边缘时停止传播滚动
  5. ThreadPoolExecutor源码
  6. 2019年,P2P的春天会来临吗?
  7. 【Java:线程与进程 详解+案例】
  8. Corral the Cows赶牛入圈(二维离散化)
  9. 安全:屏蔽恶意网站 恶意网址库
  10. Acrobat Pro DC 教程:了解 Acrobat Pro DC 界面