自定义视频前处理
更新时间:2021-02-07 17:47
1 功能简介
当 SDK 自带的美颜无法满足需求,例如需要做挂件、贴纸,或者美颜效果无法达到预期时,推荐开发者使用自定义视频前处理功能。该功能相比于自定义视频采集功能的优势是无需开发者管理设备输入源,仅需对 SDK 抛出来的原始数据进行操作,然后发回 SDK 侧即可。
对于比较复杂的场景,例如想通过摄像头画面做图层混合,建议开发者使用 自定义视频采集 功能实现,该方式性能优化的空间更大。
2 示例源码下载
该示例源码的自定义视频前处理模块集成了 FaceUnity 美颜,若需要体验美颜效果,需要先从相芯科技申请美颜的鉴权证书(请参考 申请指引 中,Android 平台下的“3 运行demo”),再替换示例源码 “zego-express-example-faceunity/android/app/src/main/java/im/zego/expressample/faceu/demo/faceunity” 目录下的 “authpack.java” 文件。
3 前提条件
在进行自定义视频前处理前,请确保已在项目中实现基本的实时音视频功能,详情请参考 快速开始 相关文档。
4 使用步骤
SDK 支持的视频前处理 Buffer 类型如下:
Buffer 类型
枚举值
说明
GLTexture2D
ZegoVideoBufferType.GL_TEXTURE_2D
表示 Texture 纹理类型的原始视频数据,建议熟悉 OpenGL 的开发者使用。
SurfaceTexture
ZegoVideoBufferType.SURFACE_TEXTURE
表示 SurfaceTexture 类型的原始视频数据,建议 Android 开发者使用。
下文以 “ZegoVideoBufferType.SURFACE_TEXTURE” 为例演示自定义视频前处理的用法,其余的 Buffer 类型实现示例请参考 示例源码。
自定义视频前处理的时序图如下:
关键流程如下:
创建 ZegoExpressEngine 引擎。
开启自定义视频前处理功能。
设置自定义视频前处理回调对象并实现对应方法。
调用本地视频预览或推流,同时创建第三方美颜模块。再将收到自定义视频前处理回调通知,获取原始视频数据。
调用第三方美颜 SDK 进行视频处理。
处理完成后,需在同一回调内调用发送视频帧方法向 SDK 提供处理后的视频帧数据。
结束本地视频预览和推流,销毁第三方美颜模块。
4.1 开启自定义视频前处理功能
调用 ZegoCustomVideoProcessConfig 接口创建自定义视频前处理对象,设置 bufferType 属性,用于向 SDK 提供视频帧数据类型。
由于 Android 视频数据类型的多样性,SDK 支持多种视频帧数据类型 bufferType,开发者需告知 SDK 使用的数据类型。目前 SDK 支持如下两种数据类型,设置其他枚举值将无法正常使用:
SurfaceTexture 类型:即 bufferType 取值为 “ZegoVideoBufferType.SURFACE_TEXTURE”
GLTexture2D 类型:即 bufferType 取值为 “ZegoVideoBufferType.GL_TEXTURE_2D”
在开始预览和开始推流前调用引擎的 enableCustomVideoProcessing 接口开启自定义视频前处理功能。
ZegoCustomVideoProcessConfig processConfig = new ZegoCustomVideoProcessConfig();
// 选择 SurfaceTexture 类型视频帧数据
processConfig.bufferType = ZegoVideoBufferType.SURFACE_TEXTURE;
engine.enableCustomVideoProcessing(true, processConfig, ZegoPublishChannel.MAIN);
4.2 设置自定义视频前处理回调
设置自定义视频前处理回调对象,创建 SurfaceTexture 对象。
// 新建匿名类作为自定义视频前处理回调对象
engine.setCustomVideoProcessHandler(new IZegoCustomVideoProcessHandler() {
@Override
public SurfaceTexture getCustomVideoProcessInputSurfaceTexture(int width, int height, ZegoPublishChannel channel) {
// 创建用于 SDK 输入视频数据的 SurfaceTexture
mInputSurfaceTexture = new SurfaceTexture(0);
// 监听此 SurfaceTexture 的数据帧通知,当 SDK 向 SurfaceTexture 的 bufferQueue 写数据时,开发者会收到此回调
mInputSurfaceTexture.setOnFrameAvailableListener(SurfaceTextureDemo.this);
// 获取用于向 SDK 传入处理后数据的 SurfaceTexture,当第三方美颜 SDK 处理完成后,发回给 SDK
mOutputSurfaceTexture = engine.getCustomVideoProcessOutputSurfaceTexture(width, height, channel);
mOutputSurface = new Surface(mOutputSurfaceTexture);
return mInputSurfaceTexture;
}
});
获取原始视频数据,进行第三方美颜处理。
当 SDK 拷贝完原始视频数据后,会通过 “mInputSurfaceTexture” 的 “onFrameAvailable” 方法通知开发者,此后开发者即可调用第三方美颜 SDK 进行视频处理。
如下示例代码片段仅展示关键调用步骤,涉及到 OpenGL 的内容,请开发者直接参考 示例源码。
@Override
public void onFrameAvailable(SurfaceTexture surfaceTexture) {
// 从 bufferQueue 取出数据
surfaceTexture.updateTexImage();
long timestampNs = surfaceTexture.getTimestamp();
// 调用 faceunity 进行美颜,美颜后返回纹理 ID
int textureID = mFuRender.onDrawOesFrame(mInputTextureId, mOutputWidth, mOutputHeight);
// 向 mOutputSurface 的 bufferQueue 写数据
mDrawer.drawRgb(textureID, transformationMatrix, mOutputWidth, mOutputHeight, 0, 0, mOutputWidth, mOutputHeight);
if (mIsEgl14) {
((EglBase14) mEglContext).swapBuffers(timestampNs);
} else {
mEglContext.swapBuffers();
}
}
5 API 参考列表
6 常见问题
提示缺少 FaceUnity 证书?
若需要体验美颜效果,需要先从相芯科技申请美颜的鉴权证书(请参考 申请指引 中,Android 平台下的“3 运行demo”),再替换 “zego-express-example-faceunity/android/app/src/main/java/im/zego/expressample/faceu/demo/faceunity” 目录下的 “authpack.java” 文件。