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 это свойство содержит фактическое значение. Этот метод никогда не вызывается снова. Таким образом, по сути, замена, похоже, всегда терпит неудачу.
Это похоже на ошибку, но, возможно, я что-то делаю неправильно.
Ответы
Ответ 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, поэтому, я думаю, скоро у меня появятся осложнения.