Hey,
I'm writing an app with the possibility to play HLS streams.
Some HLS streams I have to play have ad-breaks and I have to display them on the custom view progress bar. To do so I create an instance of AVPlayerItemMetadataCollector and add it to AVPlayerItem instance:
swift
let asset = AVURLAsset(url: url)
let item = AVPlayerItem(asset: asset)
let metadataCollector = AVPlayerItemMetadataCollector()
item.add(metadataCollector)
It works as expected when I play the stream on the device. When the player receives the manifest with EXT-X-DATERANGE tags the metadataCollector reports the ad-breaks via its delegate's metadataCollector( , didCollect: , indexesOfNewGroups: , indexesOfModifiedGroups: ) method.
But suppose, I've started a playback, switched to AirPlay, and closed the player on the device. In this case, the AirPlay device stays connected, so that if I start the playback again (the same item or another), the playback will start at once on AirPlay.
The issue in this case is:
When the playback starts at once on AirPlay, the AVPlayerItemMetadataCollector instance doesn't report any ad-breaks to its delegate.
I've tested this behavior with iPhones (iOS 14.3) and Apple TV 4K (tvOS 14.4) and LG TV with AirPlay 2 support.
Is something wrong with AVPlayerItemMetadataCollector configuration or is it an expected behavior or an iOS bug?
Post
Replies
Boosts
Views
Activity
Hello!
I'm writing an app with a possibility to play HLS streams.
I make a KVO subscription for AVPlayer.timeControlStatus to change the state of custom trickplay controls.
When I switch the playback from the device to an AirPlay device (Apple TV 4K for instance), the KVO subscription is triggerred once with .paused state and then stops getting updates. However the playback is active on the AppleTV in the same time. Also I have a periodicTimeObserver with period of 1 sec and this observer continues getting triggered each second. But if I print out the timeControlState of the player inside this periodicObserver it stays .paused. It's more strange as periodicObserver should not be triggered when prayer is in .paused state.
When I pause/play the playback using remote control of the Apple TV everything starts working as expected: AVPlayer.timeControlStatus updates begin trigger KVO observation, periodicObserver is being triggered only when playback is active and timeControlStatus is .paying.
I tried to simulate it in the clean project and prepared the project that just presents an AVPlayerViewController that shows a video from the hardcoded URL. And all the issues are being reproduced in the same way in the clean project. Please, find the listing below.
I've tested this behavior with iOS 12.3.1 and 14.3 iPhones and AplleTV 4K tvOS 14.4.
Is something wrong with AVPlayer configuration or is it an expected behavior or an iOS bug?
swift
class ViewController: UIViewController {
private var player: AVPlayer?
private var obs: NSKeyValueObservation?
@IBAction func playVideo(_ sender: Any) {
guard let url = URL(string: "https://bitdash-a.akamaihd.net/content/MI201109210084_1/m3u8s/f08e80da-bf1d-4e3d-8899-f0f6155f6efa.m3u8") else {
return
}
player = AVPlayer(url: url)
player?.addPeriodicTimeObserver(
forInterval: CMTime(seconds: 1, preferredTimescale: 600),
queue: DispatchQueue.main
) { [weak player] _ in
print("#$#$player timeControlStatus: \(player?.timeControlStatus.rawValue)")
}
obs = player?.observe(\AVPlayer.timeControlStatus) { player, _ in
print("#$#$timeControlStatus changed to: \(player.timeControlStatus.rawValue)")
}
let controller = AVPlayerViewController()
controller.player = player
present(controller, animated: true) {
self.player?.play()
}
}
}