[ACCEPTED]-AVPlayer Item get a nan duration-avplayer

Accepted answer
Score: 14

The value of duration property will be reported 11 as kCMTimeIndefinite until the duration of the underlying 10 asset has been loaded. There are two ways 9 to ensure that the value of duration is 8 accessed only after it becomes available:

  1. Wait 7 until the status of the AVPlayerItem is AVPlayerItemStatusReadyToPlay.

  2. Register for 6 key-value observation of the duration property, requesting 5 the initial value. If the initial value 4 is reported as kCMTimeIndefinite, the AVPlayerItem will notify you of 3 the availability of the item's duration 2 via key-value observing as soon as its value 1 becomes known.

Score: 7

For swift:

if player.currentItem.status == .readyToPlay {

    print(currentItem.duration.seconds) // it't not nan

}

0

Score: 4

I have this problem on iOS 12 (for iOS 13 5 everything works as expected). Current item's 4 duration is always indefinite. I solve it 3 by using player.currentItem?.asset.duration. Something like this:

private var currentItemDuration: CMTime? {
    if #available(iOS 13.0, *) {
        return player?.currentItem?.duration
    } else {
        return player?.currentItem?.asset.duration
    }
}

See this 2 answer for macOS: https://stackoverflow.com/a/52668213/7132300 It looks like it's also 1 valid for iOS 12.

Score: 2

@voromax is correct. I added the asset to the playerItem without 3 getting the duration first and duration was nan:

let asset = AVAsset(url: videoUrl)
self.playerItem = AVPlayerItem(asset: asset)

When 2 I loaded the asset.loadValuesAsynchronously first, no more nan and I got 1 the correct duration:

let assetKeys = ["playable", "duration"]

let asset = AVAsset(url: url)
asset.loadValuesAsynchronously(forKeys: assetKeys, completionHandler: {
    DispatchQueue.main.async { [weak self] in
        self?.playerItem = AVPlayerItem(asset: asset, automaticallyLoadedAssetKeys: assetKeys)
    }
})
Score: 2

You can use asset property. It will give 1 you the duration.

self.player.currentItem?.asset.duration.seconds ?? 0
Score: 1

I had the same problem but I was able to 2 get the duration with a different method. Please 1 see my answer here: https://stackoverflow.com/a/38406295/3629481

More Related questions