2010-07-13 16 views
22

Ho molti problemi a visualizzare un filmato a schermo intero nella mia app per iPad e quindi a consentire all'utente di chiuderlo con il pulsante Fine o "non-schermo intero" pulsante sui controlli del lettore.Visualizzazione corretta e rimozione di MPMoviePlayerController a schermo intero in iOS 3.2 (iPad)

Inizialmente stavo usando MPMoviePlayerViewController per la presentazione del film, ma non ricevevo le notifiche di invio/uscita a schermo intero dal suo oggetto MPMoviePlayerController, quindi sono passato a farlo da solo.

Posso rendere il filmato a schermo intero (anche se la transizione è janky), ma quando vengono premuti i pulsanti "Fatto" o "non-schermo intero", nessuna azione viene intrapresa dal giocatore. Ho inviato il mio codice qui sotto:

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

} 

Ed ecco il codice per il mio didFinish richiamata

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

Così, ovviamente, sto facendo qualcosa di sbagliato, ma io sono stato su e giù per la documentazione e io non riesco a capire come fare il film basta andare via. Ho pensato che sarebbe stato più intuitivo di questo. Che cosa sto facendo di sbagliato?

risposta

66

Ecco come gli eventi -> Notifiche funzionano: presse

  • utente 'Done' pulsante

    • MPMoviePlayerWillExitFullscreenNotification
    • MPMoviePlayerDidExitFullscreenNotification
  • utente preme 'Lascia fullscreen' pulsante sul trasporto

    • MPMoviePlayerWillExitFullscreenNotification
    • MPMoviePlayerDidExitFullscreenNotification
    • Nota che la riproduzione non si ferma
  • film raggiunge fine

    • MPMoviePlayerPlaybackDidFinishNotification con il MPMoviePlayerPlaybackDidFinishReasonUserInfoKey set per MPMovieFinishReasonPlaybackEnded
    • Se si chiama setFullscreen:NO animated:YES sull'istanza MoviePlayerController da questa notifica, avrete quindi ottenere le notifiche WillExit e DidExit.
    • Si noti che non si riceve la notifica PlaybackDidFinish quando l'utente preme il pulsante Fine o Abbandona schermo intero.

Così, in genere, se si vuole sbarazzarsi di vista del MoviePlayer, è necessario mettere [self.moviePlayerController.view removeFromSuperview] nel gestore DidExitFullscreen notifica. WillExitFullscreen è troppo presto.

Ecco il mio codice:

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

Questo è utile e sono in grado di uscire a schermo intero ora quando l'utente preme fatto, tuttavia il -playbackFinished: la callback non viene mai eseguita per me e non posso per la vita di me capire perché no. Conosci qualche motivo per cui ciò potrebbe accadere? – jbrennan

+0

Anche quando il film viene riprodotto fino alla fine? È strano, non l'ho mai visto. –

+3

se MPMoviePlayerDidExitFullscreenNotification viene chiamato sia quando si tocca "Fatto", sia quando si esce a schermo intero, come si fa a sapere che viene chiamato? Forse l'utente esce solo a schermo intero, nel qual caso non si desidera rimuovere la vista, credo. –

0

Sì. È fantastico. Ci sono davvero delle notifiche sopra menzionate ...

Tuttavia, non ci sono MPMoviePlayerPlaybackWillFinishNotification in qualche modo !!! Questo è davvero un problema.

Quando si chiama il giocatore di film come modale (non importa quale dei seguenti metodi utilizzati presentViewController/presentModalViewController/presentVideoController), se si è definito .fullScreen = YES, non è previsto per chiamare MPMoviePlayerWillExitFullscreenNotification notifica affatto (ovviamente, dato che non è cosiderante, entriamo/usciamo dallo schermo intero, ma presentiamo/licenziamo il controller).

Ma non ci sono davvero notifiche che il video sta per finire e chiudersi. Ciò è necessario (oltre a qualsiasi altra situazione possibile) per cogliere il momento in cui inizia la transizione del licenziamento. (La transizione, ovviamente, inizia prima della chiamata a MPMoviePlayerPlaybackDidFinishNotification). E, allo stesso tempo, application: supportedInterfaceOrientationsForWindow: per il controller mostrato in precedenza viene chiamato prima della notifica, e non c'è modo di dire che AppDelegate deve mostrare il nostro attuale controller già in un altro orientamento.

Quindi, dal momento che il mio video è a schermo intero e anche senza alcun controllo mostrato (questo è una specie di intro, quindi ho appena finito) la mia soluzione era solo per avere un timer che controlla ogni breve tick (0,1 secondi) qual è la posizione attuale del video ... ed è vicina alla fine, quindi è il momento della mia notifica.

Problemi correlati