iOS相册视频编辑有两种方式,一种是使用系统自带的控制器UIVideoEditorController
但是该类只提供了基础的视频编辑功能,接口十分有限,界面样式没法修改,效果如下图。
UIVideoEditorController
和UIImagePickerController
的视频显示界面十分相似,区别就是前者可以编辑,后者不能。
第二种方式就是利用强大的AVFoudation
框架自己动手实现。
实现逻辑主要分5步:
* 1.AVPlayer循环播放视频
如果是整段视频循环播放,有两种实现方式,一种是KVO监听AVPlayer
的timeControlStatus
属性,
typedef NS_ENUM(NSInteger, AVPlayerTimeControlStatus) {
AVPlayerTimeControlStatusPaused,
AVPlayerTimeControlStatusWaitingToPlayAtSpecifiedRate,
AVPlayerTimeControlStatusPlaying
} NS_ENUM_AVAILABLE(10_12, 10_0);
当状态为AVPlayerTimeControlStatusPaused
的时候让player回到起点并继续播放。
[self.player seekToTime:CMTimeMake(0, 1)];
[self.player play];
第二种循环播放方式是,利用计时器设置要播放时长,并循环执行计时器方法。
- (void)repeatPlay{
[self.player play];
CMTime start = CMTimeMakeWithSeconds(self.startTime, self.player.currentTime.timescale);
[self.player seekToTime:start toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero];
}
编辑视频时的视频段循环播放,显然只能通过第二种方式实现。
- 2.以1秒为单位,获取视频帧图像
编辑区域需要显示视频帧图像,通过AVAssetImageGenerator
这个类来获取,在该类的获取视频帧图像接口调用时需要传入要获取视频帧图像的时间节点。
- (void)generateCGImagesAsynchronouslyForTimes:(NSArray<NSValue *> *)requestedTimes completionHandler:(AVAssetImageGeneratorCompletionHandler)handler;
在视频编辑功能中,一般的时间节点都是以1秒为单位获取视频帧图像。在该接口回调中由于是异步执行,所以需要在回调中直接显示图片,详细代码实现如下。
#pragma mark 读取解析视频帧
- (void)analysisVideoFrames{
//初始化asset对象
AVURLAsset *videoAsset = [[AVURLAsset alloc]initWithURL:self.videoUrl options:nil];
//获取总视频的长度 = 总帧数 / 每秒的帧数
long videoSumTime = videoAsset.duration.value / videoAsset.duration.timescale;
//创建AVAssetImageGenerator对象
AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc]initWithAsset:videoAsset];
generator.maximumSize = bottomView.frame.size;
generator.appliesPreferredTrackTransform = YES;
generator.requestedTimeToleranceBefore = kCMTimeZero;
generator.requestedTimeToleranceAfter = kCMTimeZero;
// 添加需要帧数的时间集合
self.framesArray = [NSMutableArray array];
for (int i = 0; i < videoSumTime; i++) {
CMTime time = CMTimeMake(i *videoAsset.duration.timescale , videoAsset.duration.timescale);
NSValue *value = [NSValue valueWithCMTime:time];
[self.framesArray addObject:value];
}
NSMutableArray *imgArray = [NSMutableArray array];
__block long count = 0;
[generator ge