功能介绍

短视频SDK提供视频合拍功能AliyunIMixRecorder,即使用一个已有视频作为样本视频,与摄像头采集的数据按照特定的布局方式(比如左右分屏,上下分屏,画中画等)进行合拍录制。

概念介绍

在以下文档介绍中将提及一些特殊概念,为方便开发者理解,预先对概念做一些讲解。
  • 合拍功能
    视频合拍从产品功能层面看,就是两路视频(一路来自样本视频,一路来自设备摄像头采集),按照指定的布局模式(左右分屏,上下分屏,画中画等)进行合成,合成出来的视频每一帧画面将会同时包含两路视频的画面,而合拍视频的音频部分则采用样本视频的音频。以下为范例视图,实际上SDK内部支持开发者自己组织布局,关于如何布局将在后面讲述。合拍功能
  • 轨道

    在概念1中提及的两路视频在SDK中被抽象为两个轨道:A轨道和B轨道,A轨放设备采集的视频,B轨放样本视频,用轨道抽象有利于开发者理解轨道布局的概念。

  • 轨道布局

    轨道布局是轨道的属性之一,用来描述,该轨道的视频画面,在合拍生成的视频中如何“摆放”,轨道布局在一个归一化的坐标系中,从两个纬度来描述轨道布局信息,分别是中心点的坐标和轨道size(即宽高信息)。

    如下图所示,在该布局画面中,轨道A和轨道B的画面各占一半,因此,两个轨道的宽度均为0.5,而高度则都为1.0,而轨道A的中心点坐标为(0.25,0.5),轨道B的中心点坐标为(0.75,0.5)。

    轨道布局在合拍接口中主要涉及两个核心类:
    • AliyunMixTrackLayoutParam就是用来描述上述提到的中心点和宽高信息的。
    • AliyunMixRecorderDisplayParam里面除了包含AliyunMixTrackLayoutParam布局信息,还包含了displayMode和layoutLevel,displayMode描述了该轨道的视频在宽高比与轨道宽高不一致时采用填充还是裁剪模式,layoutLevel用来描述布局层级,假如两个轨道有相互覆盖的地方,则layoutLevel大的轨道,在布局上层,将覆盖layoutLevel小的轨道。

版本差异

版本 功能描述
专业版 支持合拍功能
标准版 支持合拍功能
基础版 不支持合拍功能

合拍录制

说明 合拍录制功能需要获取摄像头和麦克风权限,否则无法录制。
合拍流程 流程说明
参数配置 该模块用来创建/销毁录制接口。
回调设置 该模块用于回调设置。
开启预览 该模块用于创建开始预览和结束预览
录制控制/管理 该模块用于配置录制相关信息。
设置特效 该模块用于配置录制美颜、滤镜等信息。
开始录制 该模块用于创建开始录制片段、取消录制片段、停止录制片段。
代码示例 视频合拍代码示例

配置参数

  • 初始化
    配置项 配置实例
    创建录制接口
    AliyunIMixRecorder recorder = AliyunMixRecorderCreator.createAlivcMixRecorderInstance(Context context);//参数context建议使用Application Context。
    销毁录制接口
    AliyunIMixRecorder#release();
  • 输出设置
    配置项 配置实例
    设置合拍视频输入输出出参数
    AliyunIMixRecorder#setMixMediaInfo(AliyunMixMediaInfoParam inputMediaInfo, MediaInfo outputInfo);//相关参数描述请参考AliyunMixMediaInfoParam和MedianInfo的接口文档
    设置输出路径
    AliyunIMixRecorder#setOutputPath(String path);
    设置录制视频质量
    AliyunIMixRecorder#setVideoQuality(VideoQuality quality);
    设置录制视频的码率
    AliyunIMixRecorder#setVideoBitrate(int bitrate);//单位:kbps
    设置输出视频的GOP大小
    AliyunIMixRecorder#setGop(int gop);//单位:帧数

回调设置

配置项 配置实例
设置录制回调
AliyunIRecorder#setRecordCallBack(RecordCallback callBack);
设置视频帧采集回调
AliyunIRecorder#setOnFrameCallback(OnFrameCallBack callback);
设置音频采集数据的回调
AliyunIRecorder#setOnAudioCallback(OnAudioCallBack callback);

开启预览

配置项 配置实例
开始预览
AliyunIMixRecorder#startPreview();
结束预览
AliyunIMixRecorder#stopPreview();

录制控制/管理

  • 录制控制
    配置项 配置实例
    获取摄像头数量
    AliyunIRecorder#getCameraCount();
    设置摄像头类型
    AliyunIRecorder#setCamera(CameraType cameraType);
    设置摄像头预览参数(闪光灯、对焦模式、zoom、曝光度)
    AliyunIRecorder#setCameraParam(CameraParam
    cameraParam);//也可以单独设置,参考下面的接口
    切换摄像头
    AliyunIRecorder#switchCamera();
    设置闪光灯模式
    AliyunIRecorder#setLight(FlashType flashType);
    设置Zoom
    AliyunIRecorder#setZoom(float rate);
    设置曝光度
    AliyunIRecorder#setExposureCompensationRatio(float value);
    设置对焦模式
    AliyunIRecorder#setFocusMode(int mode);
    手动对焦
    AliyunIRecorder#setFocus(float xRatio, float yRatio);
    设置录制预览窗口View(SurfaceView)
    AliyunIMixRecorder#setDisplayView(SurfaceView previewView, SurfaceView playView);//**注意:这里不能使用GLSurfaceView及其子类。**
    设置传感器角度值(非常重要,建议仔细阅读接口文档)
    AliyunIRecorder#setRotation(int rotation);
    设置人脸角度的检测值(非常重要,建议仔细阅读接口文档)
    AliyunIRecorder#setFaceDetectRotation(int rotation);
    设置录制视频的角度(非常重要,建议仔细阅读接口文档)
    AliyunIRecorder#setRecordRotation(int rotation);
    设置静音录制
    AliyunIRecorder#setMute(boolean isMute);
  • 录制管理
    配置项 配置实例
    获取片段管理器
    AliyunIMixRecorder#getClipManager();**注意:如果要删除上一段不能使用AliyunIClipManager里面的接口,而要使用AliyunIMixRecorder#deleteLastPart()。**
    设置最大录制时长(总录制时长,不是单个片段的最大时长)
    AliyunIClipManager#setMaxDuration(int maxDurationMs);
    设置最小录制时长(总录制时长,不是单个片段的时长)
    AliyunIClipManager#setMinDuration(int minDurationMs);
    获取片段总时长
    AliyunIClipManager#getDuration();
    获取总的片段数量
    AliyunIClipManager#getPartCount();
    删除最后一段片段
    AliyunIMixRecorder#deleteLastPart();//这里不能使用AliyunIClipManager#deletePart();否则内部的样本视频将不会seek到上一个片段位置。
    删除指定的片段
    AliyunIClipManager#deletePart(int index);//仅仅用来删除文件,样本视频不会跟随seek。
    删除所有片段
    AliyunIClipManager#deleteAllPart();//仅仅用来删除片段文件,样本视频不会跟随seek。
    获取片段路径列表
    AliyunIClipManager#getVideoPathList();

设置特效

  • 美颜
    配置项 配置实例
    设置美颜程度
    AliyunIRecorder#setBeautyLevel(int level);
    设置美颜开关
    AliyunIRecorder#setBeautyStatus(boolean on);
  • 滤镜
    配置项 配置实例
    设置普通滤镜效果
    AliyunIRecorder#applyFilter(EffectFilter effectFilter);//参数路径设置为null表示移除滤镜效果
    移除滤镜效果
    AliyunIRecorder#applyFilter(new EffectFilter(null));
  • 动效滤镜
    配置x项 配置实例
    设置动效滤镜(灵魂出窍等)
    AliyunIRecorder#applyAnimationFilter(EffectFilter effectFilter);
    移除动效滤镜
    AliyunIRecorder#removeAnimationFilter(EffectFilter effctFilter);
  • 人脸识别(仅专业版支持)
    配置项 配置实例
    设置人脸坐标数据(接入第三方人脸识别时会用到)
    AliyunIRecorder#setFace(float[][] faces);
    设置是否需要使用SDK内置的人脸识别
    AliyunIRecorder#needFaceTrackInternal(boolean need);
    为SDK内置的人脸识别指定模型文件
    AliyunIRecorder#setFaceTrackInternalModelPath(String path);
    设置SDK内置人脸识别支持的最大人脸个数
    AliyunIRecorder#setFaceTrackInternalMaxFaceCount(int maxFaceCount);
  • 动图(仅专业版支持)
    配置项 配置实例
    添加人脸动图
    AliyunIRecorder#addPaster(EffectPaster effectPaster);
    添加普通动图
    AliyunIRecorder#addPaster(EffectPaster effectPaster,float sx,float sy,float sw,float sh,float rotation,boolean flip);
    移除动图
    AliyunIRecorder#removePaster(EffectPaster effectPaster);
  • 静态贴纸/水印
    配置项 配置实例
    添加静态水印/静态贴纸
    AliyunIRecorder#addImage(EffectImage effctImage);
    移除静态水印/静态贴纸
    AliyunIRecorder#removeImage(EffectImage effctImage);
  • 背景音乐(仅专业版、标准版支持)
    配置项 配置实例
    设置背景音乐
    AliyunIRecorder#setMusic(String path,long startTime,long duration);
    移除背景音乐
    AliyunIRecorder#setMusic(null, 0, 0);
  • 变速(仅专业版、标准版支持)
    配置项 配置实例
    设置录制变速
    AliyunIRecorder#setRate(float rate);
  • 自定义渲染
    配置项 配置实例
    设置自定义渲染的回调
    AliyunIRecorder#setOnTextureIdCallback(OnTextureIdCallBack callback);
  • 拍照
    配置项 配置实例
    带特效拍照
    AliyunIRecorder#takePhoto(boolean needBitmap);
    系统拍照(不带特效)
    AliyunIRecorder#takePicture(boolean needBitmap);
    设定系统拍照的照片大小(只支持系统拍照,特效拍照不支持)
    AliyunIRecorder#setPictureSize(Camera.Size size);
  • 其他
    配置项 配置实例
    设置特效信息(水印、静态贴纸、动图、位置、大小)
    AliyunIRecorder#setEffectView(float xRatio,float yRatio,float widthRatio,float heightRatio,EffectBase effectBase);

开始录制

配置项 配置实例
开始录制一个片段视频
AliyunIMixRecorder#startRecording();
停止录制一个片段视频
AliyunIMixRecorder#stopRecording();
结束录制,并且将录制片段视频拼接成一个视频
AliyunIMixRecorder#finishRecording();

示例代码

//合拍一段视频,前置条件:手机SD卡的根目录存在一个视频叫sample.mp4,即/sdcard/sample.mp4,以下代码只描述核心流程,不能将以下代码直接复制粘贴到工程中,详细流程请参考配套的Demo工程。
AliyunIMixRecorder mMixRecorder = AliyunIMixRecorder createAlivcMixRecorderInstance(getApplicationContext());
if(需要所见即所得){
    mRecorder.setRecordRotation(0);//这样设置可以保证所见即所得,即横向录制的视频,合拍中依然是横向,不会自动旋转角度。
    mRecorder.setFaceDetectRotation(getPictureRotation());//getPictureRotation的代码请参考Demo工程代码。
}else {
    mRecorder.setRotation(getPictureRotation());
}
mMixRecorder.setDisplayView(mCameraPrvSurfaceView, mPlayPrvSurfaceView);
AliunIClipManager mClipManager = mRecorder.getClipManager();
mClipManager.setMinDuration(mMinDuration);
mClipManager.setMaxDuration(mMaxDuration);
mRecordTimelineView.setMaxDuration(mClipManager.getMaxDuration());
mRecordTimelineView.setMinDuration(mClipManager.getMinDuration());
MediaInfo mOutputInfo = new MediaInfo();
mOutputInfo.setVideoWidth(outputWidth);
mOutputInfo.setVideoHeight(outputHeight);
AliyunMixRecorderDisplayParam recorderDisplayParam = new AliyunMixRecorderDisplayParam.Builder()
        .displayMode(VideoDisplayMode.FILL)
        .layoutParam(
            new AliyunMixTrackLayoutParam.Builder()
            .centerX(0.25f)
            .centerY(0.5f)
            .widthRatio(0.5f)
            .heightRatio(1.0f)
            .build()
        )
        .build();
AliyunMixRecorderDisplayParam sampleDisplayParam = new AliyunMixRecorderDisplayParam
        .Builder()
        .displayMode(VideoDisplayMode.FILL)
        .layoutParam(new AliyunMixTrackLayoutParam.Builder()
                     .centerX(0.75f)
                     .centerY(0.5f)
                     .widthRatio(0.5f)
                     .heightRatio(1.0f)
                     .build())
        .build();
AliyunMixMediaInfoParam mInputInfo = new AliyunMixMediaInfoParam
        .Builder()
        .streamStartTimeMills(0L)
        .streamEndTimeMills(0L)//设置为0L就会自动使用视频的时长
        .mixVideoFilePath("/sdcard/sample.mp4")
        .mixDisplayParam(sampleDisplayParam)
        .recordDisplayParam(recorderDisplayParam)
        .build();
mRecorder.setMixMediaInfo(mInputInfo, mOutputInfo);
mRecorder.setRecordCallback(new RecordCallback() {
            @Override
            public void onComplete(boolean validClip, long clipDuration) {}
            @Override
            public void onFinish(String outputPath) {
                //合成完成
            }
            @Override
            public void onProgress(final long duration) {}
            @Override
            public void onMaxDuration() {}
            @Override
            public void onError(int errorCode) {}
            @Override
            public void onInitReady() { }
            @Override
            public void onDrawReady() {}
            @Override
            public void onPictureBack(Bitmap bitmap) { }
            @Override
            public void onPictureDataBack(byte[] data) {}
        });
mRecorder.startPreview();
mRecorder.startRecording();
mRecorder.stopRecording();
mRecorder.finishRecording();