音視訊進階教程-實現直播間的自定義視訊渲染
持續創作,加速成長!這是我參與「掘金日新計劃 · 10 月更文挑戰」的第4天,https://juejin.cn/post/7147654075599978532
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 自定義視訊渲染使用步驟
自定義視訊渲染的使用流程如下:
- 設定自定義視訊渲染配置。
- 建立 ZegoExpressEngine 引擎。
- 設定自定義視訊渲染器物件並實現回撥方法。
- 登入房間後推/拉流,收到自定義視訊渲染視訊幀資料回撥。
API 介面呼叫的時序圖如下
4.1 設定自定義視訊渲染配置
4.1.1 建立 ZegoCustomVideoRenderConfig
物件並配置引數
“bufferType” 引數是列舉 ZegoVideoBufferType
,可指定開發者需要的自定義視訊渲染視訊幀資料型別。
“frameFormatSeries” 引數是列舉 ZegoVideoFrameFormatSeries
,可指定開發者需要的自定義視訊渲染視訊幀資料格式,此引數只能指定 RGB 或 YUV 顏色空間大類,具體的資料格式不同平臺間不一致,以回撥中的引數為準。
“enableEngineRender” 表示是否在要自定義視訊渲染的同時,SDK 內部也渲染。設定為 “false” 時,引擎不會在預覽介面 startPreview
和拉流介面 startPlayingStream
設定的 View 上渲染。
-
介面原型
```java /* * 自定義視訊渲染配置 * * 當需要使用自定義渲染功能時需要將該類的例項作為引數設定給 [ZegoEngineConfig] 例項的對應引數。 / public class ZegoCustomVideoRenderConfig {
/** 自定義視訊渲染視訊幀資料型別 */ public ZegoVideoBufferType bufferType; /** 自定義視訊渲染視訊幀資料格式 */ public ZegoVideoFrameFormatSeries frameFormatSeries; /** 是否在自定義視訊渲染的同時,引擎也渲染 */ public boolean enableEngineRender;
}
```
-
呼叫示例
java ZegoCustomVideoRenderConfig videoRenderConfig = new ZegoCustomVideoRenderConfig(); // 選擇 RAW_DATA 型別視訊幀資料 videoRenderConfig.bufferType = ZegoVideoBufferType.RAW_DATA; // 選擇 RGB 色系資料格式 videoRenderConfig.frameFormatSeries = ZegoVideoFrameFormatSeries.RGB; // 指定在自定義視訊渲染的同時引擎也渲染 videoRenderConfig.enableEngineRender = true;
4.1.2 呼叫 enableCustomVideoRender
介面設定引擎進階配置 videoRenderConfig
-
介面原型
java /** * 開始或停止自定義視訊渲染 * * 必須在引擎啟動前設定,即在呼叫 [startPreview]、[startPublishing]、[startPlayingStream] 之前設定;且在引擎停止之後才能修改配置 * 當開發者開啟自定義渲染時,通過呼叫 [setCustomVideoRenderHandler] 可設定接收本地以及遠端的視訊幀資料以用於自定義渲染 * * @param enable 是否開啟 * @param config 自定義渲染配置 */ public void enableCustomVideoRender(boolean enable, ZegoCustomVideoRenderConfig config);
-
呼叫示例
java 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
介面設定自定義視訊渲染回撥。
-
介面原型
java /** * 設定外部渲染器物件, 使用者傳入自己構造的渲染器物件 IZegoCustomVideoRenderHandler * * @param handler 渲染器物件, 開發者須自行實現渲染器物件須實現的方法並自行渲染視訊到UI上 */ public void setCustomVideoRenderHandler(IZegoCustomVideoRenderHandler handler)
其中的自定義視訊渲染回撥介面 IZegoCustomVideoRenderHandler 定義如下:
```java 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){ }
} ```
-
呼叫示例
```java // 設定自定義視訊渲染回撥並實現丟擲視訊資料的方法
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
物件)描述了該視訊幀的一些引數,定義如下:
```java /* * 視訊幀的引數物件 * * 包括視訊幀的格式、寬高等 / 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” 引數可以傳空,啟動預覽後即可開始推流。
``java
// 如需在自定義視訊渲染同時內部也渲染,可將
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 視訊拉流渲染
``java
// 如需在自定義視訊渲染同時內部也渲染,可將
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折的優惠,聯絡商務獲取產品優惠;