音視頻進階教程-實現直播間的自定義視頻渲染
持續創作,加速成長!這是我參與「掘金日新計劃 · 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折的優惠,聯繫商務獲取產品優惠;