AVPlayer streaming stops in background due to gaps

2019-05-06 09:59发布

问题:

I'm attempting to achieve gapless playback due to iOS idling my AVPlayer when the app is in background mode.

Before answering, yes, I have the plist modified, audio session properly setup and everything is fine and dandy, however my question, I believe, is different in nature.

So, at first I had a method in my class to initialize a new AVPlayer everytime the track URL changed, it worked well but on background not so much, I though that creating a brand new AVPlayer instance every time won't work so I switched to few other paradigms, like replaceCurrentItemWithPlayerItem keeping the AVPlayer instance alive, or even AVQueuePlayer.

The problem I'm facing is that, on iOS 6, the moment audio stops, because one track finished and the other one still has to be loaded, the iPhone freezes my app in background. If I get my app in foreground again, playback resumes normally.

Since I do not have a continuos stream, but rather individual URLs to hit to begin streaming, I though about using AVPlayerQueue and insertItem:next/advanceToNextItem strategies, attempting to not let any minimal audio interruption to freeze the app in background.

The problem however remains, since I have to add the new track in the queue on demand and by the time it buffers iOS already thinks my app is worth stopping. So I need the proper time in the lifecycle of the app to insertItem.

I was then trying to listen to this KVO notification:

[self.player.currentItem addObserver:self forKeyPath:@"playbackBufferFull" options:0 context:MyPlayerItemContext];

but it never, ever gets called. The idea was to keep track of the buffer full on the currentItem and append the next one in playlist so AVQueuePlayer might try to prebuffer it.

Since playbackBufferFull never gets called another idea is to attempt and grab the current time/duration, calculate where a 90% of the playback might be and fire an event at the appropriate time to begin buffering the next track.

Does it sound bad, given that duration properties on objects will and might change based on the progressive incoming data?

What other strategies can I take?

Thanks.

回答1:

I solved it by using a combination of AVQueuePlayer and AVPlayerActionAtItemEndAdvance.

It is tricky but it works.