I want to rotate my movie player view explicitly (not using Autorotation delegate). I wrote following code for that and also put comments in it. The parent view of movie player does rotate but not movie player view itself. Could someone please assist me here what I am doing wrong? Thanks.
#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
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.