Reputation: 3110
My iOS app uses an AVPlayer
to stream media from the web. I'm using KVO to detect events like buffering (playbackBufferEmpty
) and being caught up (playbackLikelyToKeepUp
). However, I've noticed an eerily specific bug. Although during most network slowdowns, the playbackBufferEmpty
KVO is hit, and when it recovers, the playbackLikelyToKeepUp
KVO is hit as expected, I have noticed that (with some frequency) the AVPlayer
will buffer for some period of time, recover, the playbackLikelyToKeepUp
is hit, the audio plays for maybe 1-3 seconds, and then the audio stops playing again as if it were buffering—without hitting the playbackBufferEmpty
KVO again. And it doesn't recover from this.
TL;DR: playbackBufferEmpty
(10-20 seconds) -> playbackLikelyToKeepUp
-> plays for 1-3s -> stops playing but no KVO is hit.
The worst part is when this happens, the AVPlayer
does not auto-start playing again like it does when recovering from buffering, and the app is silent until the AVPlayer
is manually stopped/started again. It happens more or less every time I stream, eventually. Is this a known issue with AVPlayer
? Is this some third KVO event that I can watch for? Or any tips on how to debug this? Thanks!
EDIT: additional info:
The AVPlayer
's error
property is nil
when this happens, the status
property is Ready to Play, and the rate
property is 1. AKA Nothing else weird going on, as far as I can tell.
Upvotes: 10
Views: 1372
Reputation: 1973
I have also experienced issues with AVPlayer
recovering from buffering / network problems, and I too have the exact same scenario where avPlayer.status
is .readyToPlay
, avPlayer.error
is nil
, and avPlayer.rate
is 1
. Talk about unreliable! I've also checked the errorLog()
and that doesn't provide anything relevant other than a generic internet connection error.
I try to detect this state by having a timer which, when it times out, I check the current video time and the time when the timer started and if it's the same (video hasn't progressed), we can assume the video really isn't playing when it is claiming that it is.
Then I treat this as an unrecoverable state and reload the entire stream by creating a new AVPlayerItem
.
Upvotes: 1