AVAsset
AVAsset是一个表现音视频媒体的抽象类.AVAsset对象给我们开发提供了媒体文件的访问接口.
这个 AVAsset 可以通过文件创建,也可以是来自用户相册目录的.如果获得了一个视频文件的 AVAsset,我们就可以从中获取静态图片,转换格式,或者是裁剪内容.
通过以下代码,获得特定位置的视频文件:
1 | NSString * videoPath = @"a video file path"; AVAsset *anAsset = [[AVURLAsset alloc] initWithURL:[NSURL fileURLWithPath:videoPath] options:nil]; ```objc 其中 options 是一个字典,这个字典只有一个 key-value: `AVURLAssetPreferPreciseDurationAndTimingKey` value 是 `YES` 或者 `NO` 这个是设置时间精确度的,如果设置为 YES, 那么会造成很大的开销,但是可以保证操作的精度,对于我的裁剪操作,不用设置.因为我的业务中,裁剪范围是用户滑块操作的,本来精度就要求不高. 传递 nil 和 传递 NO, 两者等效. 特别的,当进行视频合成操作的时候,需要设置这个字典,并将 value 设置为 `YES`,因为如果精度不够,可能造成音视频不同步等问题. ### AVAssetExportSession AVAssetExportSession 是一个控制 Asset 异步导出的对象.可以实现裁剪视频,转换格式等需求. 代码如下: |
exportSession_ = [[AVAssetExportSession alloc]
initWithAsset:anAsset presetName:AVAssetExportPreset960x540]1
2
3
4
这个`presetName` 是系统提供的预设,有一些常用的视频分辨率和视频质量控制的选项.可以按住`command`自行查看.另外.如果预设的分辨率不能满足需求,我们还可以自定义任意分辨率,这个将在我以后的文章中进行说明.
然后就是配置`AVAssetExportSession`,下面分别配置了`导出路径`,`导出文件格式`,`截取范围`:
exportSession.outputURL = tempVideoURL;
exportSession.outputFileType = AVFileTypeMPEG4;
exportSession_.timeRange = [self videoTimeRange:anAsset];1
需要说明的是这个截取范围的实现:
-(CMTimeRange)videoTimeRange:(AVAsset*)anAsset{
CMTime start = CMTimeMakeWithSeconds(self.videoRange.startTime, anAsset.duration.timescale);
CMTime duration = CMTimeMakeWithSeconds(self.videoRange.duration, anAsset.duration.timescale);
CMTimeRange range = CMTimeRangeMake(start, duration);
return range;
}1
2
3
4
5`CMTime` 是一个结构体对象,常用的两个值是: `value` 和 `timescale`. 两者的关系可以表示为: `value/timescale=seconds`.
在上面的方法中,我将来自滑块的值(秒为单位),转换成了`CMTime`然后构造了一个` CMTimeRange` 对象.
最后进行导出:
[exportSession exportAsynchronouslyWithCompletionHandler:^{
switch (exportSession.status) {
case AVAssetExportSessionStatusUnknown: {
break;
}
case AVAssetExportSessionStatusWaiting: {
break;
}
case AVAssetExportSessionStatusExporting: {
break;
}
case AVAssetExportSessionStatusCompleted: {
break;
}
case AVAssetExportSessionStatusFailed: {
break;
}
case AVAssetExportSessionStatusCancelled: {
break;
}
}
}];
```objc
可以对各种状态进行判断.进而采取不同的操作.通常关心的是Failed
和Completed
,前者给用户提示,后者进行后续操作.
到此,就完成了一段视频的裁剪操作.