12

Hallo,MPMoviewPlayerController rotación de reproducción de pantalla completa con UIViewController subyacente con el modo de retrato solamente (rotación anulado)

I tiene una aplicación sencilla, que contiene UITabBarController con dos UIViewControllers. Ambos UIViewControllers son solo retratos (no se permite la rotación). UIView de UIViewController contiene la vista de MPMoviePlayerController para permitir la reproducción de video dentro de esta vista con posibilidad de hacer pantalla completa a través de los controles (MPMovieControlStyleEmbedded). El código es simple y se ve como ...

__moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL URLWithString:@"MOVIE_URL"]]; 
__moviePlayer.controlStyle = MPMovieControlStyleEmbedded; 
__moviePlayer.view.frame = CGRectMake(10, 10, 300, 200); 
__moviePlayer.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 
__moviePlayer.shouldAutoplay = NO; 
[__moviePlayer prepareToPlay]; 
[self.view addSubview:__moviePlayer.view]; 

... Esto funciona perfectamente usuario cambia a menos que la reproducción a pantalla completa en el que necesito para permitir la rotación para permitir la reproducción del paisaje también. La rotación no funciona, porque UITabBarController no lo permite (y ambos UIViewControllers también).

Por lo tanto, probé dos enfoques, pero ninguno de ellos funciona como se esperaba.

1) una subclase UITabBarController

lo hice añadir una propiedad BOOL __allowRotation y si se establece en Sí, lo sé SÍ La vuelta en el método de shouldAutorotateToInterfaceOrientation UITabBarController.

Estoy escuchando MPMoviePlayerDidEnterFullscreenNotification y MPMoviePlayerWillExitFullscreen notificaciones de notificación para establecer esta propiedad en YES y NO.

Funciona, pero el problema es que cuando el usuario finaliza la reproducción de video en el paisaje, la vista subyacente no se gira a la posición vertical. La única forma de volver a rotar a retrato es usar API privada, que es no.

2) Ver/transformación capa

También probamos para escuchar notificaciones MPMoviePlayerDidEnterFullscreenNotification y MPMoviePlayerWillExitFullscreenNotification.

Cuando recibo MPMoviePlayerDidEnterFullscreenNotification, comienzo las notificaciones de orientación de UIDevice para obtener la orientación del dispositivo. Estoy tratando de transformar la capa de vista de MPMoviePlayerController en función de la orientación actual del dispositivo, pero es un poco inmune, porque no hace nada. Puedo asignar lo que sea para transformar la propiedad, pero no hace nada.

No hace nada no es del todo correcto. Cuando aplico la transformación durante la rotación, puedo ver el efecto de esta transformación cuando paso de la pantalla completa a la reproducción de video incrustado.

3) UIWindow independiente

no he probado esto todavía, pero he encontrado un lugar que crea MPMoviePlayerController UIWindow separado para la reproducción a pantalla completa, que debe ser accesible a través de [[UIApplication sharedApplication] ventanas]. Esto explica por qué la transformación no se aplica durante la reproducción a pantalla completa.

Pero yo no les gusta bastante esta solución, ya que el UIWindow no puede ser identificado y que no quieren usar constantes mágicas como objectAtIndex: 1 o aplicar la transformación a todos los UIWindows excepto la principal, etc.

lado

el hecho de que la implementación subyacente se puede modificar y dejará de funcionar.

Pregunta

Por lo tanto, la pregunta es, cómo permitir la reproducción a pantalla completa MPMoviePlayerController única rotación cuando subyace UIView (es decir. De UIView UIViewController) prohíbe la rotación y permite que sólo el retrato?

Respuesta

6

Usted puede tratar de presentar la nueva UIViewController (con shouldAutorotate SI) de forma modal y añadir __moviePlayer.view en este controlador cuando se envía MPMoviePlayerWillEnterFullscreenNotification. Haz lo contrario cuando moviePlayer sale de pantalla completa.

+0

Tienes razón. Estuve protagonizando el código durante tanto tiempo y esto no se me ocurrió. ¡Gracias! Funciona como se espera ahora. P.S. Pero todavía creo que debería funcionar automáticamente, porque la presentación en pantalla completa está controlada por MPMoviePlayerController. Va a completar el error del radar ... – robertvojta

+2

Se completó como una mejora para MPMoviePlayerController Error ID # 9009914 para permitir el control de autorrotación para la reproducción a pantalla completa. – robertvojta

+1

¿Podría compartir algún código? @Chiefly – situee

8

Tengo una situación muy similar. Mi aplicación es solo para retratos Pero necesito mostrar videos de pantalla completa en cualquier orientación, y luego volver a la orientación vertical, después de que el usuario salga del modo de pantalla completa.

El método de Split no funciona para mí, porque me gustaría dejar que el usuario vea el video en pantalla completa e incrustado, y cambiar de modo, sin perder la posición de reproducción, y sin pausas.

me encontré con esta solución:

En primer lugar, tengo una subclase UINavigationController raíz, que recibe todos los mensajes con respecto a la rotación.

Prohíbo la rotación en este controlador con:

- (BOOL) shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)toInterfaceOrientation { 
    return (UIInterfaceOrientationPortrait == toInterfaceOrientation); 
} 

estoy anulando el

- (id) initWithRootViewController:(UIViewController *)rootViewController; method. 

Adición del soporte para modificaciones orientación del dispositivo:

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; 

[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(receivedRotate:) name: UIDeviceOrientationDidChangeNotification object: nil]; 

Ahora tengo una manejador recibido Rotar: - que atrapa todas las rotaciones del dispositivo a pesar de no girar automáticamente a cualquier orientación taciones, excepto retrato:

- (void) receivedRotate:(NSNotification*) notify { 
    if(isVideoFullscreen) { 
     UIDeviceOrientation toInterfaceOrientation = [[UIDevice currentDevice] orientation]; 
     [UIView beginAnimations:nil context:NULL]; 
     [UIView setAnimationDuration:0.4]; 
     [UIView setAnimationCurve:2]; 

     if(toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft){ 
      self.view.transform = CGAffineTransformMakeRotation(-M_PI_2); 
      [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeLeft]; 
      self.view.bounds = CGRectMake(0, 0, 1024, 768); 
     } else if(toInterfaceOrientation == UIInterfaceOrientationLandscapeRight) { 
      self.view.transform = CGAffineTransformMakeRotation(M_PI_2); 
      [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight]; 
      self.view.bounds = CGRectMake(0, 0, 1024, 768);    
     } else if(toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) { 
      self.view.transform = CGAffineTransformMakeRotation(M_PI); 
      [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortraitUpsideDown]; 
      self.view.bounds = CGRectMake(0, 0, 768, 1024); 
     } else if(toInterfaceOrientation == UIInterfaceOrientationPortrait) { 
      self.view.transform = CGAffineTransformMakeRotation(0); 
      [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait]; 
      self.view.bounds = CGRectMake(0, 0, 768, 1024); 
     } 

     [UIView commitAnimations]; 
    } 

} 

Solo compruebo las rotaciones del dispositivo y giro mi vista en consecuencia.

Entonces, ¿cómo sabe el controlador raíz, cuando el video es a pantalla completa? Sólo tiene que añadir otros dos controladores de mensajes a la init:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willEnterFullscreen:) name:MPMoviePlayerWillEnterFullscreenNotification object:nil]; 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willExitFullscreen:) name:MPMoviePlayerWillExitFullscreenNotification object:nil]; 

Y los mismos manipuladores:

- (void) willEnterFullscreen: (NSNotification *) notify { 
    isVideoFullscreen = YES; 
} 

- (void) willExitFullscreen: (NSNotification *) notify { 
    self.view.transform = CGAffineTransformMakeRotation(0); 
    [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait]; 
    self.view.bounds = CGRectMake(0, 0, 768, 1024);  
    isVideoFullscreen = NO; 
} 

Al salir de pantalla completa - restauramos la orientación vertical. Entonces, esto funciona para mí, espero que ayude a alguien.

0

El MPMoviePlayerViewController tiene su propia función para presentar vídeos de forma modal:

NSURL *videoURL = [NSURL fileURLWithPath:video.path]; 
moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:videoURL]; 

//Calls for movie playback once video is finished 
[[NSNotificationCenter defaultCenter] addObserver:self 
             selector:@selector(moviePlayBackDidFinish:) 
              name:MPMoviePlayerPlaybackDidFinishNotification 
              object:moviePlayer]; 
playerView = [[MPMoviePlayerViewController alloc]init]; 
[moviePlayer setControlStyle:MPMovieControlStyleFullscreen]; 
[playerView setView:moviePlayer.view]; 

[moviePlayer.view setFrame: self.view.bounds]; 
[self presentMoviePlayerViewControllerAnimated:playerView]; 

[moviePlayer play]; 
NSLog(@"playing video view"); 
1

Registro de MPMoviePlayerWillExitFullscreenNotification y MPMoviePlayerWillEnterFullscreenNotification en delegado de la aplicación y manejar la orientación utilizando una variable de instancia.

 

-(void)moviePlayerFullScreen:(NSNotification *)notification 
{ 
    if ([notification.name isEqualToString:@"MPMoviePlayerWillEnterFullscreenNotification"]) { 

     self.supportedOrientation=UIInterfaceOrientationMaskAll; 

    } 
    else if ([notification.name isEqualToString:@"MPMoviePlayerWillExitFullscreenNotification"]) 
    { 
     self.supportedOrientation=UIInterfaceOrientationMaskPortrait; 

    } 
} 
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window { 
    return self.supportedOrientation; 
} 

+0

¿Cómo puedo registrar tanto MPMoviePlayerWillExitFullscreenNotification? ¿Es este código posible para iOS7? – karthikeyan

0

Hola a todos me había mismo problema que la resolvió -

Aquí está mi código completo ....

Necesitas primer cambio en AppDelegate:

-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window 
{ 
if ([[[NowPlaying sharedManager] playerViewController] allowRotation])//Place your condition here 
{ 
    return UIInterfaceOrientationMaskAll; 
} 
return UIInterfaceOrientationMaskPortrait; 
} 

Registro Notificaciones para el control de pantalla completo:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayerWillEnterFullscreenNotification:) 
              name:MPMoviePlayerWillEnterFullscreenNotification 
              object:nil]; 

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayerWillExitFullscreenNotification:) 
              name:MPMoviePlayerWillExitFullscreenNotification 
              object:nil]; 

A continuación, agregue la línea de código en el controlador de jugador:

- (void)moviePlayerWillEnterFullscreenNotification:(NSNotification *)notification 
{ 
dispatch_async(dispatch_get_main_queue(),^
       { 
        self.allowRotation = YES; 
       }); 
} 



- (void)moviePlayerWillExitFullscreenNotification:(NSNotification *)notification 
{ 
self.allowRotation = NO; 
[self.moviePlayerController setControlStyle:MPMovieControlStyleNone]; 

dispatch_async(dispatch_get_main_queue(),^
       { 

        //Managing GUI in pause condition 
         if (self.currentContent.contentType == TypeVideo && self.moviePlayerController.playbackState == MPMoviePlaybackStatePaused) 
        { 
         [self.moviePlayerController pause]; 
         if (self.playButton.selected) 
          self.playButton.selected = NO; 
        } 
        self.view.transform = CGAffineTransformMakeRotation(0); 
        [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait]; 
        self.view.bounds = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height); 
       }); 
} 

Este código se prueba en iOS6 y iOS7 funcionando bien. Gracias

Por favor, hágamelo saber si hay alguna pregunta .....

+0

¿Qué condición necesito comprobar aquí si ([[[NowPlaying sharedManager] playerViewController] allowRotation])? No puedo entender esto? ¿Me pueden dar un proyecto de demostración con respecto a esto? – karthikeyan

Cuestiones relacionadas