功能介绍
ARTC SDK 提供了灵活的自定义视频采集功能,支持客户根据业务需求自主管理视频采集设备。
建议优先使用 RTC SDK 内部采集,如果对视频质量、设备兼容性或采集流程有特殊要求而无法使用 SDK 内部采集,那么自定义视频采集为你提供更强的扩展性和定制能力。
示例代码
Android端自定义视频采集:Android/ARTCExample/AdvancedUsage/src/main/java/com/aliyun/artc/api/advancedusage/CustomVideoCaptureAndRender/CustomVideoCaptureActivity.java
。
iOS端自定义视频采集:iOS/ARTCExample/AdvancedUsage/CustomVideoCapture/CustomVideoCpatureVC.swift
。
前提条件
在设置视频配置之前,请确保达成以下条件:
功能实现
1. 关闭 SDK 内部采集
可以调用enableLocalVideo
接口关闭 SDK 内部采集。
Android
/* 关闭内部采集 */
mAliRtcEngine.enableLocalVideo(false);
/* 打开内部采集,阿里内部默认状态是true,所以如果不需要控制的情况下不需要调用此api */
mAliRtcEngine.enableLocalVideo(true);
iOS
/* 关闭内部采集 */
[_engine enableLocalVideo:NO];
/* 打开内部采集,阿里内部默认状态是true,所以如果不需要控制的情况下不需要调用此api */
[_engine enableLocalVideo:YES];
2. 设置自定义采集视频源
调用 setExternalVideoSource
设置自定义采集视频源,主要参数:
enable:控制是否开启。
useTexture:是否使用纹理输入。
streamType:相机流或屏幕共享流,表示 sdk 替换哪一路流。
renderMode:处理模式,外部输入视频源宽高比和推流profile不一致时,会按照对应的rendermode做对应处理。
Android
YUV 输入
/* YUV方式输入 */
/* 打开外部采集,这里以camera流为例,具体可以根据sourceType指定,渲染模式也可以根据需要指定 */
mAliRtcEngine.setExternalVideoSource(true,false, AliRtcVideoTrackCamera,AliRtcRenderModeAuto );
/* 关闭外部采集,这里以camera流为例,具体可以根据sourceType指定 */
mAliRtcEngine.setExternalVideoSource(false,false, AliRtcVideoTrackCamera,AliRtcRenderModeAuto );
纹理输入
/* 纹理方式输入 */
/* 打开外部采集,这里以camera流为例,具体可以根据sourceType指定,渲染模式也可以根据需要指定 */
mAliRtcEngine.setExternalVideoSource(true,true, AliRtcVideoTrackCamera,AliRtcRenderModeAuto );
/* 关闭外部采集,这里以camera流为例,具体可以根据sourceType指定 */
mAliRtcEngine.setExternalVideoSource(false,true, AliRtcVideoTrackCamera,AliRtcRenderModeAuto );
iOS
/* 打开外部采集,这里以camera流为例,具体可以根据sourceType指定,渲染模式也可以根据需要指定 */
[_engine setExternalVideoSource:YES sourceType:AliRtcVideosourceCameraType renderMode:AliRtcRenderModeAuto];
/* 关闭外部采集,这里以camera流为例,具体可以根据sourceType指定 */
[_engine setExternalVideoSource:NO sourceType:AliRtcVideosourceCameraType renderMode:AliRtcRenderModeAuto];
3. 向 SDK 发送数据
在采集到视频
Android
YUV方式输入示例:
/* 以YUV(I420)格式为例 */
int width = 720;
int height = 1280;
AliRtcEngine.AliRtcVideoFormat videoformat = AliRtcEngine.AliRtcVideoFormat.AliRtcVideoFormatI420;
int[] lineSize = {width, width / 2, width / 2, 0};
int frameLength = width * height * 3 / 2;
byte[] buffer = new byte[frameLength];
/* 构造传入SDK的数据对象 */
AliRtcEngine.AliRtcRawDataFrame rawDataFrame
= new AliRtcEngine.AliRtcRawDataFrame(buffer,
videoformat,
width,
height,
lineSize,
0,
buffer.length);
/* 调用API传入数据对象 */
int ret = mAliRtcEngine.pushExternalVideoFrame(rawDataFrame, AliRtcVideoTrackCamera);
if (ret != 0) {
/* 打印下错误信息 */
}
纹理方式输入示例:
/* 以纹理格式为例 */
/* 构造opengl的环境 */
private static EglBase14 createEglBase14(EGLContext shareEglContext) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
EglBase14.Context eglBase14Context = shareEglContext == null ? null : new EglBase14.Context(shareEglContext);
EglBase14 eglBase14 = new EglBase14(eglBase14Context, EglBase.CONFIG_PIXEL_BUFFER);
try {
eglBase14.createDummyPbufferSurface();
eglBase14.makeCurrent();
} catch (RuntimeException e) {
eglBase14.release();
Log.e(TAG, "CreateEGLBase14Context, failed, " + e.getMessage());
}
return eglBase14;
}
return null;
}
/* 构造传入的数据上下文 */
float[] transformMatrix = {
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
};
int frameWidth = 720; /* 图像的宽 */
int frameHeight = 1280; /* 图像的高 */
int textureID = xxx; /* 用户自己的纹理id */
AliRtcEngine.AliRtcRawDataFrame aliRawDataFrame
= new AliRtcEngine.AliRtcRawDataFrame(textureID,
AliRtcVideoFormatTexture2D,
frameWidth,
frameHeight,
transformMatrix,
0,
0,
frameWidth,
frameHeight,
mEglBase14.getEglContext());
/* 调用API传入数据对象 */
int ret = mAliRtcEngine.pushExternalVideoFrame(aliRawDataFrame, AliRtcVideoTrackCamera);
if (ret != 0) {
/* 打印下错误信息 */
}
iOS
/* 按照自己的数据格式填写以下内容,下面以I420格式为例 */
AliRtcVideoDataSample *dataSample = [[AliRtcVideoDataSample alloc] init];
dataSample.dataPtr = (long)yuv_read_data;
dataSample.format = AliRtcVideoFormat_I420;
dataSample.type = AliRtcBufferType_Raw_Data;
dataSample.width = width;
dataSample.height = height;
dataSample.strideY = width;
dataSample.strideU = width/2;
dataSample.strideV = width/2;
dataSample.dataLength = dataSample.strideY * dataSample.height * 3/2;
/* 调用API传入数据对象 */
int ret = [self.engine pushExternalVideoFrame:dataSample sourceType:AliRtcVideosourceCameraType];
if (ret != 0) {
/* 打印下错误信息 */
}
该文章对您有帮助吗?