iphone - force MPMoviePlayerController to play video in landscape mode

后端 未结 5 1164
攒了一身酷
攒了一身酷 2020-12-17 05:28

I have an app that is portrait mode only, but when the user plays a video I want it to play in fullscreen landscape mode (the video player doesn\'t look good in portrait mod

相关标签:
5条回答
  • 2020-12-17 06:05

    My app is quite simple, with a UINavigationController as the root view controller which displays a main navigation screen, and a few detail screens. The main screen does not support rotation due to layout constraints, and for consistency the detail screens (which are simply pushed onto the navcontroller's stack) don't either. However, some of the detail screens contain links to videos, and the videos need to display in portrait mode. The app displays the player modally using MPMoviePlayerController.

    I just had a similar issue, and tried the solution above which applies an affine transform to the MPMoviePlayerController's view, but the problem was that the status bar continued to display as in portrait mode, and overlapped the modal movie player view (on the left, if viewed in according to the rotation above). I tried a couple of things to no avail:

    • Hiding the status bar. This didn't work, because the player exists in its own world, and goes ahead and presents the status bar anyway. I couldn't find a way to make this go away.

    • Explicitly setting the status bar orientation. I'm not sure exactly why this didn't work, but I suspect that it was because I'd indicated in my info.plist that only portrait was supported and was therefore cut off from making changes.

    Net-net, the above didn't work for me. Just as well, b/c Apple admonishes devs to treat the MPMoviePlayerController as opaque, and (especially with the transform method) I was violating this.

    In the end, I found a simpler solution that worked for me:

    1. In the info.plist, I indicated that all orientations (except for upside down, so the standard iPhone idiom) were supported.

    2. Subclass UINavigationController, and override the appropriate shouldAutorotate methods so that only Portrait is supported (see this solution, among others, for how to do this in iOS <6 and iOS6 concurrently).

    This worked because:

    1. While I'd indicated that autorotation is supported by the app, I cut it off at the UINavigationController subclass which contains all of the views I'm rendering... so everything remains portrait, except for:

    2. The MPMoviePlayerController is being presented modally, atop the NavigationController, and lives in its own world. Therefore it's free to pay attention to what's in the info.plist, and rotate all by itself.

    There are a bunch of examples for how to present the player modally, but for quick reference, here's my code:

    - (void)presentModalMediaPlayerForURL:(NSURL *)inURL
    {
        NSLog(@"Will play URL [%@]", [inURL description]);
        MPMoviePlayerViewController *player = [[MPMoviePlayerViewController alloc] initWithContentURL:inURL];
        [player.view setBounds:self.view.bounds];
    
        [player.moviePlayer prepareToPlay];
        [player.moviePlayer setFullscreen:YES animated:YES];
        [player.moviePlayer setShouldAutoplay:YES];
        [player.moviePlayer setMovieSourceType:MPMovieSourceTypeFile];
        [self presentModalViewController:player animated:YES];
    
        [player release];
    }
    
    0 讨论(0)
  • 2020-12-17 06:15

    I had the same situation, but I am using iOS 6 and a NavController based project. What makes that interesting is the ViewController that is hosting the MPMoviePlayerController I don't want rotated, but I wanted the video within it to be rotated.

    ViewController with rotated MPMoviePlayerController
    I just manually rotate the MPMoviePlayerController as needed based on the devices orientation. _videoView is a MPMoviePlayerController property of the ViewController. For the example, I just hard coded the desired width and height to a 16x9 aspect ratio as I intend this video to be uploaded to youtube.

    - (void)updateVideoRotationForCurrentRotationWithAnimation:(bool)animation
    {
        CGSize containerSize  = _videoView.frame.size;   // Container NOT rotated!
        float  videoWidth     = 384;                     // Keep 16x9 aspect ratio
        float  videoHeight    = 216;
    
        if( animation )
        {
            [UIView beginAnimations:@"swing" context:nil];
            [UIView setAnimationDuration:0.25];
        }
    
        switch( self.interfaceOrientation )
        {
            case UIInterfaceOrientationPortrait:
            case UIInterfaceOrientationPortraitUpsideDown:
                m_videoPlayer.view.transform = CGAffineTransformMakeRotation(radians(90));
    
                // This video player is rotated so flip width and height, but the container view
                // isn't rotated!
                [m_videoPlayer.view setFrame:CGRectMake((containerSize.width-videoHeight)/2,
                                                        (containerSize.height-videoWidth)/2,
                                                        videoHeight,
                                                        videoWidth)];
                break;
    
            case UIInterfaceOrientationLandscapeLeft:
            case UIInterfaceOrientationLandscapeRight:
                m_videoPlayer.view.transform = CGAffineTransformMakeRotation(radians(0));
    
                // This video player isn't rotated
                [m_videoPlayer.view setFrame:CGRectMake((containerSize.width-videoWidth)/2,
                                                        (containerSize.height-videoHeight)/2,
                                                        videoWidth,
                                                        videoHeight)];
                break;
        }
    
        if( animation )
            [UIView commitAnimations];
    
    }
    
    
    - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
    {
        [self updateVideoRotationForCurrentRotationWithAnimation:YES];
    }
    

    I also call updateVideoRotationForCurrentRotationWithAnimation after view did appear so it has the correct initial orientation.

    0 讨论(0)
  • 2020-12-17 06:16

    Read this article:

    http://iosdevelopertips.com/video/getting-mpmovieplayercontroller-to-cooperate-with-ios4-3-2-ipad-and-earlier-versions-of-iphone-sdk.html

    The main idea is:

    [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO];
    
    [[self view] setBounds:CGRectMake(0, 0, 480, 320)];
    [[self view] setCenter:CGPointMake(160, 240)];
    [[self view] setTransform:CGAffineTransformMakeRotation(M_PI / 2)];
    
    0 讨论(0)
  • 2020-12-17 06:17

    I use the following code to work with ONLY LANDSCAPE mode for Movieplayer.

    NSURL *movieURL = [NSURL URLWithString:@"http://techslides.com/demos/sample-videos/small.mp4"];  // sample url
    MPMoviePlayerViewController *movieController = [[MPMoviePlayerViewController alloc] initWithContentURL:movieURL];
    
    // Logic for play movie in landscape
    CGAffineTransform landscapeTransform;
    landscapeTransform = CGAffineTransformMakeRotation(90*M_PI/180.0f);
    landscapeTransform = CGAffineTransformTranslate(landscapeTransform, 80, 80);
    [movieController.moviePlayer.view setTransform: landscapeTransform];
    
    [self presentMoviePlayerViewControllerAnimated:movieController];
    [movieController.moviePlayer prepareToPlay];
    [movieController.moviePlayer play];
    
    0 讨论(0)
  • 2020-12-17 06:20

    For full screen playback use MPMoviePlayerViewController and then to make it launch and play in landscape format use the "shouldAutorotateToInterfaceOrientation" method on the MPMoviePlayerViewController class.

    It looks like this:

    [yourInstanceOfMPMoviePlayerViewController shouldAutorotateToInterfaceOrientation: UIInterfaceOrientationLandscapeRight];
    
    0 讨论(0)
提交回复
热议问题