短视频SDK在基础录制功能的基础上全新升级了录制功能,除了满足基础录制所有的录制能力,还新增支持了View录制(即录屏)。短视频SDK支持摄像头录制、View录制等多种视频采集源按需组合的合拍录制。

版本支持

版本 是否支持
专业版 支持
标准版 支持
基础版 不支持

概念介绍

在以下文档介绍中将提及一些特殊概念,为方便开发者理解,请预先对多源录制轨道轨道布局的概念做相关了解。

相关类功能

类名 功能
AliyunIVideoRecorder 多源录制核心类,包括录制、设置预览、设置特效、设置回调等多源录制的核心功能。
AliyunMultiRecorderCreator 多源录制工厂类,获取视频录制实例。
AliyunVideoRecorderConfig 视频录制配置信息,包括设置视频的宽高、编码器类型、录制采集帧率等录制参数。
AliyunIVideoCapture 视频数据采集配置接口,包括添加摄像头采集器及添加局部录屏采集器接口。
AliyunICameraCapture 摄像头录制接口。
AliyunIViewCapture View录制接口。
OnVideoRecordListener 录制监听接口,包括设置录制完成回调、录制进度回调及录制错误回调等。
OnAudioCallBack 音频回调接口,设置音频pcm数据回调。
OnFrameCallBack 相机采集数据回调接口,包括选择预览分辨率的回调、采集帧回调及摄像头开启失败的回调。
OnPictureCallback 拍照截屏回调接口。
AliyunIClipManager 视频录制片段管理接口,包括删除片段、设置录制时长等。

多源录制流程

说明 多源录制功能需要获取摄像头和麦克风权限,否则无法录制。
阶段 流程 说明 示例代码
基础 1 创建及销毁录制接口,并配置录制参数。 初始化及参数配置
2 配置View录制和摄像头录制的相关参数。 采集源配置
3 回调设置。 回调设置
4 设置预览View并开启预览。 开启预览
5 创建开始录制片段、取消录制片段、停止录制片段。 开始录制
6 创建结束录制相关信息。 结束录制
进阶 7 配置录制相机控制相关参数(设置摄像头类型、设置闪光灯模式等)及录制片段管理相关参数(配置录制最大或最小时长、删除录制片段、获取录制片段数量等),可按需配置。 录制控制及管理
8 配置美颜、滤镜、动态贴纸等录制特效,可按需配置。 设置特效
9 设置背景音乐、背景图片及变速等。 其他功能

初始化及参数配置

初始化AliyunIVideoRecorder类,创建录制接口,并配置录制参数。代码中需要使用的参数详情,请参考接口文档。接口链接请参见相关类功能

初始化
//创建录制接口
AliyunIVideoRecorder recorder = AliyunMultiRecorderCreator.getVideoRecorderInstance(context, config);

//销毁录制接口
//不再使用SDK或者程序退出前销毁录制接口,请务必保证不要中途销毁,一般在Activity#onDestroy调用
recorder.destroy();
配置录制参数
AliyunVideoRecorderConfig config = AliyunVideoRecorderConfig.builder()
                //必需设置的参数
                .videoWidth(***)
                .videoHeight(***)
                .outputPath(***)
                //其他非必须设置的参数
                .***()
                .***()
                .build();

采集源配置

按需组合多个采集源,采集源添加完成后必需调用recorder.prepare()以表示采集源添加完成。

摄像头录制

接口参数请参考AliyunICameraCapture
//1.布局配置
AliyunLayoutParam cameraLayoutParam = AliyunLayoutParam.builder()
                .layoutLevel(***)
                .centerX(***)
                .centerY(***)
                .widthRatio(***)
                .heightRatio(***)
                .displayMode(***)
                .build();

//2.添加采集源
AliyunICameraCapture cameraCapture = recorder.getVideoCapture().addCameraCapture(cameraLayoutParam);

//3.配置采集源
//设置摄像头预览view,必需属性
cameraCapture.setDisplayView(SurfaceView)
//其他设置(按需设置)
cameraCapture.set***();

View录制

接口参数请参考AliyunIViewCapture
//1.布局配置
AliyunLayoutParam viewLayoutParam = AliyunLayoutParam.builder()
                .layoutLevel(***)
                .centerX(***)
                .centerY(***)
                .widthRatio(***)
                .heightRatio(***)
                .displayMode(***)
                .build();

//2.添加采集源
//获取目前录制View
View recordView = getRecordView();
AliyunIViewCapture viewCapture = recorder.getVideoCapture().addViewCapture(viewLayoutParam, recordView);

//3.配置采集源(按需设置)
viewCapture.set***();

采集源准备

添加完所有采集源后必需调用以下接口,以表示采集源添加完成。
recorder.prepare();

回调设置

通过设置回调,及时获取音视频处理的进展和状态。代码中需要使用的参数详情,请参考接口文档。接口链接请参见相关类功能

//设置录制回调(按需设置)
recorder.setOnRecordListener(OnVideoRecordListener);

//设置音频采集数据的回调(按需设置)
recorder.setOnAudioCallback(OnAudioCallBack);

开启预览

通常在Activity#onResume调用startPreview,在Activity#onPause调用stopPreview。代码中需要使用的参数详情,请参考接口文档。接口链接请参见相关类功能

//开始预览
//一般在Activity#onResume调用
AliyunIRecorder.startPreview();

//结束预览
//一般在Activity#onPause调用
AliyunIRecorder.stopPreview();

开始录制

在实际录制过程中,常常不能一次性就能录制完成所需视频,而总是不断的停止、取消和重新录制。停止录制时会生成一个视频片段,而取消录制则不会保留当前录制的视频片段。代码中需要使用的参数详情,请参考接口文档。接口链接请参见相关类功能

开始录制
//开始录制
recorder.startRecording();
录制片段
//开始录制
recorder.startRecording();

//停止录制,生成一个视频片段
recorder.stopRecording();

recorder.startRecording();
// 取消录制,当前的视频片段不会保存
recorder.cancelRecording();

//继续录制下一个视频片段
recorder.startRecording();
recorder.stopRecording();

结束录制

结束录制时可生成一个片段拼接的视频或只生成片段视频的配置信息。代码中需要使用的参数详情,请参考接口文档。接口链接请参见相关类功能

//结束录制,并且将录制片段视频拼接成一个视频
recorder.finishRecording();

//结束录制,生成片段视频的配置信息(不拼接片段)
recorder.finishRecordingForEdit();

录制控制及管理

配置录制相机控制相关参数(设置摄像头类型、设置闪光灯模式等)及录制片段管理相关参数(配置录制最大或最小时长、删除录制片段、获取录制片段数量等),可按需配置。代码中需要使用的参数详情,请参考接口文档。接口链接请参见相关类功能

录制摄像头控制
//获取摄像头数量
AliyunICameraCapture.getCameraCount();

//设置摄像头类型:前置摄像头、后置摄像头
AliyunICameraCapture.setCamera(CameraType cameraType);

//设置传感器角度值
//(非常重要,建议仔细阅读接口文档)
AliyunICameraCapture.setRotation(int rotation);

//设置录制视频的角度
//(非常重要,建议仔细阅读接口文档)
AliyunICameraCapture.setRecordRotation(int rotation);

//设置摄像头预览参数(闪光灯、对焦模式、zoom、曝光度),也可参考下面的接口单独设置各预览参数
AliyunICameraCapture.setCameraParam(CameraParam cameraParam);

//切换摄像头
AliyunICameraCapture.switchCamera();

//设置闪光灯模式
AliyunICameraCapture.setLight(FlashType flashType);

//设置Zoom
AliyunICameraCapture.setZoom(float rate);

//设置曝光度
AliyunICameraCapture.setExposureCompensationRatio(float value);

//设置对焦模式
AliyunICameraCapture.setFocusMode(int mode);

//手动对焦
AliyunICameraCapture.setFocus(float xRatio, float yRatio);
录制片段管理
//获取片段管理器
AliyunIClipManager manager = AliyunIVideoRecorder.getClipManager();

//设置最大录制时长(总录制时长,非单个片段的最大时长)
manager.setMaxDuration(int maxDurationMs);

//设置最小录制时长(总录制时长,非单个片段的最小时长)
manager.setMinDuration(int minDurationMs);

//删除最后一段片段
manager.deletePart();

//删除指定的片段
manager.deletePart(int index);

//删除所有片段
manager.deleteAllPart();

//获取片段总时长
manager.getDuration();

//获取总的片段数量
manager.getPartCount();

//获取片段路径列表
manager.getVideoPathList();

设置特效

配置美颜、滤镜、动态贴纸等录制特效,可按需配置。代码中需要使用的参数详情,请参考接口文档。接口链接请参见相关类功能

滤镜

支持自定义滤镜,滤镜的制作方法请参见滤镜及转场

//设置滤镜
AliyunICameraCapture.applyFilter(EffectFilter effectFilter);

//移除滤镜
AliyunICameraCapture.removeFilter();
动效滤镜
//设置动效滤镜
AliyunICameraCapture.applyAnimationFilter(EffectFilter effectFilter);

//移除动效滤镜
AliyunICameraCapture.removeAnimationFilter(EffectFilter effctFilter);
静态贴纸
//添加静态贴纸
AliyunICameraCapture.addImage(EffectImage effctImage);

//移除静态贴纸
AliyunICameraCapture.removeImage(EffectImage effctImage);

//更新静态贴纸位置
AliyunICameraCapture.setEffectView(float xRatio,float yRatio,float widthRatio,float heightRatio,EffectBase effectBase);

动态贴纸

支持自定义动态贴纸,动态贴纸的制作方法请参见动图
//添加动态贴纸
AliyunICameraCapture.addPaster(EffectPaster effectPaster,float sx,float sy,float sw,float sh,float rotation,boolean flip);

//移除动态贴纸
AliyunICameraCapture.removePaster(EffectPaster effectPaster);

//更新动态贴纸位置
AliyunICameraCapture.setEffectView(float xRatio,float yRatio,float widthRatio,float heightRatio,EffectBase effectBase);

高级美颜

视频录制模块,提供了基础的内置美颜功能,同时也支持使用外置的美颜SDK功能,如阿里云美颜特效SDK、相芯科技(FaceUnity)等美颜SDK。内置美颜功能相对比较简单,仅能设置不同的美颜等级;外置美颜SDK通常提供了更为丰富的美颜、美型、美妆美化、滤镜贴纸等功能。
  • 内置美颜
    //设置美颜开关
    AliyunICameraCapture.setBeautyStatus(boolean on);
    
    //设置美颜程度
    AliyunICameraCapture.setBeautyLevel(int level);
  • 外置美颜SDK
    想要在短视频SDK中使用外置美颜SDK所提供的特效,则需要提前获取相应外置美颜SDK的权限并将外置美颜SDK集成接入到短视频SDK中。
    • 阿里云美颜特效SDK的集成接入等相关操作请参见美颜特效SDK。特效设置代码示例请参见使用示例
    • FaceUnity的购买、集成、使用等相关操作,请参见FaceUnity
    外置美颜SDK需要获取两个数据用于实现美颜功能:相机纹理ID和相机原始帧数据。以下代码展示如何获取相机纹理ID和相机原始帧数据。
    • 获取相机纹理ID数据
      AliyunICameraCapture.setOnTextureIdCallback(new OnTextureIdCallBack() {
                  @Override
                  public int onTextureIdBack(int textureId, int textureWidth, int textureHeight, float[] matrix) {
                      if (mBeautyInterface != null) {
                          return mBeautyInterface.onTextureIdBack(textureId, textureWidth, textureHeight, matrix, mControlView.getCameraType().getType());
                      }
                      return textureId;
                  }
      
                  @Override
                  public int onScaledIdBack(int scaledId, int textureWidth, int textureHeight, float[] matrix) {
                      return scaledId;
                  }
      
                  @Override
                  public void onTextureDestroyed() {
                      //关于自定义渲染(第三方渲染)销毁gl资源,SDK3.7.8之前版本,GLSurfaceView时可以通过GLSurfaceView.queueEvent来销毁gl资源;SDK3.7.8及之后版本开始,推荐在此回调中统一销毁gl资源
                      if (mBeautyInterface != null) {
                          mBeautyInterface.release();
                          mBeautyInterface = null;
                      }
                  }
              });
    • 获取相机原始帧数据
      AliyunICameraCapture.setOnFrameCallback(new OnFrameCallBack() {
                  @Override
                  public void onFrameBack(byte[] bytes, int width, int height, Camera.CameraInfo info) {
                      //原始数据回调 NV211,此处获取原始数据主要是提供给FaceUnity高级美颜使用
                      if (mBeautyInterface != null) {
                          mBeautyInterface.onFrameBack(bytes, width, height, info);
                      }
                  }
      
                  @Override
                  public Camera.Size onChoosePreviewSize(List<Camera.Size> supportedPreviewSizes,
                                                         Camera.Size preferredPreviewSizeForVideo) {
                      return null;
                  }
      
                  @Override
                  public void openFailed() {
                  }
              });

其他功能

支持添加背景音乐、添加水印、变速等功能。代码中需要使用的参数详情,请参考接口文档。接口链接请参见相关类功能

变速
//设置录制速度
AliyunIVideoRecorder.setRate(float rate);
静音
//设置麦克风静音
AliyunIVideoRecorder.setMute(boolean isMute);
退出自动清除
//设置退出录制时,是否自动清空录制的分段视频文件
AliyunIVideoRecorder.setIsAutoClearClipVideos(boolean isAutoClear);
背景音乐
//设置背景音乐
AliyunIVideoRecorder.setMusic(String path,long startTime,long duration);

//移除背景音乐
AliyunIVideoRecorder.removeMusic();
水印
//添加水印
AliyunIVideoRecorder.addWaterMark(EffectImage effectImage);

//删除水印
AliyunIVideoRecorder.removeWaterMark(EffectImage effectImage);
设置背景
//添加背景颜色
AliyunIVideoRecorder.setBackgroundColor(int color);

//添加背景图片bitmap
AliyunIVideoRecorder.setBackgroundImage(Bitmap bitmap);

//添加背景图片路径
AliyunIVideoRecorder.setBackgroundImage(String path);

//清除背景
AliyunIVideoRecorder.clearBackground();

多源录制代码示例

import android.os.Bundle;
import android.os.Environment;
import android.view.SurfaceView;
import android.view.View;
import android.widget.TextView;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import com.aliyun.svideosdk.common.struct.common.AliyunLayoutParam;
import com.aliyun.svideosdk.common.struct.common.VideoDisplayMode;
import com.aliyun.svideosdk.common.struct.encoder.VideoCodecs;
import com.aliyun.svideosdk.common.struct.recorder.CameraType;
import com.aliyun.svideosdk.multirecorder.AliyunICameraCapture;
import com.aliyun.svideosdk.multirecorder.AliyunIVideoRecorder;
import com.aliyun.svideosdk.multirecorder.AliyunIViewCapture;
import com.aliyun.svideosdk.multirecorder.OnVideoRecordListener;
import com.aliyun.svideosdk.multirecorder.config.AliyunVideoRecorderConfig;
import com.aliyun.svideosdk.multirecorder.impl.AliyunMultiRecorderCreator;

import java.io.File;

/**
 * 多源录制示例demo
 * 注意:需提前开启存储、相机、麦克风3个手机权限
 */
public class MultiRecorderDemo extends AppCompatActivity {

    private AliyunIVideoRecorder mRecorder;
    private TextView mBtnRecord;
    private SurfaceView mCameraPreview;
    private View mViewRecord;
    private View mViewRecordIcon;

    private boolean mIsRecording = false;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.multi_recoder_demo_layout);
        initViews();
        initRecorder();
    }

    @Override
    protected void onResume() {
        super.onResume();
        mRecorder.startPreview();
    }

    @Override
    protected void onPause() {
        super.onPause();
        stopRecording();
        mRecorder.stopPreview();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mRecorder.destroy();
    }

    private String getSaveDir() {
        String saveDir = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "MultiRecord";
        File dirFile = new File(saveDir);
        if (!dirFile.exists()) {
            dirFile.mkdirs();
        }
        return saveDir;
    }

    private void initViews() {
        mBtnRecord = findViewById(R.id.record_btn);
        mCameraPreview = findViewById(R.id.multi_record_camera);
        mViewRecord = findViewById(R.id.multi_record_view);
        mViewRecordIcon = mViewRecord.findViewById(R.id.record_view_icon);
    }

    private void initRecorder() {
        //1. 参数配置
        AliyunVideoRecorderConfig config = AliyunVideoRecorderConfig.builder()
                //必需设置的参数
                .videoWidth(1080)
                .videoHeight(1920)
                .outputPath(getSaveDir() + File.separator + System.currentTimeMillis() + ".mp4")
                //其他非必须设置的参数
                .videoCodecs(VideoCodecs.H264_HARDWARE) //硬编
                .build();

        //2.创建录制接口
        mRecorder = AliyunMultiRecorderCreator.getVideoRecorderInstance(this, config);

        //3. 采集源配置
        //3.1 摄像头录制
        addCameraCapture();
        //3.2 View录制
        addViewCapture();
        //3.3 采集源准备
        mRecorder.prepare();

        //4 回调设置
        mRecorder.setOnRecordListener(new OnVideoRecordListener() {
            @Override
            public void onProgress(long duration) {

            }

            @Override
            public void onFinish(String outputPath) {

            }

            @Override
            public void onClipComplete(boolean validClip, long clipDuration) {

            }

            @Override
            public void onMaxDuration() {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        stopRecording();
                    }
                });
            }

            @Override
            public void onError(int errorCode) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        stopRecording();
                    }
                });
            }

            @Override
            public void onInitReady() {

            }
        });
    }

    private void addCameraCapture() {
        //1.布局配置:左半边
        AliyunLayoutParam cameraLayoutParam = AliyunLayoutParam.builder()
                .layoutLevel(1)
                .centerX(0.25f)
                .centerY(0.5f)
                .widthRatio(0.5f)
                .heightRatio(1.0f)
                .displayMode(VideoDisplayMode.FILL)
                .build();

        //2.添加采集源
        AliyunICameraCapture cameraCapture = mRecorder.getVideoCapture().addCameraCapture(cameraLayoutParam);

        //3.配置采集源
        //设置摄像头预览view,必需属性
        cameraCapture.setDisplayView(mCameraPreview);

        //其他设置(按需设置)
        cameraCapture.setCamera(CameraType.BACK);//后置摄像头
    }

    private void addViewCapture() {
        //1.布局配置:右半边
        AliyunLayoutParam viewLayoutParam = AliyunLayoutParam.builder()
                .layoutLevel(2)
                .centerX(0.75f)
                .centerY(0.5f)
                .widthRatio(0.5f)
                .heightRatio(1.0f)
                .displayMode(VideoDisplayMode.FILL)
                .build();

        //2.添加采集源
        // 获取目前录制View
        View recordView = mViewRecord;
        AliyunIViewCapture viewCapture = mRecorder.getVideoCapture().addViewCapture(viewLayoutParam, recordView);

        //3.配置采集源(按需设置)
    }

    private void startRecording() {
        if (mIsRecording) {
            return;
        }
        mIsRecording = true;
        mRecorder.startRecording();
    }

    private void stopRecording() {
        if (!mIsRecording) {
            return;
        }
        mRecorder.stopRecording();
        mIsRecording = false;
    }

    public void onClickRecord(View view) {
        if (mIsRecording) {
            stopRecording();
            mBtnRecord.setText("开始录制");
        } else {
            startRecording();
            mBtnRecord.setText("停止录制");
        }
    }
}

XML文件配置示例

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/demo_root_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal">

        <SurfaceView
            android:id="@+id/multi_record_camera"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1" />

        <FrameLayout
            android:id="@+id/multi_record_view"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1">

            <TextView
                android:id="@+id/record_view_icon"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:text="View录制" />

        </FrameLayout>

    </LinearLayout>

    <Button
        android:id="@+id/record_btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_marginLeft="5dp"
        android:layout_marginBottom="5dp"
        android:onClick="onClickRecord"
        android:text="开始录制" />

</RelativeLayout>