iPad 中的 MPMoviePlayerController 全屏怪癖

Posted

技术标签:

【中文标题】iPad 中的 MPMoviePlayerController 全屏怪癖【英文标题】:MPMoviePlayerController fullscreen quirk in iPad 【发布时间】:2011-02-20 15:00:55 【问题描述】:

我想在视图控制器中显示 MPMoviePlayerController 并让用户使用默认控件切换全屏,例如 YouTube 应用。我在一个简单的示例中使用以下代码:

- (void)viewDidLoad 
    [super viewDidLoad];
    self.player = [[MPMoviePlayerController alloc] init];
    self.player.contentURL = theURL;
    self.player.view.frame = self.viewForMovie.bounds;
    self.player.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    [self.viewForMovie addSubview:player.view];
    [self.player play];

在用户将视频设为全屏、旋转设备并点击屏幕之前,此方法效果很好。状态栏显示位置错误,如下图所示。

我正在使用适用于 iPad 的模板选项卡栏应用程序。我只添加了上面的 viewDidLoad、视图变量和 XIB 中的 UIView 来显示电影播放器​​。

我做错了什么?

【问题讨论】:

我遇到了同样的问题。仍然没有解决方法? 我也是。有人搞定了吗? 你得到答案了吗? 【参考方案1】:

是的,我也遇到了这个问题。这肯定是 MPMoviePlayerController 本身的一个错误。

我在我的应用程序中确定的解决方法是在我退出全屏模式时自己更正状态栏:

- (void)playerDidExitFullscreen:(NSNotification *)notification 
    MPMoviePlayerController *moviePlayer = (MPMoviePlayerController *) notification.object;

    if (moviePlayer == self.player) 
        UIApplication *app = [UIApplication sharedApplication];
        if (app.statusBarOrientation != self.interfaceOrientation) 
            [app setStatusBarOrientation:self.interfaceOrientation animated:NO];
        
    

这在全屏模式下并不能解决问题,但之后会解决问题。

注意当然需要在通知中添加该功能:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerDidExitFullscreen:) name:MPMoviePlayerDidExitFullscreenNotification object:nil];

【讨论】:

【参考方案2】:

shouldAutorotateToInterfaceOrientation:interfaceOrientation 是否对所有支持的方向都返回 YES?

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 返回是;

如果您提供更多代码会有所帮助。

【讨论】:

是的。我添加到项目中的唯一代码是上面的 viewDidLoad,当然还有 XIB 中的 viewForMovie。它是 iPad 的默认标签栏应用程序。【参考方案3】:

您是否正在为您的 UI 使用界面构建器?如果是这样,请确保在视图属性检查器中将视图的方向设置为“横向”。

【讨论】:

它现在在另一个方向上失败了。【参考方案4】:

遇到了同样的问题,花了半天时间解决了。在 iPad 处于纵向时,每当我使用示例代码(或我在网上找到的任何代码)开始播放视频时,视频和控制栏都会被格式化为纵向,因此会在屏幕上的所有位置显示。

无论如何,以下内容对我有用。

  /* Call the code like below:
        int iLandscape;
        if( newOrientation==UIInterfaceOrientationLandscapeLeft || newOrientation==UIInterfaceOrientationLandscapeRight )
             iLandscape=1;

        [self PlayVideo:iLandscape fullscreen:1]
    */
        //////////////////////////////////////////////////////////////////////////
        - (void)PlayVideo:(int)iLandscape fullscreen:(int)iFullScreen 
        
            NSString *url = [[NSBundle mainBundle] pathForResource:@"myvideofile" ofType:@"m4v"];

        if( iFullScreen==0 )
        
            MPMoviePlayerController *player2 = 
                [[MPMoviePlayerController alloc] 
                    initWithContentURL:[NSURL fileURLWithPath:url]];

            [[NSNotificationCenter defaultCenter] 
                addObserver:self
                   selector:@selector(movieFinishedCallback:)
                       name:MPMoviePlayerPlaybackDidFinishNotification
                     object:player2];

            //---play partial screen---
            player2.view.frame = CGRectMake(0, 0, m_iScreenWidth, m_iScreenHeight);
            [self addSubview:player2.view];
            //---play movie---
            [player2 play];
           
        else
        
            MPMoviePlayerViewController *playerViewController = [[MPMoviePlayerViewController alloc] 
                initWithContentURL:[NSURL fileURLWithPath:url]];

            [[NSNotificationCenter defaultCenter] 
                addObserver:self
                   selector:@selector(movieFinishedCallback:)
                       name:MPMoviePlayerPlaybackDidFinishNotification
                     object:[playerViewController moviePlayer]];

            if( iLandscape )
            
                playerViewController.view.frame = CGRectMake(0, 0, m_iScreenWidth, m_iScreenHeight);
            
            [self addSubview:playerViewController.view];
            //play movie
            MPMoviePlayerController *player = [playerViewController moviePlayer];
            player.scalingMode=MPMovieScalingModeAspectFit;
            [player play];
        
    


    //////////////////////////////////////////////////////////////////////////
    - (void) movieFinishedCallback:(NSNotification*) aNotification 
    
        MPMoviePlayerController *player = [aNotification object];
        [[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:player];    
        [player autorelease];    
        [player.view removeFromSuperview];
    

【讨论】:

【参考方案5】:

你解决了这个问题吗?

[[UIApplication sharedApplication] setStatusBarOrientation:UIDeviceOrientationPortrait animated:NO];

此代码可能会对您有所帮助。

【讨论】:

【参考方案6】:

找到了。

遇到了同样的问题 - 这就是我所做的。我建议将代码一一添加到您的项目中,以确切了解它是如何工作的。

首先——我放的是纵向模式。

[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];

然后我把电影推到状态栏上。注意 - 这假设视频具有 4x3 纵横比

theVideo = [[MPMoviePlayerController alloc] initWithContentURL: [NSURL fileURLWithPath : path]];
float aspectRatio = (3.0f/4.0f);
float theMovieHeight = [self view].bounds.size.width * aspectRatio;
[[theVideo view] setFrame:(CGRectMake(0, [self view].bounds.size.height - theMovieHeight, [self view].bounds.size.width, theMovieHeight ))]; 

然后,在应用程序启动的地方(在我的项目中,它在didFinishLaunchingWithOptions 函数中)——无论如何,您只需要访问窗口对象即可。

float aspectRatio = (3.0f/4.0f);
float theMovieHeight = self.window.bounds.size.width * aspectRatio;
float theSpaceAboveTheMovie = self.window.bounds.size.height - theMovieHeight;
float whereTheMovieShouldBeCentered = (self.window.bounds.size.height - theMovieHeight) / 2;

CGAffineTransform theTransform = CGAffineTransformMakeTranslation(0,0);

theTransform = CGAffineTransformScale(theTransform, 1.0f/aspectRatio, 1.0f/aspectRatio);
theTransform = CGAffineTransformTranslate(theTransform, -whereTheMovieShouldBeCentered, 0);
theTransform = CGAffineTransformRotate(theTransform, M_PI / 2);
theTransform = CGAffineTransformTranslate(theTransform, 0, -theSpaceAboveTheMovie);

[self.window setTransform:theTransform];

请记住,仿射变换是以相反的顺序完成的。因此,如果您想查看每个转换在做什么(我建议您应该这样做),请将前三个注释掉

在这里您应该会看到位于页面中心的电影和状态栏

//  theTransform = CGAffineTransformScale(theTransform, 1.0f/aspectRatio, 1.0f/aspectRatio);
//  theTransform = CGAffineTransformTranslate(theTransform, -whereTheMovieShouldBeCentered, 0);
//  theTransform = CGAffineTransformRotate(theTransform, M_PI / 2);
    theTransform = CGAffineTransformTranslate(theTransform, 0, -theSpaceAboveTheMovie);

然后是前两个

在这里您应该会看到电影和状态栏已旋转且不再居中

//  theTransform = CGAffineTransformScale(theTransform, 1.0f/aspectRatio, 1.0f/aspectRatio);
//  theTransform = CGAffineTransformTranslate(theTransform, -whereTheMovieShouldBeCentered, 0);
    theTransform = CGAffineTransformRotate(theTransform, M_PI / 2);
    theTransform = CGAffineTransformTranslate(theTransform, 0, -theSpaceAboveTheMovie);

在这里你应该看到它旋转并居中

//  theTransform = CGAffineTransformScale(theTransform, 1.0f/aspectRatio, 1.0f/aspectRatio);
    theTransform = CGAffineTransformTranslate(theTransform, -whereTheMovieShouldBeCentered, 0);
    theTransform = CGAffineTransformRotate(theTransform, M_PI / 2);
    theTransform = CGAffineTransformTranslate(theTransform, 0, -theSpaceAboveTheMovie);

所有这些都可以旋转并全屏

您可以下载我的示例代码here。

【讨论】:

【参考方案7】:

试试这个

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

    [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO];
  

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

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

    [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];




- (void)exitedFullscreen:(NSNotification*)notification 
    NSLog(@"exitedFullscreen");

    [[NSNotificationCenter defaultCenter] removeObserver:self];

【讨论】:

以上是关于iPad 中的 MPMoviePlayerController 全屏怪癖的主要内容,如果未能解决你的问题,请参考以下文章

iPad 和 iPhone 中的 UITextField 键盘类型

如何停止 iPad 中的方向更改?

iOS:如何开始开发 iPad 应用程序,例如一个 iPad 中的应用程序成为管理员,而同一应用程序的其他 iPad 成为侦听器

ipad ios 5.1 中的界面方向问题

ipad中的自动布局

xcode中的iPhone项目到iPad项目?