2010-07-13 14 views
22

Tengo muchos problemas para mostrar una película a pantalla completa en mi aplicación de iPad y luego permitir que el usuario la cierre con el botón Listo o la "pantalla completa" botón en los controles del jugador.Visualizar y rechazar correctamente MPMoviePlayerController en pantalla completa en iOS 3.2 (iPad)

Inicialmente estaba usando MPMoviePlayerViewController para la presentación de la película, pero no recibía las notificaciones de pantalla completa de entrada/salida desde su objeto MPMoviePlayerController, así que cambié a hacerlo yo mismo.

Puedo hacer que la película aparezca a pantalla completa (aunque la transición es janky), pero cuando se presionan los botones "Hecho" o "Pantalla completa", el jugador no toma ninguna medida. He publicado mi código de abajo:

- (void)startPlayingMovieWithURLString:(NSString *)movieURLString { 
    // I get all of these callbacks **EXCEPT** the "willExitFullScreen:" callback. 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willEnterFullScreen:) name:MPMoviePlayerWillEnterFullscreenNotification object:nil]; 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willExitFullScreen:) name:MPMoviePlayerWillExitFullscreenNotification object:nil]; 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didFinishPlayback:) name:MPMoviePlayerPlaybackDidFinishNotification object:nil]; 

    [self.moviePlayerController setContentURL:someExistingURL]; 

     // "self" is a UIViewController subclass, and is presented as a "fullscreen" modal view controller from its parent 
     // I'm setting the movie player's view's frame to take up the full rectangle of my view controller, but really I want the movie to be completely removed when the user presses "done" (that is, removed from the view hierarchy). Not sure when/where to do this. 
    self.moviePlayerController.view.frame = self.view.frame; 
    [self.view addSubview:self.moviePlayerController.view]; 
    [self.moviePlayerController setFullscreen:YES animated:YES]; 

} 

Y aquí está el código de mi didFinish devolución de llamada

- (void)didFinishPlayback:(NSNotification *)notification { 
     // This ends up recursively telling the player that playback ended, thus calling this method, thus…well you get the picture. 
     // What I'm trying to do here is just make the player go away and show my old UI again. 
    [self.moviePlayerController setFullscreen:NO animated:YES]; 
} 

Así que, obviamente estoy haciendo algo mal, pero he estado arriba y abajo de la documentación y yo no puede entender cómo hacer que la película simplemente se vaya. Pensé que sería más intuitivo que esto. ¿Qué estoy haciendo mal?

Respuesta

66

Éstos son cómo los eventos -> Notificaciones funcionan: prensas

  • de usuario 'Done' botón

    • MPMoviePlayerWillExitFullscreenNotification
    • MPMoviePlayerDidExitFullscreenNotification
  • usuario pulsa 'Salir de pantalla completa' botón en el transporte

    • MPMoviePlayerWillExitFullscreenNotification
    • MPMoviePlayerDidExitFullscreenNotification
    • Tenga en cuenta que la reproducción no se detiene
  • película llega al final

    • MPMoviePlayerPlaybackDidFinishNotification con el conjunto de MPMoviePlayerPlaybackDidFinishReasonUserInfoKeyMPMovieFinishReasonPlaybackEnded
    • Si llama setFullscreen:NO animated:YES en su instancia MoviePlayerController de esta notificación, Se obtiene entonces los WillExitDidExit y notificaciones.
    • Tenga en cuenta que no obtiene la notificación PlaybackDidFinish cuando el usuario presiona los botones Listo o Salir de pantalla completa.

Así que, por lo general, si usted quiere deshacerse de vista del MoviePlayer, es necesario poner [self.moviePlayerController.view removeFromSuperview] en el controlador DidExitFullscreen notificación. WillExitFullscreen es demasiado pronto.

Aquí está mi código:

- (void)willEnterFullscreen:(NSNotification*)notification { 
    NSLog(@"willEnterFullscreen"); 
} 

- (void)enteredFullscreen:(NSNotification*)notification { 
    NSLog(@"enteredFullscreen"); 
} 

- (void)willExitFullscreen:(NSNotification*)notification { 
    NSLog(@"willExitFullscreen"); 
} 

- (void)exitedFullscreen:(NSNotification*)notification { 
    NSLog(@"exitedFullscreen"); 
    [self.movieController.view removeFromSuperview]; 
    self.movieController = nil; 
    [[NSNotificationCenter defaultCenter] removeObserver:self]; 
} 

- (void)playbackFinished:(NSNotification*)notification { 
    NSNumber* reason = [[notification userInfo] objectForKey:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey]; 
    switch ([reason intValue]) { 
     case MPMovieFinishReasonPlaybackEnded: 
      NSLog(@"playbackFinished. Reason: Playback Ended");   
       break; 
     case MPMovieFinishReasonPlaybackError: 
      NSLog(@"playbackFinished. Reason: Playback Error"); 
       break; 
     case MPMovieFinishReasonUserExited: 
      NSLog(@"playbackFinished. Reason: User Exited"); 
       break; 
     default: 
      break; 
    } 
    [self.movieController setFullscreen:NO animated:YES]; 
} 

- (void)showMovie { 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willEnterFullscreen:) name:MPMoviePlayerWillEnterFullscreenNotification object:nil]; 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willExitFullscreen:) name:MPMoviePlayerWillExitFullscreenNotification object:nil]; 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(enteredFullscreen:) name:MPMoviePlayerDidEnterFullscreenNotification object:nil]; 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(exitedFullscreen:) name:MPMoviePlayerDidExitFullscreenNotification object:nil]; 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackFinished:) name:MPMoviePlayerPlaybackDidFinishNotification object:nil]; 

    NSURL* movieURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"tron" ofType:@"mov"]]; 
    self.movieController = [[MPMoviePlayerController alloc] initWithContentURL:movieURL]; 
    self.movieController.view.frame = self.view.frame; 
    [self.view addSubview:movieController.view]; 
    [self.movieController setFullscreen:YES animated:YES]; 
    [self.movieController play]; 
} 
+1

Esto es útil y ahora puedo salir de pantalla completa cuando el usuario presiona, sin embargo, la reproducción finalizada: la devolución de llamada nunca se ejecuta para mí y no puedo entender por qué no. ¿Conoces alguna razón por la que esto podría suceder? – jbrennan

+0

¿Incluso cuando la película se reproduce hasta el final? Eso es extraño, nunca me he encontrado con eso. –

+3

si se llama a MPMoviePlayerDidExitFullscreenNotification al tocar "Listo" y al salir de la pantalla completa, ¿cómo sabe a qué se llama? Tal vez el usuario solo salga de la pantalla completa, en cuyo caso no quiere quitar la vista, supongo. –

0

Sí. Eso es genial. En realidad, hay notificaciones mencionadas anteriormente ...

Sin embargo, no hay MPMoviePlayerPlaybackWillFinishNotification por qué! Eso es realmente un problema.

Cuando se llama al reproductor de películas como modal (no importa cuál de los siguientes métodos utilizados presentViewController/presentModalViewController/presentVideoController), si ha definido .fullScreen = Sí, es que no se espera que llamar MPMoviePlayerWillExitFullscreenNotification notificación en absoluto (Obviamente, dado que no es conveniente, ingresamos/salimos de la pantalla completa, pero solo presentamos/descartamos el controlador).

Pero realmente no hay notificaciones de que el video está por terminar y cerrar. Es necesario (además de cualquier otra situación posible) captar el momento en que se inicia la transición de despido. (La transición, por supuesto, comienza antes de que se llame al MPMoviePlayerPlaybackDidFinishNotification). Y, al mismo tiempo, la aplicación: supportedInterfaceOrientationsForWindow: para el controlador que se muestra anteriormente se llama antes de la notificación, y no hay forma de decir el AppDelegate que nuestro controlador actual debe mostrarse ya en otra orientación.

Así que, como mi video es a pantalla completa y también sin controles mostrados (esto es una especie de introducción, así que solo hasta que termine) mi solución fue solo tener un temporizador que verifica cada marca corta (0.1 segundos) ¿cuál es la posición actual del video ... y está cerca del final, entonces este es el momento de mi propia notificación.

Cuestiones relacionadas