AVPlayer "freezes" the app at the start of buffering an audio stream

raixer picture raixer · Oct 9, 2011 · Viewed 17k times · Source

I am using a subclass of AVQueuePlayer and when I add new AVPlayerItem with a streaming URL the app freezes for about a second or two. By freezing I mean that it doesn't respond to touches on the UI. Also, if I have a song playing already and then add another one to the queue, AVQueuePlayer automatically starts preloading the song while it is still streaming the first one. This makes the app not respond to touches on the UI for two seconds just like when adding the first song but the song is still playing. So that means AVQueuePlayer is doing something in main thread that is causing the apparent "freeze".

I am using insertItem:afterItem: to add my AVPlayerItem. I tested and made sure that this was the method that was causing the delay. Maybe it could be something that AVPlayerItem does when it gets activated by AVQueuePlayer at the moment of adding it to the queue.

Must point out that I am using the Dropbox API v1 beta to get the streaming URL by using this method call:

[[self restClient] loadStreamableURLForFile:metadata.path];

Then when I receive the stream URL I send it to AVQueuePlayer as follows:

[self.player insertItem:[AVPlayerItem playerItemWithURL:url] afterItem:nil];

So my question is: How do I avoid this? Should I do the preloading of an audio stream on my own without the help of AVPlayer? If so, how do I do this?

Thanks.

Answer

Gigisommo picture Gigisommo · Aug 3, 2012

Don't use playerItemWithURL it's sync. When you receive the response with the url try this:

AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:url options:nil];
NSArray *keys = @[@"playable"];

[asset loadValuesAsynchronouslyForKeys:keys completionHandler:^() {
    [self.player insertItem:[AVPlayerItem playerItemWithAsset:asset] afterItem:nil];
}];