功能介绍
除了音视频 SDK 音视频模块内部默认的采集和渲染外,下场景需求默认视频模块可能无法满足需求:
- 有自己的音频或者视频模块
- 希望推送非采集的视频源(如屏幕数据)
- 有自己的美颜或经过前处理后的数据
- 有自己视频采集设备管理
anyRTC 自采集和渲染包括 Push 和 mediaIO 两种自定义视频采集方式:
**Push 方式:**调用 setExternalVideoSource
方法告知 SDK 使用外置的视频源。外置视频源通过 pushVideoFrame
发送给 SDK 。你可以使用自渲染模块对采集的视频进行渲染。
anyRTC SDK 对该模式不在支持渲染,渲染模块通过自采集自行处理;使用该模式无法切换回 SDK 采集。
**mediaIO 方式:**调用 setVideoSource
方法告知 SDK 使用外置的视频源,外置视频源通过 consumeRawVideoFrame
发送给 SDK。你可以使用自渲染模块对采集的视频进行渲染。
C++ SDK 暂不提供专门的自定义视频渲染接口。你必须通过自采集的方式实现自渲染功能。即,自渲染模块的视频帧输入只能从自采集模块获取。
实现方法(Push 方式)
操作步骤
自定义视频采集和播放前,请确保已实现基本的音视频功能。
- 在
joinChannelByToken
前通过调用setExternalVideoSource
指定外部视频采集设备。 - 指定外部采集设备后,开发者自行管理视频数据采集和处理。
- 完成视频数据处理后,再通过
pushExternalVideoFrame
发送给 SDK 进行后续操作。
为满足实际使用需求,你可以在将视频数据发送回 SDK 前,通过 ARVideoFrame
修改视频数据。比如,设置 rotation
为 180,使视频帧顺时针旋转 180 度。
API 调用时序
示例代码
// Swift
// 推入数据类型为 CVPixelBufferRef
let videoFrame = ARVideoFrame()
videoFrame.format = 12
// [NSDate date].timeIntervalSince1970 为当前时间戳;1000 表示每秒钟 1000 帧
videoFrame.time = CMTimeMakeWithSeconds([NSDate date].timeIntervalSince1970, 1000)
videoFrame.textureBuf = "Your CVPixelBufferRef"
videoFrame.ratation = 0
// 推入数据类型为 rawData
let videoFrame = ARVideoFrame()
videoFrame.format = "your data fromat"
// [NSDate date].timeIntervalSince1970 为当前时间戳;1000 表示每秒钟 1000 帧
videoFrame.time = CMTimeMakeWithSeconds([NSDate date].timeIntervalSince1970, 1000)
videoFrame.strideInPixels = "your stride"
videoFrame.height = "your height"
videoFrame.dataBuf = "your rawData"
videoFrame.ratation = 0
rtcKit.pushExternalVideoFrame(videoFrame)
// Objective-C
// 推入数据类型为 CVPixelBufferRef
ARVideoFrame *videoFrame = [[ARVideoFrame alloc] init];
videoFrame.format = 12;
// [NSDate date].timeIntervalSince1970 为当前时间戳;1000 表示每秒钟 1000 帧
videoFrame.time = CMTimeMakeWithSeconds([NSDate date].timeIntervalSince1970, 1000);
videoFrame.textureBuf = "Your CVPixelBufferRef";
videoFrame.ratation = 0;
// 推入数据类型为 rawData
ARVideoFrame *videoFrame = [[ARVideoFrame alloc] init];
videoFrame.format = "your data fromat";
// [NSDate date].timeIntervalSince1970 为当前时间戳;1000 表示每秒钟 1000 帧
videoFrame.time = CMTimeMakeWithSeconds([NSDate date].timeIntervalSince1970, 1000);
videoFrame.strideInPixels = "your stride";
videoFrame.height = "your height";
videoFrame.dataBuf = "your rawData";
videoFrame.ratation = 0;
[rtcKit pushExternalVideoFrame: videoFrame];
API 参考
实现方法(mediaIO 方式)
anyRTC 通过 MediaIO 提供 ARVideoSourceProtocol 协议和 ARVideoFrameConsumer 类,你可以通过该类设置采集的视频数据格式,并控制外部视频的采集过程。
操作步骤
-
实现ARVideoSourceProtocol协议。anyRTC 通过 ARVideoSourceProtocol
协议下的各回调设置视频数据格式,并控制采集过程:
-
收到 bufferType 回调后,在该回调的返回值中指定想要采集的视频数据格式;
-
收到 shouldInitialize 回调后,保存该回调中的 ARVideoFrameConsumer anyRTC ARVideoFrameConsumer 对象发送和接收自定义的视频数据;
-
收到 shouldStart 回调后,通过 ARVideoFrameConsumer 对象向 SDK 发送视频帧;
为满足实际使用需求,你可以在将视频帧发送回 SDK 前,修改 ARVideoFrameConsumer 中视频帧参数,如 rotation。
-
收到 shouldStop 回调后,停止使用 ARVideoFrameConsumer 对象向 SDK 发送视频帧;
-
收到 shouldDispose 回调后,释放 ARVideoFrameConsumer 对象。
-
-
继承实现的 ARVideoSourceProtocol 协议,构建一个自定义的视频源对象。
-
调用 setVideoSource 方法,将自定义的视频源对象设置给 ARtcEngineKit。
-
根据场景需要,调用 startPreview、joinChannelByToken 等方法预览或发送自定义采集的视频数据。
API 调用时序
参考下图时序使用 MediaIO 在你的项目中实现自定义视频采集。
示例代码
-
遵守 ARVideoSourceProtocol 协议, 并实现接口,构建自定义的 Video Source 类。
// 协议中的变量 var consumer: ARVideoFrameConsumer? // 调用 Consumer 的方法,将视频数据推入 anyRTC SDK // 推入 rawData 类型 consumer.consumeRawData("your rawData", withTimestamp: CMTimeMake(1, 15), format: "your data format", size: size, rotation: rotation) // 推入 CVPixelBuffer consumer.consumePixelBuffer("your pixelBuffer", withTimestamp: CMTimeMake(1, 15), rotation: rotation) // 协议中的方法 // 1. 视频采集使用的 Buffer 类型 func bufferType() -> ARVideoBufferType { return bufferType } // 2. 在初始化视频源(shouldInitialize)中, 初始化自定义的 Video Source func shouldInitialize() -> Bool { } // 3. 自定义视频源开始采集视频数据,并通过 Consumer 推入视频数据 func shouldStart() { } // 4. 自定义视频源停止采集视频数据 func shouldStop() { } // 5. 在释放自定义视频源 func shouldDispose() { }
// Objective-C // 协议中的变量 @synthesize consumer; // 调用 Consumer 的方法,将视频数据推入 anyRTC SDK // 推入 rawData 类型 [consumer consumeRawData: "your rawData" withTimestamp: CMTimeMake(1, 15) format: "your data format" size: size rotation: rotation]; // 推入 CVPixelBuffer [consumer consumePixelBuffer: "your pixelBuffer" withTimestamp: CMTimeMake(1, 15) rotation: rotation]; // 协议中的方法 // 1. 视频采集使用的 Buffer 类型 - (ARVideoBufferType)bufferType { return ARVideoBufferTypePixelBuffer; } // 2. 在初始化视频源(shouldInitialize)中, 初始化自定义的 Video Source - (BOOL)shouldInitialize { return YES; } // 3. 自定义视频源开始采集视频数据,并通过 Consumer 推入视频数据 - (void)shouldStart { } // 4. 自定义视频源停止采集视频数据 - (void)shouldStop { } // 5. 在释放自定义视频源 - (void)shouldDispose { }
-
将遵守了 ARVideoSourceProtocol 协议的自定义 VideoSource 对象设给 ARtcEngineKit。
// Swift rtcKit.setVideoSource(videoSource)
// Objective-C [rtcKit setVideoSource: videoSource];
API 参考
自定义渲染器
通过 MediaIO 采集到的视频数据,还可以搭配 anyRTC 的 ARVideoSinkProtocol 协议使用,实现自定义渲染功能。
操作步骤
-
实现 ARVideoSinkProtocol协议。anyRTC 通过 ARVideoSinkProtocol
协议下的各回调设置视频数据格式,并控制渲染过程:
- 收到 bufferType 和 pixelFormat 回调后,在对应回调的返回值中设置你想要渲染的数据类型;
- 根据收到的 shouldInitialize、shouldStart、shouldStop、shouldDispose 回调,控制视频数据的渲染过程;
- 实现一个对应渲染数据类型的 ARVideoFrameConsumer 对象,以获取视频数据。
-
继承实现的 ARVideoSinkProtocol 协议,构建一个自定义的渲染器。
-
调用 setLocalVideoRenderer 或 setRemoteVideoRenderer,用于本地渲染或远端渲染。
-
根据场景需要,调用 startPreview 、joinChannelByToken 等方法预览或发送自定义渲染的视频数据。
API 调用时序
参考下图时序使用 MediaIO 在你的项目中实现自定义视频渲染。
示例代码
参考下文代码使用 MediaIO 在你的项目中实现自定义视频渲染。
-
遵守 ARVideoSinkProtocol 协议, 并实现接口,构建自定义的 Video Renderer 类。
// Swift // 协议中的方法 // 1. 希望 anyRTC SDK 抛出的视频 Buffer 类型 func bufferType() -> ARVideoBufferType { return bufferType } // 希望 anyRTC SDK 抛出的视频数据格式 func pixelFormat() -> ARVideoPixelFormat { return pixelFormat } // 2. 初始化自定义的 Video Renderer func shouldInitialize() -> Bool { return true } // 3. 启动自定义的 Video Renderer func shouldStart() { } // 4. anyRTC SDK 停止抛出视频数据 func shouldStop() { } // 5. 自定义的 Video Renderer 可以被释放 func shouldDispose() { } // 6. anyRTC SDK 通过该接口抛出 CVPixelBuffer 类型的视频数据, 自定义 Video Renderer 可以获取数据进行渲染 func renderPixelBuffer(_ pixelBuffer: CVPixelBuffer, rotation: ARVideoRotation) { } anyRTC SDK 通过该接口抛出 rawData 类型的视频数据, 自定义 Video Renderer 可以获取数据进行渲染 func renderRawData(_ rawData: UnsafeMutableRawPointer, size: CGSize, rotation: ARVideoRotation) { } }
// Objective-C // 协议中的方法 // 1. 希望 anyRTC SDK 抛出的视频 Buffer 类型 - (ARVideoBufferType)bufferType { return ARVideoBufferTypePixelBuffer; } // 希望 anyRTC SDK 抛出的视频数据格式 - (ARVideoPixelFormat)pixelFormat { return ARVideoPixelFormatI420; } // 2. 初始化自定义的 Video Renderer - (BOOL)shouldInitialize { return YES; } // 3. 启动自定义的 Video Renderer - (void)shouldStart { } // 4. anyRTC SDK 停止抛出视频数据 - (void)shouldStop { } // 5. 自定义的 Video Renderer 可以被释放 - (void)shouldDispose { } // 6. anyRTC SDK 通过该接口抛出 CVPixelBuffer 类型的视频数据, 自定义 Video Renderer 可以获取数据进行渲染 - (void)renderPixelBuffer:(CVPixelBufferRef _Nonnull)pixelBuffer rotation:(ARVideoRotation)rotation { } // anyRTC SDK 通过该接口抛出 rawData 类型的视频数据, 自定义 Video Renderer 可以获取数据进行渲染 - (void)renderRawData:(void * _Nonnull)rawData size:(CGSize)size rotation:(ARVideoRotation)rotation { }
-
将遵守了 ARVideoSourceProtocol 协议的自定义 VideoRenderer 对象设给 ARtcEngineKit。
// Swift rtcKit.setLocalVideoRenderer(videoRenderer) rtcKit.setRemoteVideoRenderer(videoRenderer, forUserId: uid)
// Objective-C [rtcKit setLocalVideoRenderer: videoRenderer]; [rtcKit setRemoteVideoRenderer: videoRenderer, uid];
API 参考
开发注意事项
- 自定义视频采集和渲染场景中,需要开发者具有采集或渲染视频的能力:
- 自定义视频采集场景中,你需要自行管理视频数据的采集和处理。
- 自定义视频渲染场景中,你需要自行管理视频数据的处理和显示。
- 自定义视频渲染场景中,当 renderPixelBuffer 或 renderRawData 报告 rotation 不为 0 时,自渲染视频会呈一定角度。该角度可能由 SDK 采集或自采集的设置引起,你需要能根据实际使用需求处理自渲染的视频角度。
相关文档
如果你还想在项目中实现自定义的音频采集和渲染功能,请参考文档自定义视频采集和渲染