Does anyone know if AVQueuePlayer starts buffering the next AVPlayerItem when the current item is about to finish playing?

I know there's nothing in the docs to suggest this, I'm asking mostly if anyone has observed this kind of behavior or not.


Ok, I've looked over this problem again and written some code to check out AVQueuePlayer.

jollyCocoa's answer pointed me in the right direction by suggesting to observe the status property on AVPlayerItem. However the documentation doesn't seem to point out that this property (and it's AVPlayerItemStatusReadyToPlay value in particular) might be related to buffering.

However the AVPlayerItem's loadedTimeRanges property seems more related to buffering.

Doing KVO on that array was a bit trickier - the array object itself doesn't change, only it's items do - so I resorted to printing out it's content every second.

What I found out is that a few seconds in the queue's first item, the loadedTimeRanges for the second item shows up a new CMTimeRange with start time 0 and some small duration. The duration can increase up to 60 or so seconds while the previous item keeps playing.

Short answer: AVQueuePlayer will buffer the next AVPlayerItem while playing the current one.


As of iOS 5, it appears that AVQueuePlayer no longer pre-buffers. It did pre-buffer the next track in iOS 4.

I'm not sure why there's been a change or if it's even deliberate on Apple's part or simply a bug. In any case, it's a pain and I'll be submitting a bug to them about it.


Found a work around!!! After many hours of searching, and failed tests, I found a solution that works on iOS 5 and above.

This will play files without any delay in between. Not as convenient if you want to switch between files, but will certainly put everything together for you. It's still possible to keep track of where each file starts, when adding AVURLAsset, keep the CMTime variable, something like:

NSValue *toJumpTo = [NSValue valueWithCMTime:composition.duration];
[array addObject:toJumpTo];

and then just go through the array, checking the current time value and comparing it using CMTimeCompare.

Edit: Was found on this page visible from the web archive (the link currently points to spam).


I've been experimenting with the AVQueuePlayer using movies provided by a server. In this particular test I set up a queuePlayer with AVPlayerItems initialized with URL's to two different video assets of different types. One is an .mp4-file (progressive download), the other one an .m3u8 http-streaming file. It does act a bit funky, I must say.

Depending on the order in which I queue the files I get quite different behavior. If I start with the .mp4-file, the AVPlayerLayer goes blank and silent when the nextItem starts player (the .m3u8-file). If I change the order and start with the m3u8-file, the AVPlayerLayer goes blank but the audio from the second file plays fine.

My impression, from what I've seen so far, is that the AVQueuePlayer does NOT start downloading the next AVPlayerItem before the current AVPlayerItem has finished playing. But I might be wrong.

To be continued I guess...

Edit: Ok, so I've done some more testing and it seems the next items starts downloading before the last item finishes playing. See post below. Stroke the "NOT"...

Edit2: Adding my explanation here instead, since the comment left me with no formatting options. (Best practice for this is welcome, if this is a bad way to handle answer updates)

Anyhow, I iterated through my itemsArray adding observation of the status property using KVO...

[playerItem addObserver: self forKeyPath:@"status" options: 0 context: NULL];

I also set my controller as the observer of the AVPlayerItem Notification AVPlayerItemDidPlayToEndTimeNotification:

[[NSNotificationCenter defaultCenter] addObserver: self
                                         selector: @selector(playerItemDidReachEnd:) 
                                             name: AVPlayerItemDidPlayToEndTimeNotification 
                                           object: nil];

Now I could log the status change of the AVPlayerItem, and it turns out the next AVPlayerItem in the queue is logged with a status change AVPlayerItemStatusReadyToPlay before the current item ends playing back.

My conclusion is therefor that the next item in line starts downloading prior to the current item ends.

However! I create an array with AVPlayerItems which I use to create my player. Reading the AVFoundation docs on AVAssets, I get the impression that these download their assets asynchronously, but I'm still uncertain when these downloads are being initiated by the IAPlayerItem. I still have some funky behavior when I add the .m3u8-file to the queue, which makes me wonder if these assets begin downloading at the time of creation (seems a bit strange to me though).