在运行iOS 11的iPhone 6s上,我正在运行以下代码来构建AVMutableComposition并在AVPlayer上运行它。问题是3840x2160的视频如果加载合成后会抖动。如果我加载使用相同视频文件url构造的AVURLAsset,没有任何问题。有人知道这个问题吗?
private func buildComposition(_ timeRange:CMTimeRange) {
guard let videoUrl = url else { return }
let composition = AVMutableComposition()
let asset = AVURLAsset(url: videoUrl, options: [AVURLAssetPreferPreciseDurationAndTimingKey : true])
let videotracks = asset.tracks(withMediaType: .video)
var videoTimeRange = timeRange
var audioTimeRange = timeRange
if videotracks.count > 0 {
let compositionVideoTrack = composition.addMutableTrack(withMediaType: .video, preferredTrackID: kCMPersistentTrackID_Invalid)
let srcVideoTrack = videotracks[0]
if !timeRange.isValid {
videoTimeRange = srcVideoTrack.timeRange
}
do {
try compositionVideoTrack?.insertTimeRange(videoTimeRange, of: srcVideoTrack, at: CMTime.zero)
} catch {
NSLog("Unable to insert \(videoTimeRange) in video track")
}
}
let audioTracks = asset.tracks(withMediaType: .audio)
if audioTracks.count > 0 {
let audioTrack = composition.addMutableTrack(withMediaType: .audio, preferredTrackID: kCMPersistentTrackID_Invalid)
let srcAudioTrack = audioTracks[0]
if !timeRange.isValid {
audioTimeRange = srcAudioTrack.timeRange
}
do {
try audioTrack?.insertTimeRange(audioTimeRange, of: srcAudioTrack, at: CMTime.zero)
} catch {
NSLog("Error inserting audio track \(audioTimeRange)")
}
}
self.composition = composition
}
private var composition:AVMutableComposition? {
didSet {
if let asset = composition {
let requestedKeys = ["tracks", "playable"]
asset.loadValuesAsynchronously(forKeys: requestedKeys) {
DispatchQueue.main.async { [unowned self] in
self.preparetoPlay(asset, keys: requestedKeys)
}
}
} else {
playerController?.player?.replaceCurrentItem(with: nil)
}
}
}
编辑:我发现了问题。我有一个洗涤器,它使用AVAssetImageGenerator的copyCGImage(time :) API生成缩略图。切换到异步生成CGImages时间并解决了问题。不确定为什么为什么copyCGImage连续导致AVPlayer冻结,也只能在使用AVComposition时冻结,而在使用AVURLAsset时冻结。