Maintaining good scroll performance when using AVPlayer

后端 未结 6 1089
无人及你
无人及你 2020-11-30 17:34

I\'m working on an application where there is a collection view, and cells of the collection view can contain video. Right now I\'m displaying the video using AVPlayer

6条回答
  •  Happy的楠姐
    2020-11-30 18:11

    Don't know if this will help – but here's some code I'm using to load videos on background queue that definitely helps with main thread blocking (Apologies if it doesn't compile 1:1, I abstracted from a larger code base I'm working on):

    func loadSource() {
        self.status = .Unknown
    
        let operation = NSBlockOperation()
        operation.addExecutionBlock { () -> Void in
        // create the asset
        let asset = AVURLAsset(URL: self.mediaUrl, options: nil)
        // load values for track keys
        let keys = ["tracks", "duration"]
        asset.loadValuesAsynchronouslyForKeys(keys, completionHandler: { () -> Void in
            // Loop through and check to make sure keys loaded
            var keyStatusError: NSError?
            for key in keys {
                var error: NSError?
                let keyStatus: AVKeyValueStatus = asset.statusOfValueForKey(key, error: &error)
                if keyStatus == .Failed {
                    let userInfo = [NSUnderlyingErrorKey : key]
                    keyStatusError = NSError(domain: MovieSourceErrorDomain, code: MovieSourceAssetFailedToLoadKeyValueErrorCode, userInfo: userInfo)
                    println("Failed to load key: \(key), error: \(error)")
                }
                else if keyStatus != .Loaded {
                    println("Warning: Ignoring key status: \(keyStatus), for key: \(key), error: \(error)")
                }
            }
            if keyStatusError == nil {
                if operation.cancelled == false {
                    let composition = self.createCompositionFromAsset(asset)
                    // register notifications
                    let playerItem = AVPlayerItem(asset: composition)
                    self.registerNotificationsForItem(playerItem)
                    self.playerItem = playerItem
                    // create the player
                    let player = AVPlayer(playerItem: playerItem)
                    self.player = player
                }
            }
            else {
                println("Failed to load asset: \(keyStatusError)")
            }
        })
    
        // add operation to the queue
        SomeBackgroundQueue.addOperation(operation)
    }
    
    func createCompositionFromAsset(asset: AVAsset, repeatCount: UInt8 = 16) -> AVMutableComposition {
         let composition = AVMutableComposition()
         let timescale = asset.duration.timescale
         let duration = asset.duration.value
         let editRange = CMTimeRangeMake(CMTimeMake(0, timescale), CMTimeMake(duration, timescale))
         var error: NSError?
         let success = composition.insertTimeRange(editRange, ofAsset: asset, atTime: composition.duration, error: &error)
         if success {
             for _ in 0 ..< repeatCount - 1 {
              composition.insertTimeRange(editRange, ofAsset: asset, atTime: composition.duration, error: &error)
             }
         }
         return composition
    }
    

提交回复
热议问题