Подтвердить что ты не робот

AVPlayer replaceCurrentItemWithPlayerItem не работает на iOS 4.3.3+

У меня есть аудиоплеер, который я создаю с помощью AVPlayer.

В настоящее время я сохраняю экземпляр player и когда мне нужно поменять дорожки (либо с помощью ручного выбора, либо заканчивается трек), я создаю новый AVPlayerItem, и я вызываю replaceCurrentItemWithPlayerItem с новым пункт.

В соответствии с документами replaceCurrentItemWithPlayerItem является асинхронной операцией, поэтому я также наблюдаю текущий ключевой путь текущего игрока. Когда это вызвано, я говорю игроку играть.

Вот соответствующий код:

AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:asset];
[playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:CHStreamingAudioPlayer_PlayerItemStatusChangedContext];

if (!_player) {
    _player = [[AVPlayer alloc] initWithPlayerItem:playerItem]; 
    [_player addObserver:self forKeyPath:@"status"          options:NSKeyValueObservingOptionNew context:CHStreamingAudioPlayer_PlayerStatusChangedContext];
    [_player addObserver:self forKeyPath:@"currentItem"     options:NSKeyValueObservingOptionNew context:CHStreamingAudioPlayer_PlayerCurrentItemChangedContext];
} else {
    [_player replaceCurrentItemWithPlayerItem:playerItem];
}

И вот обратный вызов наблюдения ключевого значения:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    if (context == CHStreamingAudioPlayer_PlayerCurrentItemChangedContext) {
        NSLog(@"Player current item changed! Change dictionary: %@", change);
        if (_player.currentItem) {
            [self play]; //<---- doesn't get called
        }
    } else {
        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
}

В iOS 4.3.3 (и iOS 5) мой ключевой метод наблюдения вызывается, но _player.currentItem всегда nil. В 4.2.1 и 4.3.2 это свойство содержит фактическое значение. Этот метод никогда не вызывается снова. Таким образом, по сути, замена, похоже, всегда терпит неудачу.

Это похоже на ошибку, но, возможно, я что-то делаю неправильно.

4b9b3361

Ответ 1

У меня была эта проблема с iOS 5 (включая 5.0.1). Он отлично работал на iOS 4.x.

Есть два способа обхода этого, отпустите и заново создайте AVPlayer с нужным AVPlayerItem каждый раз, когда вам нужно поменять дорожки. Или просто вызовите replaceCurrentItemWithPlayerItem: в основной поток.

Я попробовал оба варианта, и они отлично работали.

Кредиты на: Форумы разработчиков Apple

Ответ 2

У меня возникли подобные проблемы. Вероятно, вы начали с AVPlayerDemoPlaybackViewController из примера кода Apple, как и я. Возможно, проблема в том, что currentItem есть nil, потому что он еще не загружен или не готов к воспроизведению (моя проблема заключалась в том, что я не мог получить продолжительность нового AVPlayerItem).

Вы можете попробовать начать воспроизведение, если наблюдаемый статус currentItem равен ReadyToPlay.

AVPlayerStatus status = [[change objectForKey:NSKeyValueChangeNewKey] integerValue];
    switch (status) {
        case AVPlayerStatusUnknown: {
            NSLog(@"PLAYER StatusUnknown");
        }
            break;
        case AVPlayerStatusReadyToPlay: {
            NSLog(@"PLAYER ReadyToPlay");
            [self play];
        }
            break;
        case AVPlayerStatusFailed: {
            AVPlayerItem *playerItem = (AVPlayerItem *)object;
            [self handleError: [playerItem.error localizedDescription]];
        }
            break;
    }

Я не знаю, будет ли это для вас, я не пробовал это на более низком или выше 4.3.4 iPad, поэтому, я думаю, скоро у меня появятся осложнения.