The post How to get media duration from your iOS video player (AVPlayer) appeared first on Now Playing Apps.
]]>If you are developing a custom video player skin, chances you have to somehow show the overall duration of the current playing media. And using AVPlayerItem’s duration is the best way of doing this. And this is how duration is accessed.
(lldb) po playerItem!.duration.seconds
nan
However, when done this way after we start playing, we get this “nan”
The problem here is we are trying to access the duration before AVPlayer gets a chance to download the content (or manifest if using a streaming protocol like HLS). And the solution is to wait for the right time.
Simple answer. When the content is ready. Or otherwise when AVPlayerItem.Status.readyToPlay
. Let’s see it in code
let streamURL = "http://184.72.239.149/vod/smil:BigBuckBunny.smil/playlist.m3u8"
playerItem = AVPlayerItem(url: URL(string: streamURL)!)
player = AVPlayer(playerItem: playerItem)
playerItem?.addObserver(self, forKeyPath: #keyPath(AVPlayerItem.status), options: [.old, .new], context: nil)
and then observing like this:
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == #keyPath(AVPlayerItem.status), let statusNumber = change?[.newKey] as? NSNumber {
switch statusNumber.intValue {
case AVPlayerItem.Status.readyToPlay.rawValue:
let durationInSeconds = playerItem?.asset.duration.seconds ?? 0
print("Ready to play. Duration (in seconds): \(durationInSeconds)")
default: break
}
}
}
When you take this approach, make sure to remove the observer when you close the player or change playerItem inside the player
playerItem?.removeObserver(self, forKeyPath: #keyPath(AVPlayerItem.status))
With Swift 4, listening to changes like these are even easier. This is how:
observation = playerItem?.observe(\AVPlayerItem.status, changeHandler: { observedPlayerItem, change in
if (observedPlayerItem.status == AVPlayerItem.Status.readyToPlay) {
print("Current stream duration \(observedPlayerItem.duration.seconds)")
}
})
It is easy to remove this observer, just assign it to nil
. Here’s the link to the WWDC video
And that’s it! Happy streaming.
The post How to get media duration from your iOS video player (AVPlayer) appeared first on Now Playing Apps.
]]>