当你使用 RTC SDK 实现视频内部采集后,在编码传输前,你可以自定义逻辑,对视频帧进行处理。

此功能常用于以下场景:

备注:
RTC SDK 和火山引擎 CV SDK 进行了深度整合,联合提供强大且较下述方案更易集成的 RTC-CV 联合集成方案,详情请咨询技术支持同学。

在这些场景下,你可以参考本文,在 RTC SDK 内部采集和 RTC SDK 传输之间,根据需要添加视频前处理逻辑。

前提条件

你已使用 RTC SDK 提供的视频内部采集机制实现了视频采集,并完成了音视频通话。

集成步骤

以 Android 平台为例:

  1. 根据业务需要,依照 IVideoProcessor,构建视频前处理器。
  2. 调用 registerLocalVideoProcessor 将构建的视频前处理器添加到视频前处理环节。

视频数据流转示意图如下:

image

要取消视频前处理逻辑,调用 registerLocalVideoProcessor 将前处理器设置为 null 即可。

注意事项

在构建视频前处理器时,你应关注 RTC SDK 支持的给出和接收的视频帧格式和像素格式。接入的视频帧前处理器应当与此值匹配。详细说明请查看 API 文档。

API 参考

以下是各个平台的相关 API 参考:

示例代码

Android:

public RTCVideoFrame processFrame(RTCVideoFrame rtcVideoFrame) {
                    int cameraTextureId = rtcVideoFrame.getGlTextureId();
                    int width = rtcVideoFrame.getWidth();
                    int height = rtcVideoFrame.getHeight();
                    int textureId = FuRender.drawFrameSingleInput(cameraTextureId, width, height);
                    if (textureId < 0) {
                        return null;
                    }
                    RTCVideoFrame textureFrame = RTCVideoFrame.createTextureFrame(RTCVideoFrame.PixelFormat.TEXTURE_2D,
                            textureId, width, height, rtcVideoFrame.getRotation(),
                            rtcVideoFrame.getTimestamp(), rtcVideoFrame.getTransform(), null);
                    return textureFrame;
                }
java

iOS:

# pragma mark -- ByteRTCVideoProcessorDelegate
- (ByteRTCVideoFrame *)processFrame:(ByteRTCVideoFrame *)src_frame{
    CVPixelBufferRef pixelBuffer = src_frame.textureBuf;
    CVPixelBufferLockBaseAddress(pixelBuffer, 0);
    int width = (int)CVPixelBufferGetWidth(pixelBuffer);
    int height = (int)CVPixelBufferGetHeight(pixelBuffer);
    // y
    uint8_t* src_y = CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 0);
    const size_t src_ystride = CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer, 0);
    // u
    uint8_t* src_u = CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 1);
    const size_t src_ustride = CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer, 1);
    // v
    uint8_t* src_v = CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 2);
    const size_t src_vstride = CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer, 2);
    [[LPFaceUnityManager sharedManager] processFrame:src_y
                                                   u:src_u
                                                   v:src_v
                                             ystride:(int)src_ystride
                                             ustride:(int)src_ustride
                                             vstride:(int)src_vstride
                                               width:width
                                              height:height];
    CVPixelBufferUnlockBaseAddress(pixelBuffer, 0);
    return src_frame;
}
ObjectiveC