AVQueuePlayer проигрывает несколько звуковых дорожек в фоновом режиме iOS5 - PullRequest
1 голос
/ 20 ноября 2011

Я использовал AVQueuePlayer для воспроизведения нескольких элементов в фоновом режиме. И код прекрасно работал в iOS4. А в iOS5 AVQueuePlayer изменил свое поведение, поэтому игрок перестает играть после завершения первого элемента.

Мэтт Галлахер написал подсказку в этом сообщении . «Начиная с iOS 5, похоже, что AVQueuePlayer больше не выполняет предварительную буферизацию. Он предварительно буферизовал следующую дорожку в iOS 4».

Поэтому мой вопрос заключается в том, как воспроизвести несколько элементов в фоновом режиме, используя AVPlayer или AVQueuePlayer в iOS5.

1 Ответ

1 голос
/ 21 ноября 2011

Ответ Мэтта Галлахера в его блоге : «Вы должны наблюдать текущий элемент в AVQueuePlayer. Когда он изменяется, вы должны использовать UIApplication, чтобы запустить backgroundTask, и завершить фоновую задачу только тогда, когда вы получите уведомление о готовности к воспроизведению следующего файла.»

На самом деле, это не помогло мне.

Итак, мое решение:

[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];

Я не могу объяснить, почему, но эта строка кода, добавленная до добавления нового AVPlayerItem, заставила мой код работать. Также для тех, кто добавляет следующий трек в фоновом режиме и использует метод

- (void)loadValuesAsynchronouslyForKeys:(NSArray *)keys completionHandler:(void (^)(void))handler;

Вы должны добавить AVPlayerItem к игроку в главном потоке. как это:

- (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: Мэтт Галлахер был прав, но это работает, только если вы не используете асинхронную загрузку.

...