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

語言: CN / TW / HK

持續創作,加速成長!這是我參與「掘金日新計劃 · 10 月更文挑戰」的第4天,http://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折的優惠,聯繫商務獲取產品優惠;