Crash in – Un AVPlayerItem no se puede asociar con más de una instancia de AVPlayer

Tengo un crash que afecta a aproximadamente el 10% de mis usuarios, pero no puedo reproducirlo, y no sé exactamente cuándo ocurre esto.

Crashlytics informa acerca de la mitad de los usuarios que tienen problemas con la aplicación no enfocada, es decir, audio de background o AirPlay. La aplicación reproduce un flujo de video HLS y cambia a una versión de solo audio cuando está en segundo plano.

¿Alguna idea de qué está mal o por qué habría varias instancias de AVPlayer de mi class de jugador Singleton?

¡Gracias!

Exception Type: NSInvalidArgumentException Reason: An AVPlayerItem cannot be associated with more than one instance of AVPlayer Fatal Exception Latest Crash: 4/06/2013 at 8:48:46 UTC+0200 0 CoreFoundation __exceptionPreprocess + 162 1 libobjc.A.dylib objc_exception_throw + 30 2 AVFoundation -[AVPlayerItem _attachToPlayer:] + 188 3 AVFoundation -[AVPlayer _attachItem:andPerformOperation:withObject:] + 336 4 AVFoundation -[AVPlayer _insertItem:afterItem:] + 26 5 AVFoundation -[AVQueuePlayer insertItem:afterItem:] + 136 6 MediaPlayer __block_global_4 + 520 7 ... libdispatch.dylib _dispatch_call_block_and_release + 10 14 

Parece que se resuelve deteniendo explícitamente la reproducción antes de configurar una nueva URL, por ejemplo,

 [moviePlayer stop]; moviePlayer.movieSourceType = MPMovieSourceTypeStreaming; [moviePlayer setContentURL:[NSURL URLWithString:[videos objectForKey:quality]]]; 

Se encontró la causa de este problema … Si se creó MovieViewController y actualmente está en búfer (es decir, estado! = MPMovieLoadStatePlayable o MPMovieLoadStatePlaythroughOK) llamar al método 'play' bloqueará la aplicación con esta exception.

Intente configurar ContentURL después de SourceType

 moviePlayerController_ = [[MPMoviePlayerViewController alloc] init]; moviePlayerController_.movieSourceType = MPMovieSourceTypeStreaming; [moviePlayerController_.moviePlayer setContentURL:url]; 

Si no está seguro de qué tipo de URL de video va a search, configure el tipo de origen en Desconocido. Esto funcionará para todos los casos.

 moviePlayerController = [[MPMoviePlayerViewController alloc] init]; moviePlayerController.movieSourceType = MPMovieSourceTypeUnknown; [moviePlayerController.moviePlayer setContentURL:url]; 

Un par de cosas a tener en count:

  1. Un proxy entre el elemento del jugador y el jugador proporcionaría un medio para controlar el acceso al elemento del jugador por instancias de AVPlayer.

  2. Las references asociadas permiten el almacenamiento de properties agregadas a una class dada a través de una categoría; por lo tanto, podría crear una categoría para la class de elemento de jugador que consiste en una única propiedad que se establece cada vez que el elemento de jugador se asigna a un AVPlayer (es una cadena de descripción, por ejemplo). Para asegurarse de que el ítem del jugador no esté asignado a otro jugador, simplemente compare la descripción almacenada con el AVPlayer con la que devuelve el jugador en cuestión.