短视频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];
}
水印
//添加水印
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];
高级美颜
- 内置美颜
// 开启 self.aliyunRecorder.beautifyStatus = YES; self.aliyunRecorder.beautifyValue = 80; // 关闭 self.aliyunRecorder.beautifyStatus = NO; self.aliyunRecorder.beautifyValue = 0;
- 外置美颜SDK
想要在短视频SDK中使用外置美颜SDK所提供的特效,则需要提前获取相应外置美颜SDK的权限并将外置美颜SDK集成接入到短视频SDK中。
短视频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方法重新开启预览。