实时音视频
  • iOS
  • Android : Java
  • macOS
  • Windows
  • HarmonyOS
  • Linux
  • Web
  • 小程序
  • Flutter
  • Electron
  • Unity3D
  • uni-app
  • React Native
  • Cocos2D
  • 产品简介
  • 下载
  • 体验 App
  • 快速开始
    • 跑通示例源码
    • 集成 SDK
    • 实现视频通话
    • 实时音视频 SDK 与实时语音 SDK 差异
  • 基础功能
  • 进阶功能
  • 最佳实践
  • 常见错误码
  • 服务端 API
  • 客户端 API
  • 常见问题

自定义视频采集

更新时间:2022-07-28 14:51

1 功能简介

自定义视频采集的功能指的是由开发者自定义向 ZegoExpressEngine SDK 提供视频输入源输入视频数据,并由 ZegoExpressEngine SDK 进行编码推流的功能。当用户开启自定义视频采集的功能后,默认情况下,ZegoExpressEngine SDK 在推流端内部将对本端预览画面进行渲染,用户无需自行进行渲染。

当开发者业务中出现以下情况时,推荐使用 SDK 的自定义视频采集功能:

  • 开发者开发的 App 使用了第三方美颜厂商的美颜 SDK,可以直接对接 ZegoExpressEngine SDK 的自定义视频采集功能。即由第三方美颜厂商的美颜 SDK 负责视频数据的采集,视频数据的前处理,由 ZegoExpressEngine SDK 负责视频数据的编码以及将音视频流推到 ZEGO 音视频云端。
  • 直播过程中,开发者需要使用摄像头完成的额外功能和 ZegoExpressEngine SDK 的默认的视频采集逻辑有冲突,导致摄像头无法正常使用。例如,直播到一半,需要录制短视频。
  • 直播非摄像头采集的数据。例如本地视频文件播放、屏幕分享、游戏直播等。

2 示例源码下载

请参考 下载示例源码 获取源码。

相关源码请查看 “/ZegoExpressExample/AdvancedVideoProcessing/src/main/java/im/zego/CustomerVideoCapture” 目录下的文件。

3 前提条件

在进行自定义视频采集前,请确保:

4 使用步骤

自定义视频采集的使用流程如下:

  1. 创建 ZegoExpressEngine 引擎。
  2. 开启自定义视频采集功能。
  3. 设置自定义视频采集回调对象并实现对应方法。
  4. 登录房间并推流,将收到自定义视频采集回调通知开始采集。
  5. 调用发送视频帧方法向 SDK 提供视频帧数据。
  6. 结束推流,将收到自定义视频采集回调通知停止采集。

API 接口调用的时序图如下:

开启自定义视频采集功能时需要将 enableCamera 接口保持默认配置 “True” ,否则推流没有视频数据。

4.1 开启自定义视频采集功能

调用 ZegoCustomVideoCaptureConfig 接口创建自定义视频采集对象,设置属性 bufferType,向 SDK 提供视频帧数据类型;调用接口 enableCustomVideoCapture 开启自定义视频采集功能。

由于 Android 采集的多样性,SDK 支持多种视频帧数据类型 bufferType,开发者需告知 SDK 使用的数据类型。目前 SDK 支持裸数据类型 “RAW_DATA”、GLTexture2D 类型 “GL_TEXTURE_2D” 和编码类型 “ENCODED_DATA”,设置其他枚举值将无法向 SDK 提供视频帧数据。

ZegoCustomVideoCaptureConfig videoCaptureConfig = new ZegoCustomVideoCaptureConfig();
// 选择 RAW_DATA 类型视频帧数据
videoCaptureConfig.bufferType = ZegoVideoBufferType.RAW_DATA;

engine.enableCustomVideoCapture(true, videoCaptureConfig, ZegoPublishChannel.MAIN);

4.2 设置自定义视频采集回调

调用 setCustomVideoCaptureHandler 设置自定义视频采的通知集回调,实现 onStartonStop 自定义采集回调方法。

// 将自身作为自定义视频采集回调对象
sdk.setCustomVideoCaptureHandler(new IZegoCustomVideoCaptureHandler() {
    @Override
    public void onStart(ZegoPublishChannel channel) {
        // 收到回调后,开发者需要执行启动视频采集相关的业务逻辑,例如开启摄像头等
        ...
    }
    @Override
    public void onStop(ZegoPublishChannel channel) {
        // 收到回调后,开发者需要执行停止视频采集相关的业务逻辑,例如关闭摄像头等
        ...
    }
});

4.3 向 SDK 发送视频帧数据

调用开始预览接口 startPreview 或者开始推流接口 startPublishingStream 后,将会收到 onStart 回调;开发者启动采集相关的业务逻辑后,调用发送自定义采集的视频帧数据接口向 SDK 发送视频帧数据,自定义采集的视频帧数据接口与 4.1 开启自定义视频采集功能 中向 SDK 提供视频帧数据类型 bufferType 一一对应:

视频帧类型 bufferType 发送视频帧数据接口
裸数据类型 RAW_DATA sendCustomVideoCaptureRawData
GLTexture2D 类型 GL_TEXTURE_2D sendCustomVideoCaptureTextureData
GL_TEXTURE_EXTERNAL_OES 类型 GL_TEXTURE_EXTERNAL_OES sendCustomVideoCaptureTextureData
编码类型 ENCODED_DATA sendCustomVideoCaptureEncodedData

以下代码是调用 sendCustomVideoCaptureRawData 接口向 SDK 发送视频帧数据。

// 将采集的数据传给ZEGO SDK
// Pass the collected data to ZEGO SDK
if (byteBuffer == null) {
    byteBuffer = ByteBuffer.allocateDirect(data.length);
}
byteBuffer.put(data);
byteBuffer.flip();

mSDKEngine.sendCustomVideoCaptureRawData(byteBuffer, data.length, param, now);

停止推流/预览后,退出房间或销毁引擎时,将会收到 onStop 回调,开发者可停止采集相关的业务逻辑,例如关闭摄像头等。

4.4 (可选)设置自定义采集画面的转换矩阵

  1. 该功能仅当 4.1 开启自定义视频采集功能 中设置的自定义采集类型为 “Texture2D” 时才有效。
  2. 建议具有一定 OpenGL 开发经验的开发者使用该功能。

收到 onStart 回调后,可以根据需要调用 setCustomVideoCaptureTransformMatrix 接口设置指定通道的自定义采集画面转换矩阵,包括旋转、翻转、缩放。

matrix 参数可以参考方法 SurfaceTexture.getTransformMatrix 获取。

4.5 (可选)设置自定义采集设备状态

推流端通过 setCustomVideoCaptureDeviceState 设置设备状态为 ZegoRemoteDeviceState.DISABLE 或 ZegoRemoteDeviceState.MUTE 都无效,即拉流端无法收到 onRemoteCameraStateUpdate 回调。

当推流端通过 enableCamera 关闭摄像头时,拉流端会在 onRemoteCameraStateUpdate 回调中收到 ZegoRemoteDeviceState.DISABLE 状态;当推流端通过 mutePublishStreamVideo 不推视频流时,拉流端会在 onRemoteCameraStateUpdate 回调中收到 ZegoRemoteDeviceState.MUTE 状态。

收到 onStart 回调后,可以根据需要调用 setCustomVideoCaptureDeviceState 接口设置指定推流通道的自定义采集设备状态。

拉流端可以通过监听 onRemoteCameraStateUpdate 回调获取推流端设备状态。

5 API 参考列表

方法 描述
enableCustomVideoCapture 设置引擎进阶配置
setCustomVideoCaptureHandler 设置自定义视频采集回调
onStart SDK 通知将要开始采集视频帧
onStop SDK 通知将要停止采集视频帧
sendCustomVideoCaptureRawData 向 SDK 发送原始视频帧数据
sendCustomVideoCaptureTextureData 向 SDK 发送 Texture 视频帧数据

6 常见问题

  1. 如何使用 “OpenGL Texture 2D 类型” 方式传递采集数据?

    4.1 开启自定义视频采集功能 中的配置 ZegoCustomVideoCaptureConfig bufferType 参数选择 GLTexture2D 类型 GL_TEXTURE_2D,然后调用 sendCustomVideoCaptureTextureData 方法。

  2. 使用自定义视频采集,本地预览的画面正常,推出去观众端看到的画面变形了?

    自定义视频采集进来的图像比例和 SDK 默认设置的分辨率的比例不一致(比如自定义视频采集进来的视频帧画面比例是 4:3,SDK 默认推流画面分辨率比例是 16:9)。解决方案:

    • 方案一:开发者自行将自定义视频采集的视频分辨率比例修改为 16:9。

    • 方案二:开发者调用 setVideoConfig,将 SDK 的推流分辨率比例自定义为 4:3。

    • 方案三:开发者调用 setCustomVideoCaptureFillMode 方法,设置为 “ASPECT_FIT” 等比缩放(带黑边)或者 “ASPECT_FILL” 等比填充(画面被裁剪)模式。

  3. 开启自定义视频采集后,采集的帧率和拉流播放帧率不一致?

    当自定义采集的帧率和拉流播放帧率不一致时,可以通过如下方式处理:

  4. SDK 接收视频帧数据方法内部对传入的数据是同步处理还是异步处理?

    SDK 接收视频帧数据后,会先同步拷贝数据,然后再异步执行编码等操作,所以在将数据传入 SDK 后即可立即释放。

  1. 如何在自定义视频采集时实现视频旋转?

    当开发者使用 自定义视频采集 时,监听设备方向变化后,可参考以下两种方式实现横竖屏切换:

    • 自行处理视频帧数据:在设备方向变化的回调中,对采集到的视频帧数据做旋转处理,再将处理后的数据通过 sendCustomVideoCaptureTextureData 接口传给 SDK。
    • 通过 SDK 处理视频帧数据:在设备方向变化的回调中,在将采集到的视频帧数据传给 SDK 之前,根据实际朝向设置 ZegoVideoEncodedFrameParam 中的 “rotation”,调用 sendCustomVideoCaptureEncodedData 接口传入视频帧数据和设置朝向的参数,将数据传给 SDK。

相关文档