2011-09-14 131 views
15

我有一個使用AVPlayer構建的音頻播放器。AVPlayer replaceCurrentItemWithPlayerItem無法在iOS 4.3.3+上工作

目前,我把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's 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上,該屬性包含實際值。這種方法不會再被調用。所以從本質上來說,替換似乎總是失敗。

這看起來像一個錯誤,但也許我做錯了什麼。

+0

Dunja解答了您的問題嗎? –

回答

17

我在iOS 5(包括5.0.1)中遇到了這個問題。它曾經在iOS 4.x上正常工作。

有兩種方法可以解決這個問題,每次需要交換音軌時,發佈並重新創建AVPlayer和期望的AVPlayerItem。或者,只需在主線程上撥打replaceCurrentItemWithPlayerItem:即可。

我試過這兩個選項,他們工作得很好。

積分:Apple Developer Forums

+0

在主線程上運行修復了我的bug。 – vaughan

1

我一直在遇到類似的問題。你可能像我一樣從AVPlayerDemoPlaybackViewController from Apple sample code開始。也許問題是爲什麼currentItemnil是因爲它尚未加載或準備播放(我的問題是我無法獲得新的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高,所以我想我會很快遇到併發症。