Ruben Martinez Jr.
Ruben Martinez Jr.

Reputation: 3110

AVPlayer Not Recovering After Buffering

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

Answers (1)

ykay
ykay

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

Related Questions