音視訊進階教程-實現直播間的自定義視訊渲染

語言: CN / TW / HK

持續創作,加速成長!這是我參與「掘金日新計劃 · 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 自定義視訊渲染前提條件

在實現自定義視訊渲染功能之前,請確保:

4 自定義視訊渲染使用步驟

自定義視訊渲染的使用流程如下:

  1. 設定自定義視訊渲染配置。
  2. 建立 ZegoExpressEngine 引擎。
  3. 設定自定義視訊渲染器物件並實現回撥方法。
  4. 登入房間後推/拉流,收到自定義視訊渲染視訊幀資料回撥。

API 介面呼叫的時序圖如下

下載.png

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” 和影象之間的關係如圖:

下載2.png

4.3 自定義視訊渲染視訊幀資料回撥

4.3.1 推流預覽渲染

推流方首先需要呼叫啟動預覽介面,才能收到自定義視訊渲染視訊幀資料回撥,如果 ZegoCustomVideoRenderConfig 自定義視訊渲染配置的 “enableEngineRender” 引數為 “false”,啟動預覽的 “canvas” 引數可以傳空,啟動預覽後即可開始推流。

``java // 如需在自定義視訊渲染同時內部也渲染,可將ZegoCustomVideoRenderConfigenableEngineRender引數設為true`,然後在預覽時傳入內部渲染的 View ZegoCanvas previewCanvas = new ZegoCanvas(textureViewLocalPreview);// textureViewLocalPreview為UI介面上的 TextureView 物件 ZegoExpressEngine.getEngine().startPreview(previewCanvas);

// 如僅需自定義視訊渲染,可將 ZegoCustomVideoRenderConfigenableEngineRender 引數設為 falsecanvas 引數傳空即可,但也必須呼叫此介面,否則自定義視訊渲染將不會回撥預覽視訊幀資料 ZegoExpressEngine.getEngine().startPreview(null);

// 開始預覽後,此時將會收到自定義視訊渲染預覽視訊幀資料回撥

// 開始推流 ZegoExpressEngine.getEngine().startPublishingStream(streamid);// streamid為開發者定義的流id ```

4.3.2 視訊拉流渲染

``java // 如需在自定義視訊渲染同時內部也渲染,可將ZegoCustomVideoRenderConfigenableEngineRender引數設為true`,然後在拉流時傳入內部渲染的 View ZegoCanvas playCanvas = new ZegoCanvas(textureViewLocalPreview);// textureViewLocalPreview為UI介面上的 TextureView 物件 ZegoExpressEngine.getEngine().startPlayingStream(streamID, playCanvas);

// 如僅需自定義視訊渲染,可將 ZegoCustomVideoRenderConfigenableEngineRender 引數設為 falsecanvas 引數傳空即可 egoExpressEngine.getEngine().startPlayingStream(streamID, null);

// 開始拉流後,此時將會收到拉的這條流的自定義視訊渲染視訊幀資料回撥 ```

至此,App 成功獲得 SDK 回撥的視訊幀資料,用於實際的渲染動作或者進行深加工操作。

5 獲取 實時音視訊SDK-自定義視訊渲染 功能的更多幫助

獲取本文實時音視訊SDK-自定義視訊渲染的開發文件、技術支援,訪問即構文件中心開發文件頁

近期有開發規劃的開發者可上即構官網檢視,恰逢即構七週年全線音視訊產品1折的優惠,聯絡商務獲取產品優惠;