短视频SDK提供基础视频录制,同时支持添加配乐,变速录制,人脸贴纸等录制效果。

版本支持

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

相关类功能

名称 功能
AliyunIRecorder 录制功能核心类,包括录制、设置预览、设置特效、设置回调等核心录制功能。
AliyunClipManager 录制片段管理器,获取片段信息,对视频片段进行删除操作等。
AliyunIRecorderDelegate 录制代理回调。

录制流程

说明 录制功能需要获取摄像头和麦克风权限,否则无法录制。

基础录制的流程如下所示:

录制流程
阶段 流程 说明 代码示例
基础 1 初始化AliyunIRecorder类,创建录制接口,并配置录制参数。 初始化
2 创建开始预览和结束预览。 预览控制
3 创建开始录制片段、取消录制片段、停止录制片段。 开始录制
4 创建结束录制相关信息。 结束录制
进阶 5 配置录制最大或最小时长、删除录制片段、获取录制片段数量等,可按需配置。 录制片段管理
6 配置美颜、滤镜、背景音乐等录制特效,可按需配置。 设置特效
7 对于常见的回调事件处理及对锁屏、来电、退后台等事件的特殊处理。 事件处理

初始化

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

说明
  • taskPath表示文件夹路径,用来存放录制相关配置。
  • preview长宽比和videoSize保持一致。
CGSize resolution = CGSizeMake(720, 1280);           // 720P
AliyunIRecorder *recorder = [[AliyunIRecorder alloc] initWithDelegate:self videoSize:resolution];
recorder.taskPath = taskPath;//设置文件夹路径
recorder.preview = self.videoView;//设置预览视图
recorder.recordFps = 30;
recorder.GOP = recorder.recordFps * 3;  // 预计隔3s一个关键帧
recorder.outputPath = [taskPath stringByAppendingPathComponent:@"output.mp4"];//设置录制视频输出路径
recorder.frontCaptureSessionPreset = AVCaptureSessionPreset1280x720;
recorder.backCaptureSessionPreset = AVCaptureSessionPreset1280x720;

// 录制片段设置
recorder.clipManager.deleteVideoClipsOnExit = YES; // 退出时自动删除所有片段,也可以考虑在拍摄结束后自行删除taskPath
recorder.clipManager.maxDuration = 15;
recorder.clipManager.minDuration = 3;

self.aliyunRecorder = recorder;

预览控制

代码中需要使用的参数详情,请参考接口文档。接口链接请参见相关类功能

开启预览
// AliyunIRecorderCameraPositionFront 前摄像头启动预览
// AliyunIRecorderCameraPositionBack 后摄像头启动预览
[self.aliyunRecorder startPreviewWithPositon:AliyunIRecorderCameraPositionFront];

调整预览参数

开启预览后,可按需对相关预览参数进行调整。
// 开关手电筒,为后摄像头时开启
AliyunIRecorderTorchMode torchMode = self.aliyunRecorder.cameraPosition == AliyunIRecorderCameraPositionBack ? AliyunIRecorderTorchModeOn : AliyunIRecorderTorchModeOff;
[self.aliyunRecorder switchTorchWithMode:torchMode];

// 切换前后摄像头
[self.aliyunRecorder switchCameraPosition];

// 调整变焦倍数
self.aliyunRecorder.videoZoomFactor = 30.0;

// 调整摄像头角度
self.aliyunRecorder.cameraRotate = 270;

// 改变视频分辨率
[self.aliyunRecorder reStartPreviewWithVideoSize:CGSizeMake(720, 720)];

结束预览

通常在完成录制后,调用结束预览。
[self.aliyunRecorder stopPreview];

开始录制

startRecording和stopRecording需要成对出现,可以调用一次或多次,对应SDK内部会生成一段或多段临时视频文件。代码中需要使用的参数详情,请参考接口文档。接口链接请参见相关类功能

// 开始录制一段视频
[self.aliyunRecorder startRecording];  

// 停止录制一段视频
[self.aliyunRecorder stopRecording];

结束录制

结束录制时可生成一个片段拼接的视频或只生成片段视频的配置信息。代码中需要使用的参数详情,请参考接口文档。接口链接请参见相关类功能
  • finishRecording:拼接视频片段,生成完整视频。如果后续不需要继续编辑生成的视频,可以使用该方式。
  • finishRecordingForEdit:不拼接视频片段。适用于拍摄视频后需要继续编辑视频,可以通过输出的taskPath初始化编辑器,详情请参考编辑初始化
//结束录制,并且将录制片段视频拼接成一个完整的视频
[self.aliyunRecorder finishRecording];

//结束录制,不拼接视频片段,生成taskPath
NSString *taskPath = [self.aliyunRecorder finishRecordingForEdit];
AliyunEditor *editor = [[AliyunEditor alloc] initWithPath:taskPath preview:preview];
...

录制片段管理

配置录制最大或最小时长、删除录制片段、获取录制片段数量等,可按需配置。代码中需要使用的参数详情,请参考接口文档。接口链接请参见相关类功能

// 删除最后一个视频片段
[self.aliyunRecorder.clipManager deletePart];

// 删除所有视频片段
[self.aliyunRecorder.clipManager deleteALLPart];

// 获取总的片段数量
[self.aliyunRecorder.clipManager partCount];

设置特效

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

滤镜

支持自定义滤镜,滤镜的制作方法请参见滤镜及转场
//添加滤镜
NSString *filterDir = [self.class resourcePath:@"Filter/Jiaopian"];
AliyunEffectFilter *filter = [[AliyunEffectFilter alloc] initWithFile:filterDir];
[self.aliyunRecorder applyFilter:filter];

//移除滤镜
[self.aliyunRecorder deleteFilter];
动效滤镜
//添加动效滤镜
NSString *filterDir = [self.class resourcePath:@"AnimationEffect/split_screen_3"];
AliyunEffectFilter *animationFilter =[[AliyunEffectFilter alloc] initWithFile:filterDir];
[self.aliyunRecorder applyAnimationFilter:animationFilter];

//移除动效滤镜
[self.aliyunRecorder deleteAnimationFilter];

人脸贴纸

内置人脸检测添加人脸贴纸
// 使用内置人脸检测方法添加人脸贴纸
self.aliyunRecorder.useFaceDetect = YES;//开启人脸识别,当系统检测有人脸动图加入时将自动追踪
self.aliyunRecorder.faceDetectCount = 3;//设置人脸个数,最大设置3个,最小设置1个。如果不需要检测人脸,请使用:useFaceDetect = NO
self.aliyunRecorder.faceDectectSync = YES;//开启同步贴合人脸,同步贴合人脸的贴合性强,但是性能差的设备可能卡顿。非同步贴合人脸的画面流畅,但是贴合性差。
NSString *parsterDir = [self.class resourcePath:@"Gif/hanfumei-800"];
AliyunEffectPaster *paster = [[AliyunEffectPaster alloc] initWithFile:parsterDir];
[self.aliyunRecorder applyPaster:paster];//添加人脸贴纸

//删除人脸贴纸
[self.aliyunRecorder deletePaster:paster];
自定义人脸识别
// 第一步 关闭内置人脸识别
self.aliyunRecorder.useFaceDetect = NO;
// 第二步 在回调接口调用第三方人脸检测库进行人脸识别,并返回相关结果

- (void)recorderOutputVideoRawSampleBuffer:(CMSampleBufferRef)sampleBuffer {
    NSArray<AliyunFacePoint *> *facePoints = ...; // 第三方人脸检测库进行检测
    if (self.aliyunRecorder.faceNumbersCallback) {
        int num = (int)facePoints.count;
        self.aliyunRecorder.faceNumbersCallback(num);
    }
    [self.aliyunRecorder faceTrack:facePoints];
}

水印

设置水印的本质即加入一张图片进行渲染。可以通过applyImage接口添加静态贴纸进行渲染,例如实现相框的拍摄场景。
//添加水印
NSString *watermarkPath = [self.class resourcePath:@"Image/watermark.png"];
AliyunEffectImage *watermark = [[AliyunEffectImage alloc] initWithFile:watermarkPath];
CGSize size = CGSizeMake(280, 200);
CGFloat centerx = 44 + size.width / 2.0;
CGFloat centery = 44 + size.height / 2.0;
watermark.frame = CGRectMake(centerx, centery, size.width, size.height); // 注意frame的origin表示中点位置
[self.aliyunRecorder applyImage:watermark];

//删除水印
[self.aliyunRecorder deleteImage:watermark];
音乐
说明 添加音乐后将无法设置静音,且不能进行录音。
//添加音乐
AliyunEffectMusic *effectMusic =[[AliyunEffectMusic alloc] initWithFile:[self.class resourcePath:@"bgm.aac"]];
effectMusic.startTime = 3.0; // 从音乐3s处开始播放
effectMusic.duration = 5.0;  // 持续5s,如果不设置则为音乐自身剩余长度且不能超过360s
[self.aliyunRecorder applyMusic:effectMusic];

//移除音乐
[self.aliyunRecorder applyMusic:nil];

高级美颜

视频录制模块,提供了基础的内置美颜功能,同时也支持使用外置的美颜SDK功能,如阿里云美颜特效SDK、相芯科技(FaceUnity)等美颜SDK。内置美颜功能相对比较简单,仅能设置不同的美颜等级;外置美颜SDK通常提供了更为丰富的美颜、美型、美妆美化、滤镜贴纸等功能。
  • 内置美颜
    // 开启
    self.aliyunRecorder.beautifyStatus = YES;
    self.aliyunRecorder.beautifyValue = 80;
    
    // 关闭
    self.aliyunRecorder.beautifyStatus = NO;
    self.aliyunRecorder.beautifyValue = 0;
  • 外置美颜SDK
    想要在短视频SDK中使用外置美颜SDK所提供的特效,则需要提前获取相应外置美颜SDK的权限并将外置美颜SDK集成接入到短视频SDK中。
    • 阿里云美颜特效SDK的集成接入等相关操作请参见美颜特效SDK。特效设置代码示例请参见使用示例
    • FaceUnity的购买、集成、使用等相关操作,请参见FaceUnity

    短视频SDK在摄像头采集后,会把采集的数据(CMSampleBufferRef)通过回调接口AliyunIRecorderDelegate传递给业务层,在业务层通过引入外置美颜SDK进行自定义渲染,最终把渲染的结果(CVPixelBufferRef)又交回给短视频SDK进行预览和合成。注意外置美颜SDK与短视频的GL环境冲突。

    // AliyunIRecorderDelegate
    - (CVPixelBufferRef)customRenderedPixelBufferWithRawSampleBuffer:(CMSampleBufferRef)sampleBuffer {
        if (!self.enableBeauty) {
            return CMSampleBufferGetImageBuffer(sampleBuffer);  // 不进行自定义渲染,直接返回
        }
        
        // 自定义渲染,这里可以接入美颜特效SDK,处理后返回CVPixelBufferRef示例
        ...
    }
拍照
 // 拍摄一张图片 异步获取
 // image:采集的渲染后图片
 // rawImage:采集的原始图片
[self.aliyunRecorder takePhoto:^(UIImage *image, UIImage *rawImage) {
        
}];

事件处理

对于常见的回调事件处理及对锁屏、来电、退后台等事件的特殊处理。代码中需要使用的参数详情,请参考接口文档。接口链接请参见相关类功能

回调事件处理

// 常见的事件回调处理如下
- (void)recorderDeviceAuthorization:(AliyunIRecorderDeviceAuthor)status {
    dispatch_async(dispatch_get_main_queue(), ^{
        if (status == AliyunIRecorderDeviceAuthorAudioDenied) {
            [DeviceAuthorization openSetting:@"麦克风无权限"];
        } else if (status == AliyunIRecorderDeviceAuthorVideoDenied) {
            [DeviceAuthorization openSetting:@"摄像头无权限"];
        }
    });
}

- (void)recorderVideoDuration:(CGFloat)duration {
    // 这里更新录制进度
    NSLog(@"Record Video Duration: %f", duration);
}

- (void)recorderDidStopRecording {
    NSLog(@"Record Stop Recording");
    if (self.recordState == RecorderStateFinish) {
        if (self.aliyunRecorder.clipManager.duration >= self.aliyunRecorder.clipManager.minDuration) {
            [self.aliyunRecorder finishRecording];
        }
        else {
            self.recordState = RecorderStatePreviewing;
        }
    }
}

- (void)recorderWillStopWithMaxDuration {
    NSLog(@"Record Will Stop Recording With Max Duration");
    [self.aliyunRecorder stopPreview];
}

- (void)recorderDidStopWithMaxDuration {
    NSLog(@"Record Did Recording With Max Duration");
    [self.aliyunRecorder finishRecording];
}

- (void)recorderDidFinishRecording {
    NSLog(@"Record Did Finish Recording");
    [self.aliyunRecorder stopPreview];
    self.recordState = RecorderStateInit;
}

- (void)recoderError:(NSError *)error {
    NSLog(@"Record Occurs Error: %@", error);
}

其他事件处理

对于锁屏、来电、退后台等事件,需要进行特殊处理。页面需要监听UIApplicationWillResignActiveNotification事件,当进入Inactive状态前需要调用stopRecording和stopPreview方法停止预览。还需要监听UIApplicationDidBecomeActiveNotification事件,当进入Active状态后调用startPreview方法重新开启预览。