iOS:电影播放器​​视图不会旋转

时间:2012-03-05 19:25:11

标签: ios5 uiview mpmovieplayercontroller transformation

我想明确地旋转我的电影播放器​​视图(不使用Autorotation委托)。我为此编写了以下代码,并在其中添加了注释。电影播放器​​的父视图确实旋转但不是电影播放器​​视图本身。有人可以在这帮助我,我做错了吗?感谢。

#import "CustomMoviePlayer.h"
#define degreesToRadian(x) (M_PI * (x) / 180.0)
#define radianToDegrees(x) ((x) * 180.0/M_PI)

@implementation CustomMoviePlayer

@synthesize moviePlayer, myParentViewController;

-(void)playMovie:(NSString*)filePath onViewController:(UIViewController*)controller
{

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(rotateMoviePlayer) name: UIDeviceOrientationDidChangeNotification object:nil];
    [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];   

    myParentViewController = controller;

    NSURL *url = [NSURL fileURLWithPath:filePath];

    moviePlayer =  [[MPMoviePlayerController alloc] initWithContentURL:url];
    moviePlayer.controlStyle = MPMovieControlStyleDefault;
    moviePlayer.shouldAutoplay = YES;

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlaybackComplete:) name:MPMoviePlayerPlaybackDidFinishNotification object:moviePlayer];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlaybackStateChanged:) name:MPMoviePlayerPlaybackStateDidChangeNotification object:moviePlayer];

    [controller.view addSubview:moviePlayer.view];
    [moviePlayer setFullscreen:YES animated:YES];
}

- (void)moviePlaybackStateChanged:(NSNotification *)notification
{
    NSLog(@"State changed... %d", [moviePlayer playbackState]);
}

- (void)moviePlaybackComplete:(NSNotification *)notification
{
    NSLog(@"Finished video...");

    [[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:moviePlayer];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackStateDidChangeNotification object:moviePlayer];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];

    [myParentViewController.view setTransform:CGAffineTransformIdentity];
    [moviePlayer.view removeFromSuperview];
    [moviePlayer release];
}

-(void)rotateMoviePlayer
{
    NSLog(@"Rotate movie player");

    UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];

    if (orientation != UIDeviceOrientationUnknown) {

        CGAffineTransform transform = CGAffineTransformMakeRotation(degreesToRadian(0));

        switch (orientation) {
            case UIDeviceOrientationLandscapeLeft:
                transform = CGAffineTransformMakeRotation(M_PI / 2); 
                break;
            case UIDeviceOrientationLandscapeRight:
                transform = CGAffineTransformMakeRotation(-M_PI / 2);
                break;
            case UIDeviceOrientationPortraitUpsideDown:
                transform = CGAffineTransformMakeRotation(M_PI);
                break;  
            default:
                break;
        }
        // This view does rotate and I can see it rotating when there is no moviePlayer on top of it!
        [myParentViewController.view setTransform:CGAffineTransformIdentity];
        [myParentViewController.view setTransform:transform];

        // It doesn't mater whether I put following two lines or not...Movie player view doesn't rotate!
        [moviePlayer.view setTransform:CGAffineTransformIdentity];
        [moviePlayer.view setTransform:transform];
    }    
}

- (void)dealloc {
    [moviePlayer release];
    [super dealloc];
}

@end

3 个答案:

答案 0 :(得分:3)

您在全屏模式下使用MPMoviePlayerController,因此应用于其视图(和/或其超视图)的旋转/无效。

使用全屏模式时,MPMoviePlayerController实际上是通过将其渲染层直接添加到UIWindow来使用不同的方法 - 也就是说,它实际上不会使用其view属性。

要在全屏播放电影时获取当前UIWindow,您可以使用以下代码段;

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

进入该窗口后,直接对其应用旋转。

然而,这将导致许多难以克服的问题(相信我,去过那里,得到了T恤的集合)。作为替代方式,我强烈建议您使用假全屏模式。

而不是像你一样初始化播放器

[moviePlayer setFullscreen:YES animated:YES];

为什么不简单地将其视图的帧大小初始化为整个屏幕 - 或者像这样的超级视图的边界

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

然后,要获取全屏界面,请使用以下控件样式:

moviePlayer.controlStyle = MPMovieControlStyleFullscreen;

这样,你得到的播放将遵循在superview上完成的任何转换,你将没有副作用。

答案 1 :(得分:1)

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

答案 2 :(得分:0)

这耗费了我一段时间,我得到了很多不同的恐怖错误,但最终我通过 MPMoviePlayerController 结束了 NOT ,但 MPMoviePlayerViewController 。在呈现之前,我只是旋转了 self.playerView 这是一个属性。我还添加了 NSNotification ,它将在视频播放完毕后返回主控制和主ViewController。以下是我如何执行它:

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

回调 movieFinishedCallback :如下所示,

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

        });
    }
}

这对我有用。希望它有所帮助。