Matt Gallagher's answer in his blog:
"You must observe the current item in the AVQueuePlayer. When it changes, you must use UIApplication to start a backgroundTask and only end the background task when you receive a ready to play notification for the next file."
Actually, this did not helped me.
So my solution is:
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
I can't explain why, but this line of code put before adding new AVPlayerItem made my code work.
Also for those one who adds next track in background and uses method
- (void)loadValuesAsynchronouslyForKeys:(NSArray *)keys completionHandler:(void (^)(void))handler;
You must add AVPlayerItem to player on the main thread.
like this:
- (void)addAsset:(AVAsset*)as
{
[player insertItem:[AVPlayerItem playerItemWithAsset:as] afterItem:[player currentItem]];
}
.........
//adding new track
AVURLAsset* as = [[self createAsset:urlString] retain];
NSArray *keys = [NSArray arrayWithObject:@"tracks"];
[as loadValuesAsynchronouslyForKeys:keys completionHandler:^(void) {
NSError *error =
AVKeyValueStatus trackStatus = [as statusOfValueForKey:@"tracks" error:&error];
switch (trackStatus) {
case AVKeyValueStatusLoaded:
[self performSelectorOnMainThread:@selector(addAsset:) withObject:as waitUntilDone:YES];
[as release];
break;
case AVKeyValueStatusFailed:
[as release];
break;
case AVKeyValueStatusCancelled:
[as release];
break;
default:
break;
}
}];
UPDATE:
Matt Gallagher was right, but it works only if you do not use asynchronous loading.