2010-07-13 4 views
22

J'ai beaucoup de mal à afficher un film en plein écran dans mon application iPad, puis permettant à l'utilisateur de le fermer avec le bouton Terminé ou le "non-plein écran" bouton sur les commandes du lecteur.Affichage correct et rejet plein écran MPMoviePlayerController dans iOS 3.2 (iPad)

Initialement, j'utilisais MPMoviePlayerViewController pour la présentation du film, mais je ne recevais pas les notifications plein écran d'entrée/sortie de son objet MPMoviePlayerController, donc j'ai changé pour le faire moi-même.

Je peux faire en sorte que le film apparaisse en plein écran (bien que la transition soit joviale), mais lorsque les boutons «Terminé» ou «non-plein écran» sont pressés, aucune action n'est effectuée par le lecteur. J'ai posté mon code ci-dessous:

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

} 

Et voici le code pour mon rappel didFinish

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

Alors, évidemment, je suis en train de faire quelque chose de mal, mais je suis haut et en bas de la documentation et je ne peut pas comprendre comment faire pour que le film s'en aille. Je pensais que ce serait plus intuitif que ça. Qu'est-ce que je fais mal?

Répondre

66

Voici comment les événements -> Notifications de travail:

  • presses utilisateur 'Done' bouton

    • MPMoviePlayerWillExitFullscreenNotification
    • MPMoviePlayerDidExitFullscreenNotification
  • presses utilisateur 'Laisser fullscreen' bouton sur le transport

    • MPMoviePlayerWillExitFullscreenNotification
    • MPMoviePlayerDidExitFullscreenNotification
    • Notez que la lecture ne s'arrête pas
  • film arrive en fin

    • MPMoviePlayerPlaybackDidFinishNotification avec le MPMoviePlayerPlaybackDidFinishReasonUserInfoKey ensemble à MPMovieFinishReasonPlaybackEnded
    • Si vous appelez setFullscreen:NO animated:YES sur votre instance MoviePlayerController de cette notification, vous obtenez alors les WillExit et DidExit notifications.
    • Notez que vous n'obtenez pas la notification PlaybackDidFinish lorsque l'utilisateur appuie sur les boutons Terminé ou Quitter plein écran.

Donc, en général, si vous voulez vous débarrasser de l'avis du MoviePlayer, vous avez besoin de mettre [self.moviePlayerController.view removeFromSuperview] dans le gestionnaire de notification DidExitFullscreen. WillExitFullscreen est trop tôt.

Voici mon code:

- (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

Ceci est utile et je suis en mesure de quitter fullscreen maintenant lorsque l'utilisateur appuie sur fait, mais le -playbackFinished: callback n'est jamais exécuté pour moi et je ne peux pas pour la vie de moi comprendre pourquoi pas. Connaissez-vous des raisons pour lesquelles cela pourrait arriver? – jbrennan

+0

Même quand le film joue à la fin? C'est étrange, je n'ai jamais rencontré ça. –

+3

si MPMoviePlayerDidExitFullscreenNotification est appelée à la fois en touchant "Terminé" et en quittant le mode plein écran, comment savez-vous ce qui est appelé? Peut-être que l'utilisateur quitte uniquement l'écran plein dans ce cas, vous ne voulez pas supprimer la vue, je suppose. –

0

Oui. C'est génial. Il y a vraiment des notifications mentionnées ci-dessus ...

Cependant, il n'y a pas MPMoviePlayerPlaybackWillFinishNotification !!! Pour certaines raisons C'est vraiment un problème.

Lorsque vous appelez le lecteur vidéo en modal (peu importe lequel des méthodes suivantes utilisées presentViewController/presentModalViewController/presentVideoController), si vous avez défini .fullScreen = OUI, il ne devrait appeler MPMoviePlayerWillExitFullscreenNotification notification du tout (de toute évidence, parce qu'il ne nous cosidering entrer/sortir du plein écran, mais seulement présent/écartons le contrôleur).

Mais il n'y a vraiment pas de notifications que la vidéo est sur le point de terminer et fermer. Cela est nécessaire (en dehors de toute autre situation possible) pour saisir le moment où la transition du licenciement est commencée. (La transition, bien sûr, commence avant la MPMoviePlayerPlaybackDidFinishNotification appelé). Et, en même temps, application: supportedInterfaceOrientationsForWindow: pour le contrôleur précédemment affiché est appelé avant la notification, et il n'y a aucun moyen de dire l'AppDelegate que notre contrôleur actuel doit être montré déjà dans une autre orientation. Donc, puisque ma vidéo est en plein écran et aussi sans aucun contrôle montré (c'est une sorte d'intro, donc juste jusqu'à ce qu'il se termine) ma solution était juste d'avoir une minuterie qui vérifie chaque tick court (0.1 secondes) quelle est la position actuelle vidéo ... et il est proche de la fin, alors le moment est venu pour ma propre notification.

Questions connexes