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. 怎么删除Elasticsearch里的index内容
  2. 批量将图片保存到模拟器
  3. Integer overflow, simple but not easy
  4. python播放wav文件_python3 写一个WAV音频文件播放器的代码
  5. git介绍和常用操作
  6. java 类及对象的课后作业_JAVA类和对象课后作业
  7. Report Builder 3.0连接ORACEL数据库
  8. 顺丰同城:拟通过香港IPO发行1.31亿股H股 预期将于12月14日在港交所上市
  9. mongoDB配制及学习
  10. 对Redis单线程的一些看法
  11. html中播放的语法是什么,css语法是什么?
  12. 飞利浦DR与PACS进行worklist多部位登记方法分享
  13. QQ空间官方账号被黑产利用漏洞分析
  14. 【中兴笔试题】三角形面积
  15. 建议直接收藏,阿里巴巴开源15个顶级Java项目
  16. python boxplot的使用方法
  17. 【python学习】自定义三维向量类 加减乘除查看值和长度
  18. Excel if及ifs函数用法
  19. Apollo(阿波罗)架构深度剖析
  20. Tomcat部署与优化

热门文章

  1. 【嵌入式开发基础】gn ninja命令安装
  2. selenium实现后台24小时平均温、全国降水量自动上传工作
  3. 非参数估计—Parzen窗与K-nearest-neighbor
  4. c# php md5 32位加密,C#实现将32位MD5摘要串转换为128位二进制字符串的方法
  5. 电子西塔琴音源 Orange Tree Samples Evolution Sitardelic Kontakt
  6. 深度原创丨当互联网巨头从云端“抄底” BI 和大数据...
  7. 如何宣传推广自己的博客啊?
  8. 话机按键音效——DTMF生成
  9. qduoj 生化危机ycb老师的电脑中毒了(邻接表)
  10. android绑定交通卡,安卓手机公交卡的用法