iPad 中的 MPMoviePlayerController 全屏怪癖

发布于 2024-09-01 17:18:41 字数 728 浏览 9 评论 0原文

我想在视图控制器中显示 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];
}

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

screenshot

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

我做错了什么?

I want to show a MPMoviePlayerController in a view controller and let the user toggle full screen with the default controls, like the YouTube app. I'm using the following code in a bare-bones example:

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

This works well until the user makes the video full screen, rotates the device and taps on the screen. The status bar is shown in the wrong position, as shown in the screenshot below.

screenshot

I'm working with the template Tab Bar Application for iPad. I've only added the viewDidLoad above, the view variables and an UIView in the XIB to show the movie player.

What am I doing wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

扶醉桌前 2024-09-08 17:18:42

是的,我也遇到这个问题。这绝对是 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];

Yeah, I'm experiencing this problem as well. It definitely appears to be a bug in the MPMoviePlayerController itself.

The workaround I've settled on in my application is to just correct the status bar myself when I exit fullscreen mode:

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

This doesn't fix the problem while in fullscreen mode, but it does fix it afterwards.

Note of course that the function needs to be added to the notification:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerDidExitFullscreen:) name:MPMoviePlayerDidExitFullscreenNotification object:nil];
中二柚 2024-09-08 17:18:42

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

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    return YES;
}

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

Is shouldAutorotateToInterfaceOrientation:interfaceOrientation returning YES for all of the supported orientations?

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    return YES;
}

If you provided more of your code it would help.

踏月而来 2024-09-08 17:18:42

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

are you using interface builder for your UI? if so make sure you set the view's orientation to 'landscape' in the view attributes inspector.

浅笑依然 2024-09-08 17:18:42

遇到同样的问题,搞了半天才解决。当 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];
    }

Had the same problem, just spent half a day sorting it out. With the iPad in portrait orientation, whenever I started a video using the sample code (or any I could find on the net) the video and control bar were formatted for portrait, and hence all over the place on the screen.

Anyway, the following works for me.

  /* 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];
    }
我早已燃尽 2024-09-08 17:18:42

找到了。

有同样的问题 - 这就是我所做的。我建议将代码一一添加到您的项目中,以准确了解其工作原理。

首先 - 我把东西设置为纵向模式。

[[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);

并且与它们一起,它被旋转并全屏

您可以下载我的示例代码 这里

Found it.

Had the same problem - here is what I did. I would suggest adding the code to your project one by one to see exactly how it works.

First - I put things is portrait mode.

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

Then I shoved the movie down onto the status bar. Note - this assumes that the video has a 4x3 aspect ratio

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

Then, in the place where the application starts up (in my project, it is in the didFinishLaunchingWithOptions function) - anyway, you just need access to the window object.

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

Remember that affine transforms are done in reverse order. So if you want to see what each transform is doing (I suggest you should), comment out the first three

Here you should see the movie and status bar centered on the page

//  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);

Then the first two

Here you should see the movie and status bar rotated and no longer centered

//  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 you should see it rotated and centered

//  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);

And with them all, it is rotated and fullscreen

You can download my sample code here.

回忆躺在深渊里 2024-09-08 17:18:42

试试这个

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

Try this

 - (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];
}
人生戏 2024-09-08 17:18:42
[[UIApplication sharedApplication] setStatusBarOrientation:UIDeviceOrientationPortrait animated:NO];

这段代码可能对你有帮助。

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

This code might help you.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文