AVPlayer дрожит при воспроизведении AVMutableComposition - PullRequest
0 голосов
/ 08 октября 2018

На iPhone 6s под управлением iOS 11 я запускаю следующий код для создания AVMutableComposition и запуска его на AVPlayer.Проблема в том, что 3840x2160 видео нервничают, если я загружаю композицию.Не возникает проблем, если я загружаю AVURLAsset, созданный с использованием того же URL-адреса видеофайла.Кто-нибудь знает об этой проблеме?

 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)
        }
    }
}

РЕДАКТИРОВАТЬ: Я нашел проблему.У меня был скруббер, который генерировал миниатюры, используя copyCGImage (иногда :) API AVAssetImageGenerator.Переключился на генерацию CGImagesAsynchronically для раз, и проблема решена.Не уверен, почему copyCGImage постоянно вызывает зависание AVPlayer, что также только при использовании AVComposition, а не при использовании AVURLAsset.

...