2011-09-14 18 views
15

Tengo un reproductor de audio que estoy compilando con AVPlayer.AVPlayer replaceCurrentItemWithPlayerItem no funciona en iOS 4.3.3+

Actualmente, mantener la instancia player alrededor y cuando necesito para intercambiar pistas (ya sea a partir de una selección manual o la pista ha llegado al final) creo un nuevo AVPlayerItem y me llaman replaceCurrentItemWithPlayerItem con el nuevo elemento.

De acuerdo con los documentos, replaceCurrentItemWithPlayerItem es una operación asíncrona, por lo que también observo la ruta de acceso currentItem del reproductor. Cuando se llama, le digo a mi jugador que juegue.

Este es el código correspondiente:

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]; 
} 

Y aquí está la clave de devolución de llamada de observación valor:

- (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]; 
    } 
} 

En iOS 4.3.3 (y el IOS 5) se llama mi método de observación clave, pero _player.currentItem es siempre nil. En 4.2.1 y 4.3.2 esta propiedad contiene el valor real. Este método nunca se llama de nuevo. Entonces, en esencia, reemplazar parece fallar siempre.

Esto parece un error, pero quizás estoy haciendo algo mal.

+0

¿La respuesta a continuación por Dunja resolver su problema? –

Respuesta

17

Tuve este problema con iOS 5 (incluyendo 5.0.1). Solía ​​funcionar bien en iOS 4.x.

Hay dos formas de solucionar esto, liberar y recrear su AVPlayer con el AVPlayerItem s deseado cada vez que necesite intercambiar pistas. O simplemente, llame al replaceCurrentItemWithPlayerItem: en el hilo principal.

Intenté ambas opciones y funcionaron bien.

Créditos a: Apple Developer Forums

+0

Al ejecutar el hilo principal, solucioné el error por mí. – vaughan

1

He estado teniendo problemas similares. Probablemente comenzó desde AVPlayerDemoPlaybackViewController from Apple sample code como yo. Tal vez el problema por el que currentItem es nil es porque no está cargado o listo para su reproducción (mi problema era que no pude obtener la duración del nuevo AVPlayerItem).

Puede intentar iniciar la reproducción cuando el estado observado de currentItem es 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; 
    } 

No sé si esto va a wok para ti, no lo probé esto en menor o mayor que el iPad 4.3.4, así que supongo que voy a correr en complicaciones pronto.

Cuestiones relacionadas