iOS: Movie player view doesn't rotate

房东的猫 提交于 2019-11-28 11:42:50

You are using MPMoviePlayerController in fullscreen mode, hence the rotation/s applied to its view (and/or its superview) are not being effective.

When using fullscreen mode, MPMoviePlayerController is actually using a different approach by adding its rendering layer directly to a UIWindow - that is, it does effectively not use its view property.

For getting the current UIWindow when a movie is playing in fullscreen, you may use the following snippet;

UIWindow *window = [UIApplication sharedApplication].keyWindow;
if (!window)
{
    window = [[UIApplication sharedApplication].windows objectAtIndex:0];
}

Once you got that window, apply your rotation/s directly to it.

This however will result in many possible issues that are hard to overcome (trust me, been there, got a collection of Tshirts). As an alternative way, I would strongly suggest you to use a fake-fullscreen mode.

Instead of initializing the player like you did

[moviePlayer setFullscreen:YES animated:YES];

Why not simply initializing its view's frame size to the entire screen - or the bounds of its superview like this

moviePlayer.view.frame = myParentViewController.view.bounds;

Then, for getting the fullscreen interface, use the following control style:

moviePlayer.controlStyle = MPMovieControlStyleFullscreen;

That way, your resulting playback will adhere to any transformation done on the superview and you will be free of side effects.

[UIView beginAnimations:nil context:nil];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
[UIView setAnimationRepeatCount:1];
player.view.transform = CGAffineTransformRotate(player.view.transform, M_PI_2);
[UIView commitAnimations];
[player.view setContentMode:UIViewContentModeScaleAspectFit];

This consumed me for a while and I got so many different horrifying errors, but eventually I ended up NOT doing it through MPMoviePlayerController but MPMoviePlayerViewController. I just rotated the self.playerView which is a property, before presenting it. Also I added the NSNotification that will lead back to the main control and the main ViewController after the video finishes. Here's how I went about executing it:

        [[NSNotificationCenter defaultCenter] removeObserver:self.playerView
                                                        name:MPMoviePlayerPlaybackDidFinishNotification
                                                      object:self.playerView.moviePlayer];

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

        self.playerView = [[MPMoviePlayerViewController alloc] initWithContentURL:docUrl];
        self.playerView.view.frame = CGRectMake(10, 10, self.frame.size.width-20, 180);
        [self.playerView.moviePlayer prepareToPlay];

        if(IS_IPHONE_6P)
        {
            [self.playerView.view setBounds:CGRectMake(0, 0, 736, 414)];
            [self.playerView.view setCenter:CGPointMake(212, 368)];
        }
        else if(IS_IPHONE_6)
        {
            [self.playerView.view setBounds:CGRectMake(0, 0, 375, 667)];
            [self.playerView.view setCenter:CGPointMake(187, 333)];
        }
        else if (IS_IPHONE_5)
        {
            [self.playerView.view setBounds:CGRectMake(0, 0, 736, 414)];
            [self.playerView.view setCenter:CGPointMake(160, 284)];
        }
        else
        {
            [self.playerView.view setBounds:CGRectMake(0, 0, 480, 320)];
            [self.playerView.view setCenter:CGPointMake(160, 240)];
        }

        [self.playerView.view setTransform:CGAffineTransformMakeRotation(M_PI / 2)];
        self.playerView.modalPresentationStyle = UIModalPresentationFormSheet;
        self.playerView.modalTransitionStyle = UIModalTransitionStyleCoverVertical;

        [self presentViewController:self.playerView animated:YES completion:nil];

And the callback movieFinishedCallback: is as follows,

    - (void)movieFinishedCallback:(NSNotification*)aNotification
{
    // Obtain the reason why the movie playback finished
    NSNumber *finishReason = [[aNotification userInfo] objectForKey:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey];

    // Dismiss the view controller ONLY when the reason is not "playback ended"
    if ([finishReason intValue] != MPMovieFinishReasonPlaybackEnded)
    {
        MPMoviePlayerController *moviePlayer = [aNotification object];
        [[NSNotificationCenter defaultCenter] removeObserver:self
                                                        name:MPMoviePlayerPlaybackDidFinishNotification
                                                      object:moviePlayer];

        NSLog(@"Video Closed");
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^
        {
            [self dismissViewControllerAnimated:NO completion:nil];
            self.playerView = nil;

        });
    }
}

This worked for me. Hope it helps.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!