ios cocoa-touch mpmovieplayercontroller avplayer ios8.4

Un AVPlayerItem no se puede asociar con más de una instancia de AVPlayer en iOS 8.4



cocoa-touch mpmovieplayercontroller (2)

Después de actualizar a iOS 8.4, recibo la infame excepción con MPMoviePlayerController que dice:

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

He visto varias soluciones que consisten principalmente en reiniciar el reproductor antes de volver a utilizarlo. Sin embargo, para mí el bloqueo no ocurre cuando intento reproducir un video nuevo, sino cuando apago la pantalla completa para el reproductor girando al modo vertical.

Este es mi código:

@implementation MoviePlayerViewController -(void)viewDidLoad { [super viewDidLoad]; self.moviePlayer.controlStyle = MPMovieControlStyleEmbedded; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayerWillEnterFullscreenNotification:) name:MPMoviePlayerWillEnterFullscreenNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayerWillExitFullscreenNotification:) name:MPMoviePlayerWillExitFullscreenNotification object:nil]; } - (void) moviePlayerWillEnterFullscreenNotification:(NSNotification*)notification { [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceOrientationDidChange) name:UIDeviceOrientationDidChangeNotification object:nil]; } - (void) moviePlayerWillExitFullscreenNotification:(NSNotification*)notification { [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications]; [[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil]; } - (void)deviceOrientationDidChange { UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation]; if (orientation == UIDeviceOrientationPortrait) { [self.moviePlayer setFullscreen:NO animated:YES]; } } @end

El cambio a pantalla completa ocurre en el UIViewController que tiene MoviePlayerViewController como subvista u:

-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { if (!self.moviePlayerViewController.moviePlayer.fullscreen && UIInterfaceOrientationIsPortrait(fromInterfaceOrientation)) { [self.moviePlayerViewController.moviePlayer setFullscreen:YES animated:YES]; } }

No hay problema cuando entro o salgo de la pantalla completa manualmente usando el botón de pantalla completa en el reproductor. También puedo rotar el reproductor en pantalla completa sin problemas. Sin embargo, cuando intento rotarlo de pantalla completa (es decir, de paisaje a retrato) obtengo la excepción, aparentemente en la línea:

[self.moviePlayer setFullscreen:NO animated:YES];

Aquí está mi rastro de la pila cuando ocurre la excepción:

Thread : Fatal Exception: NSInvalidArgumentException 0 CoreFoundation 0x00000001865e02d8 __exceptionPreprocess 1 libobjc.A.dylib 0x0000000197f3c0e4 objc_exception_throw 2 AVFoundation 0x0000000184db4b50 -[AVPlayerItem _attachToFigPlayer] 3 AVFoundation 0x0000000184da7770 -[AVPlayer _attachItem:andPerformOperation:withObject:] 4 AVFoundation 0x0000000184dc8f00 -[AVQueuePlayer insertItem:afterItem:] 5 MediaPlayer 0x00000001889d1d30 -[MPQueuePlayer insertItem:afterItem:] 6 MediaPlayer 0x000000018893de7c -[MPAVQueueCoordinator _syncPlayerItems] 7 MediaPlayer 0x000000018893d8a4 -[MPAVQueueCoordinator _syncItems] 8 MediaPlayer 0x000000018893c68c -[MPAVQueueCoordinator reloadItemsKeepingCurrentItem:] 9 MediaPlayer 0x000000018899fd38 -[MPAVPlaylistManager setPlaylistFeeder:startIndex:keepPlaying:] 10 MediaPlayer 0x000000018899fb4c __67-[MPAVPlaylistManager reloadWithPlaybackContext:completionHandler:]_block_invoke 11 MediaPlayer 0x000000018889fa5c -[MPArrayQueueFeeder reloadWithPlaybackContext:completionHandler:] 12 MediaPlayer 0x000000018899f9b4 -[MPAVPlaylistManager reloadWithPlaybackContext:completionHandler:] 13 MediaPlayer 0x00000001888b7550 -[MPAVController reloadWithPlaybackContext:completionHandler:] 14 MediaPlayer 0x000000018888d114 -[MPMoviePlayerControllerNew _prepareToPlayWithStartIndex:] 15 MediaPlayer 0x000000018888a988 -[MPMoviePlayerControllerNew _moviePlayerDidBecomeActiveNotification:] 16 CoreFoundation 0x00000001865862c4 __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ 17 CoreFoundation 0x00000001864c3450 _CFXNotificationPost 18 Foundation 0x00000001873f2a80 -[NSNotificationCenter postNotificationName:object:userInfo:] 19 MediaPlayer 0x000000018888d530 -[MPMoviePlayerControllerNew _postNotificationName:object:userInfo:] 20 MediaPlayer 0x000000018888d494 -[MPMoviePlayerControllerNew _postNotificationName:object:] 21 MediaPlayer 0x00000001888878dc -[MPMoviePlayerControllerNew setFullscreen:animated:] 22 myApp 0x000000010004ddf8 -[MoviePlayerViewController deviceOrientationDidChange] (MoviePlayerViewController.m:36) 23 CoreFoundation 0x00000001865862c4 __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ 24 CoreFoundation 0x00000001864c3450 _CFXNotificationPost 25 Foundation 0x00000001873f2a80 -[NSNotificationCenter postNotificationName:object:userInfo:] 26 UIKit 0x000000018b059b34 -[UIDevice setOrientation:animated:] 27 UIKit 0x000000018b0597f0 -[UIApplication handleEvent:withNewEvent:] 28 UIKit 0x000000018b059080 -[UIApplication sendEvent:] 29 UIKit 0x000000018b0c52c4 _UIApplicationHandleEvent 30 GraphicsServices 0x000000018fdc9194 _PurpleEventCallback 31 GraphicsServices 0x000000018fdc8c84 PurpleEventCallback 32 CoreFoundation 0x0000000186597a54 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ 33 CoreFoundation 0x00000001865979b4 __CFRunLoopDoSource1 34 CoreFoundation 0x0000000186595934 __CFRunLoopRun 35 CoreFoundation 0x00000001864c12d4 CFRunLoopRunSpecific 36 GraphicsServices 0x000000018fdc76fc GSEventRunModal 37 UIKit 0x000000018b0bef40 UIApplicationMain 38 myApp 0x000000010002b2dc main (main.m:16) 39 libdyld.dylib 0x00000001985e6a08 start


La solucion es:

No use MPMoviePlayerController , lo siento. Refactor para usar AVPlayerViewController en AVPlayerViewController lugar. Esta es una API más moderna; el que está usando ha quedado obsoleto, por lo que no es sorprendente que tenga un extraño y misterioso crash en una versión más nueva de iOS.


Tuve un problema que te suena familiar, pero puede o no ser exactamente lo mismo. Tenía varios controles de vista y estaba arreglando que un controlador de vista suspendiera su película para que otra pudiera jugar. Pero cuando el dispositivo giraba, el controlador estándar de la barra de pestañas de iOS que estaba usando cargaba los otros controladores de vista (llamando a viewDidLoad, creo) para cualquier otra pestaña en la barra de pestañas si aún no se habían cargado. No esperaba este comportamiento, ya que las pestañas nunca fueron seleccionadas por mí. Mi código para cargar la película estaba en viewDidLoad, por lo que estaba intentando comenzar a reproducir otra película en el otro controlador de vista al que nunca se le había pedido que "apareciera". Me tomó un tiempo darme cuenta de lo que estaba sucediendo porque los dos controladores de vista heredaban de la misma clase base y parecía el objeto correcto en el depurador, hasta que miré más de cerca.

Si la memoria se sirve, moví el código para cargar y comenzar a reproducir mis películas en viewWillAppear para que no se ejecutara a menos que la pestaña realmente estuviera seleccionada. Luego, cuando se gira el dispositivo y el otro controlador de visualización se carga de repente, no tiene efectos secundarios adversos. Aún así es extraño ver que hace eso.