播放AVMutableComposition时AVPlayer抖动

时间:2018-10-08 17:07:51

标签: ios avfoundation avplayer avmutablecomposition avcomposition

在运行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时冻结。

0 个答案:

没有答案