Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why AVPlayerItem's canPlayFastForward method returns False?

I really want to implement fast forward and reverse play with AVFoundation.

As far as I know I can only play 0.0 ~ 2.0 rate with AVPlayer if AVPlayerItem's canPlayReverse and canPlayFastForward returns False.

But I need -1.0 and also rate over 2.0.

My problem is that I just can't find when and why the results is false.

There is no mention about when canPlayFastForward returns false on Apple's doc.

Can anyone explain when and why the results of canPlayFastForward & canPlayReverse is false and how can I change it to true?

like image 377
KimCrab Avatar asked Apr 13 '16 23:04

KimCrab


1 Answers

Possibility is you are checking the AVPlayerItem's canPlayReverse or canPlayFastForward before the AVPlayerItem's property status changes to .readToPlay. If you are doing so, you will always get false.

Don't do like this:

import AVFoundation

let anAsset = AVAsset(URL: <#A URL#>)
let playerItem = AVPlayerItem(asset: anAsset)
let canPlayFastForward = playerItem.canPlayFastForward
if (canPlayFastForward){
   print("This line won't execute")
}

Instead observe the AVPlayerItem's property status. Following is the documentation from Apple:

AVPlayerItem objects are dynamic. The value of AVPlayerItem.canPlayFastForward will change to YES for all file-based assets and some streaming based assets (if the source playlist offers media that allows it) at the time the item becomes ready to play. The way to get notified when the player item is ready to play is by observing the AVPlayerItem.status property via Key-Value Observing (KVO).

import AVFoundation
dynamic var songItem:AVPlayerItem! //Make it instance variable

let anAsset = AVAsset(URL: <#A URL#>)
let songItem = AVPlayerItem(asset: anAsset)
playerItem.addObserver(self, forKeyPath: "status", options: .new, context: nil)

Ovveride the observeValue method in the same class:

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        if let status = change?[.newKey] as? Int{
            if(status == AVPlayerItemStatus.readyToPlay.rawValue){
               yourPlayer.rate = 2.0 // or whatever you want
            }
        }

    }

Don't forget to remove this class from songItem's status observer

deinit {
        playerItem.removeObserver(self, forKeyPath: "status")
    }
like image 171
Chanchal Raj Avatar answered Nov 10 '22 23:11

Chanchal Raj