起因
有用户反馈上传慢动作视频后,视频为正常状态的视频,而不是慢动作视频,在视频列表界面中显示的视频时间长度也不正确。 打开系统相处进行查看时,显示的视频时间长度也是正常状态的视频时间长度,而不是慢动作状态下的视频时间长度,但是打开播放后就是慢动作视频。 系统提供了编辑慢动作视频的功能,可以选择慢动作区域,由此可以推测出,系统存取在相册中的是正常状态下的视频, 在播放时在通过视频的对应信息来控制播放的速度。 那么如何导出正确的视频资源和显示正确的视频时间呢?
播放对应的视频和显示正确的时间
播放对应的视频
无论播放的视频是什么类型,都是通过 PHAsset 获取到对应的 AVAsset ,然后通过 AVAsset 进行播放。 在通过 PHAsset 获取 AVAsset 时,是通过以下方法来获取:
1
2
3
4
5
6
7
let imageManager = PHCachingImageManager()
let requestOptions = PHVideoRequestOptions()
requestOptions.version = .original
imageManager.requestAVAsset(forVideo: asset,
options: requestOptions,
resultHandler: { (asset, audioMix, info) in
})
PHVideoRequestOptions 有个 version 的属性,可用于设置获取到的 AVAsset 对应的资源是哪个,再结合相册里面的是正常的视频,可以得出如果设置 version 为 original ,获取的 AVAsset 对应的是正常的视频资源。version 还可以设置 current ,再设置为 current 后,使用 AVPlayer 播放的就是慢动作的视频了。
显示正确的时间
PHAsset 有个 duration 属性,一般情况下使用 PHAsset 的 duration 既可,系统相册估计也是直接使用 duration 来表示时间。但是,在遇到慢动作视频的时候,duration 显示的则是正常状态的视频时间长度,那么如何获取慢动作视频时间长度呢?我们从上面的代码已经可以获取到慢动作视频对应的 AVAsset ,直接使用 AVAsset 的 duration 属性,再转化为秒,就是慢动作视频的时间长度了:
1
let seconds = lround(CMTimeGetSeconds(avAsset.duration))
但是普通的视频是可以直接使用 PHAsset 的 duration ,大多数视频也都是正常视频,是否可以通过 PHAsset 判断是否为慢动作视频,从而选择不同的方式来获取视频时间。其实慢动作视频也是通过普通视频以慢动作方式播放出来,其本质还是普通视频,只是帧率比较高。而 PHAsset 有个 mediaSubtypes 属性,它是 PHAssetMediaSubtype 类型,而 PHAssetMediaSubtype 则有 videoHighFrameRate 这个选项,说明如下:
High-frame-rate videos are created by the Slow-Mo feature in the Camera app on an iOS device.
可见 PHAsset 如果对应的是慢动作视频,那么它的 mediaSubtype 就会包含 videoHighFrameRate ,所以可以得出判断方式:
1
2
3
4
5
extension PHAsset {
var isSlowMotionVideo: Bool {
return mediaSubtypes.contains(PHAssetMediaSubtype.videoHighFrameRate)
}
}
如何导出慢动作视频
有文章说到慢动作视频获取到的 AVAsset 为 AVComposition ,我在 iOS 13.1 和 iOS 12.4.1 上获取的都是 AVURLAsset 类,或许其它版本获取到的是 AVComposition 类,无论获取到的是 AVURLAsset 还是 AVComposition 类,我们在编辑视频时都以 video tracks 的最后一条 track 为依据即可。
Comments powered by Disqus.