Search code examples
iosswiftavfoundationavplayerhttp-live-streaming

HLS audio stream fails to resume play after time in background (AVPlayer refuses to buffer)


I have an iOS app that is designed to play HLS audio stream content.

The app supports time-shifting - you can skip backward, skip forward, scrub backward/forward, as well as pause the stream and unpause to where you left off.

The app works fine when operating in the foreground. It also works fine when actovely playing in the background (I have the background audio entitlement set correctly).

However, if the app is put into the background for more than a few moments (~30 seconds seems to do it) with the audio paused and either A) the user un-pauses the audio, or B) the user returns the app to the foreground and attempts to un-pause it from there, the audio does not play even after waiting a few moments. Note that the app process is not killed during this time.

To pause and unpause, I am using AVPlayer's pause and play methods.

While looking into it, I verified that the buffer (determined by looking at loadedTimeRanges) is filled during normal playback, but is quickly emptied shortly after the paused app is put in the background. If the app is returned to the foreground quickly enough, the buffer begins to fill again and playback can resume. Otherwise - if the user moves the app to the background for ~30 seconds - the buffer never refills at all and attempting to play again fails until the AVPlayerItem is re-configured.

I realize that there is no guarantee that the buffer will always have content (ie. it could be emptied to minimize memory footprint, which I suspect is the case here), but would expect AVPlayer to begin to start loading audio from it again as needed when playback resumes. Even if it has been in the background for a while.

Does anybody have an idea why this is occurring or how to work around it?

Note: I have created a simple sample iOS 14+ Xcode project that exhibits the problem using a known HLS stream. Tap 'Configure' to load the URL, then play/pause to exhibit the issue (I added console output showing the state of loadedTimeRanges).

https://tapestryapps.com/AudioTestbed.zip

Thank you.


Solution

  • The code works for me on iOS 13.5.1 and iOS 14.4, but fails on 14.0.1. It looks like an iOS bug. You could work around this by recreating the AVPlayerItem when returning to the foreground on affected systems.