Custom Video Preprocessing
Feature Overview
Video preprocessing is a process between capture and encoding. Developers capture video data themselves. After obtaining the video data captured by the SDK, they can perform video preprocessing through the SDK's built-in basic beauty effects and watermark features. If the SDK cannot meet developers' needs (for example, the beauty effects cannot achieve the expected results), they can also combine with ZEGO Effects SDK to perform special processing on the video, such as beauty effects, adding accessories, etc. This process is custom video preprocessing.

Compared with custom video capture, custom video preprocessing has the advantage that developers do not need to manage device input sources, they only need to operate on the raw data provided by ZEGO Express SDK, and then send it back to ZEGO Express SDK.
For more complex scenarios, such as wanting to perform layer mixing through camera images, it is recommended that developers use the Custom Video Capture feature to implement it, as this method has greater room for performance optimization.
Example Source Code Download
ZEGO provides example source code for implementing beauty effects through the Effects SDK. Please refer to Using Real-Time Video and AI Beauty Effects Together.
Prerequisites
Before performing custom video preprocessing, please ensure:
- You have created a project in the ZEGOCLOUD Console and applied for a valid AppID and AppSign. For details, please refer to Console - Project Information.
- You have integrated ZEGO Express SDK in your project and implemented basic audio and video streaming functionality. For details, please refer to Quick Start - Integration and Quick Start - Implementation.
Usage Steps
The flow and interface calls for custom video preprocessing are as follows:
Initialize Express SDK and login to Room.
Call the enableCustomVideoProcessing interface to enable custom video preprocessing feature.
Get raw video data and perform video preprocessing.
Call the setCustomVideoProcessHandler interface to register custom video preprocessing callbacks and implement callback methods such as onCapturedUnprocessedTextureData.
Start preview and publish stream.
Through the onStart callback, notify that custom video preprocessing has started. If developers use third-party beauty libraries or pre-allocate memory, they can initialize tools and allocate memory at this time.
Through the onCapturedUnprocessedTextureData callback interface, get raw video data. Developers can perform related processing according to business needs: they can process through Express SDK's built-in basic beauty effects, watermarks and other features; they can also combine with Effects SDK to achieve more processing effects.
After video data processing is completed, in the onCapturedUnprocessedTextureData callback, call the sendCustomVideoProcessedTextureData interface to send the processed video frame data to Express SDK.
Other clients can play the processed video stream.
Stop preview and publishing stream.
Logout from Room.
Through the onStop callback, notify that custom video preprocessing has ended. If developers use third-party beauty libraries or pre-allocate memory, they can deinitialize tools and release memory at this time.
Destroy Engine and release resources.
1 Enable Custom Video Preprocessing
Create a custom video preprocessing ZegoCustomVideoProcessConfig object and set the bufferType property to provide the video frame data type to Express SDK.
Currently Android SDK supports the following 3 types of bufferType data types. Setting other enumeration values will not work properly:
| Buffer Type | Enumeration Value | Description |
|---|---|---|
| GLTexture2D | ZegoVideoBufferType.GL_TEXTURE_2D | Indicates raw video data of Texture texture type. |
| SurfaceTexture | ZegoVideoBufferType.SURFACE_TEXTURE | Indicates raw video data of SurfaceTexture type. |
| GLTexture2DAndRawData | ZegoVideoBufferType.GL_TEXTURE_2D_AND_RAW_DATA | Indicates OpenGL Texture 2D type video frame and raw data type video frame. |
Before starting preview and starting to publish stream, call the enableCustomVideoProcessing interface to enable the custom video preprocessing feature.
The following takes "ZegoVideoBufferType.GL_TEXTURE_2D" as an example to demonstrate the usage of custom video preprocessing.
ZegoCustomVideoProcessConfig config = new ZegoCustomVideoProcessConfig();
// Select GL_TEXTURE_2D type video frame data
config.bufferType = ZegoVideoBufferType.GL_TEXTURE_2D;
// Enable custom preprocessing
express.enableCustomVideoProcessing(true, config, ZegoPublishChannel.MAIN);2 Get Raw Video Data and Perform Video Preprocessing
-
Call the setCustomVideoProcessHandler interface to register custom video preprocessing callbacks and implement callback methods such as onCapturedUnprocessedTextureData.
-
When the SDK obtains raw video data, it will notify the developer through the onCapturedUnprocessedTextureData method.
-
Developers can use Express SDK's built-in basic beauty effects, watermarks and other features to process video data. For details, please refer to Publish Stream Video Enhancement; they can also combine with Effects SDK to achieve more processing effects. For details, please refer to Using Real-Time Video and AI Beauty Effects Together.
-
After processing is completed, call the sendCustomVideoProcessedTextureData interface to send the processed video frame data to Express SDK, which will be published to the stream, and other clients can play the processed video stream.
// Callback method to get raw data
// Callback processing
express.setCustomVideoProcessHandler(new IZegoCustomVideoProcessHandler() {
...
// Receive Texture from ZegoExpressEngine engine
@Override
public void onCapturedUnprocessedTextureData(int textureID, int width, int height, long referenceTimeMillisecond, ZegoPublishChannel channel) {
ZegoEffectsVideoFrameParam param = new ZegoEffectsVideoFrameParam();
param.format = ZegoEffectsVideoFrameFormat.BGRA32;
param.width = width;
param.height = height;
// Custom preprocessing: Use Effects SDK for video processing here
int processedTextureID = effects.processTexture(textureID, param);
// Send the processed buffer back to Express SDK
express.sendCustomVideoProcessedTextureData(processedTextureID, width, height, referenceTimeMillisecond);
}
}