You need to enable JavaScript to run this app.
导航

Native 端自定义视频处理

最近更新时间2024.02.28 18:03:31

首次发布时间2021.11.26 16:28:05

使用 RTC SDK 实现视频内部采集或外部自定义采集后,在渲染和编码传输前,你可以对视频帧进行自定义处理,并传回 RTC SDK 进行本地预览和编码发送。例如以下场景:

  • RTC SDK 自带的美颜特效功能智能美化特效(CV)SDK 均无法满足你的业务需求时,你可以通过接入第三方美颜 SDK,对视频进行处理。

  • RTC SDK 当前的视频处理功能无法满足业务需求时。目前已支持的前处理功能包括视频降噪、HRD、数字变焦、镜像、旋转、水印等。

前提条件

你已经集成 RTC SDK,实现了基本的音视频通话。
支持视频自定义处理功能的 SDK 详见API 参考

功能说明

适用范围

  • 适用于:内部摄像头采集视频流、外部自定义摄像头采集视频流
  • 不适用于:内部屏幕采集视频流、外部自定义屏幕采集视频流、静态图

此功能在视频处理链路的位置

alt

功能实现

本文以接入第三方美颜 SDK 为例,介绍 RTC SDK 的自定义视频处理的实现方法。参考步骤描述和示例代码,将涉及到美颜处理的部分替换为实际的实现代码。

API 时序图

alt

1. 实现视频处理器接口

首先,你需要自行实现 IVideoProcessor 接口。

public class VideoProcessor extends IVideoProcessor {
    @Override
    public VideoFrame processVideoFrame(VideoFrame frame) {}
    }

2. 注册视频处理器

实现 IVideoProcessor 接口后,你需要将其注册进 RTC SDK 中,只有完成注册后,自定义视频处理器才会获取到采集的视频帧。在注册时,你可以指定 RTC SDK 返回给 IVideoProcessor.processVideoFrame 的视频帧格式。

注意:重复调用 registerLocalVideoProcessor 接口时,仅最后一次调用生效。

// 返回的视频帧格式仅支持 I420 和 TEXTURE_20
private void setVideoProcessor(){
    VideoPreprocessorConfig config = new VideoPreprocessorConfig();
    config.requiredPixelFormat = VideoPixelFormat.TEXTURE_2D;
    rtcVideo.registerLocalVideoProcessor(customVideoProcessor, config);
}

3. 完成自定义视频处理

将自定义视频处理器注册到 RTC SDK 后,App 会通过 IVideoProcessor.processVideoFrame 回调收到采集的视频帧,你需要在这里完成自定义的视频处理操作。以下示例代码以第三方美颜为例,说明如何处理视频帧。

public VideoFrame processI420Frame(VideoFrame frame) {

        if (!renderSwitch) {
            return frame;
        }

        int width = frame.getWidth();
        int height = frame.getHeight();
        
        // 美颜处理      

        CpuBufferVideoFrameBuilder builder = new CpuBufferVideoFrameBuilder(VideoPixelFormat.I420);
        builder.setWidth(width)
                .setHeight(height)
                .setRotation(frame.getRotation()) // set rotation back if rotation has not been changed.
                .setTimeStampUs(frame.getTimeStampUs())
                .setColorSpace(frame.getColorSpace())
                .setPlaneData(0, frame.getPlaneData(0))
                .setPlaneData(1, frame.getPlaneData(1))
                .setPlaneData(2, frame.getPlaneData(2))
                .setPlaneStride(0, frame.getPlaneStride(0))
                .setPlaneStride(1, frame.getPlaneStride(1))
                .setPlaneStride(2, frame.getPlaneStride(2))
                .setReleaseCallback(() -> {
                });

        return builder.build();
    }
// 注意:
// - 返回纹理视频帧给 RTC SDK时,需要通过 GLTextureVideoFrameBuilder 辅助构建。
// - 在构建返回的视频帧时,如果你没有处理旋转变换,请将原始的旋转角度设置过来。

4. 返回自定义处理视频

经过自定义视频处理后,在 IVideoProcessor.processVideoFrame 中构建的视频帧返回值将被返回给 RTC SDK 进行后续的处理。
各端对返回 RTC SDK 的视频帧格式支持如下

平台内存类型支持的视频帧像素格式

iOS/Mac

kVideoFrameTypeRawMemory

支持NV12格式的数据

kVideoFrameTypeCVPixelBuffer支持I420、NV12、BGRA、ARGB格式的数据
AndroidkVideoFrameTypeRawMemory支持I420、NV12、NV21、RGBA格式的数据
kVideoFrameTypeGLTexture支持Texture2D、TextureOES格式的数据
Windows/LinuxkVideoFrameTypeRawMemory支持I420、NV12、RGBA、BGRA、ARGB格式的数据

5. 取消注册视频处理器

通过调用 registerLocalVideoProcessor 并将其中的 IVideoProcessor 设置为 null 来实现取消注册自定义视频处理器。完成取消注册之后,你将不会再通过 IVideoProcessor.processVideoFrame 收到采集的视频帧。

示例项目

API 参考

你可以根据上文的描述和示例,使用以下客户端 SDK,在不同的端上实现自定义视频处理。

表格中的 macOS API 接口为 Objective-C,而示例项目中的 macOS 项目使用的是 Windows SDK 中的 API 接口。

平台AndroidiOSmacOSWindowsLinux
视频处理器接口IVideoProcessorByteRTCVideoProcessorDelegateByteRTCVideoProcessorDelegateIVideoProcessorIVideoProcessor
注册视频处理器registerLocalVideoProcessorregisterLocalVideoProcessor:withConfig:registerLocalVideoProcessor:withConfig:RegisterLocalVideoProcessorRegisterLocalVideoProcessor