Setting MPMoviePlayerController orientation without MPMoviePlayerViewController - ios

It seems the best (only?) way to rotate an MPMoviePlayerController to landscape is to use an MPMoviePlayerViewController .
I'm currently modifying an open source game which, unfortunately, does not have a root UIViewController set. Is there any way to set the orientation only with MPMoviePlayerController, or do I have to suck it up and hack a root UIViewController into this application?
Edit: in response to Shivan Raptor, the game is Canabalt: https://github.com/ericjohnson/canabalt-ios. I'm instantiating an MPMoviePlayerController as follows:
self.moviePlayerController = [[MPMoviePlayerController alloc] initWithContentURL:self.videoTempFilePath];
self.moviePlayerController.repeatMode = MPMovieRepeatModeNone;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlaybackComplete:)
name:MPMoviePlayerDidExitFullscreenNotification
object:self.moviePlayerController];
[glView addSubview:self.moviePlayerController.view];
// MUST SET THIS HERE AFTER WE ADD AS SUBVIEW
self.moviePlayerController.fullscreen = YES;
[self.moviePlayerController play];
The movie plays in portrait and stays locked there, but I'd like to play it in landscape.

I created a root UIViewController and made the MPMoviePlayerViewController a child of it. This created the desired effect.

I think this might helpful.
- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
if (toInterfaceOrientation == UIInterfaceOrientationLandscapeRight) {
[self.view setTransform:CGAffineTransformMakeRotation(M_PI / 2)];
return true;
}
else if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft) {
[self.view setTransform:CGAffineTransformMakeRotation(M_PI * 2)];
return true;
}
else if (toInterfaceOrientation == UIInterfaceOrientationPortrait) {
[self.view setTransform:CGAffineTransformIdentity];
return true;
}
else return false;
}

Related

Playing video in Landscape and portrait

I have my app in portrait mode.
When video player enters full screen mode, I want to play that video in both landscape and portrait orientation.
moviePlayer = [[MPMoviePlayerController alloc]initWithContentURL:url];
[moviePlayer.view setAutoresizingMask:(UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth)];
[moviePlayer setScalingMode:MPMovieScalingModeFill];
moviePlayer.view.frame = CGRectMake(0, 0, self.videoPlayerView.frame.size.width, self.videoPlayerView.frame.size.height);
[self.videoPlayerView addSubview:moviePlayer.view];
and I am playing it on one button.
For you question i would like to give the below Reference
Portrait video to landscape
and
Allow video on landscape with only-portrait app
Enable your Landscape Device Orientation in Deployment Info. Then, add these methods in your ViewController:
- (BOOL) shouldAutorotate {
return NO;
}
- (NSUInteger) supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
- (UIInterfaceOrientation) preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationPortrait;
}
Try to add a canvas view as superview to your player and apply transformation to the canvas view.
- (void)initialize{
self.canvas = [[UIView alloc] initWithFrame: self.view.bounds];
[self.view addSubview:self.canvas];
// init moviePlayer
moviePlayer = [[MPMoviePlayerController alloc]initWithContentURL:url];
...
[self.canvas addSubview: moviePlayer.view];
// Add observers
...
[[NSNotificationCenter defaultCenter] addObserver: self
selector: #selector(deviceOrientationDidChange)
name: UIDeviceOrientationDidChangeNotification
object: nil];
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
}
- (void)deviceOrientationDidChange{
// Apply rotation only in full screen mode
if (self.isFullScreen) {
UIDeviceOrientation currentOrientation = [UIDevice currentDevice].orientation;
[UIView animateWithDuration: 0.3
animations: ^{
CGAffineTransform transform = CGAffineTransformMakeRotation(0);
switch (orientation) {
case UIDeviceOrientationLandscapeLeft:
transform = CGAffineTransformMakeRotation(M_PI_2);
break;
case UIDeviceOrientationLandscapeRight:
transform = CGAffineTransformMakeRotation(M_PI + M_PI_2);
break;
default:
break;
};
self.canvas.transform = transform;
self.canvas.frame = self.canvas.superview.bounds;
}];
}
}

How to show MPVideoPlayer in landscape mode and all other views in portrait?

Ive seen similar question asked already so apologies if there were a correct answer I missed.
My app has to be in portrait mode all the time except when it shows media player which has to be in landscape full screen mode.
Here is how its done:
AppDelegate.m
#implementation HCAAppDelegate
+(void) landscapeLock {
HCAAppDelegate* appDelegate = [UIApplication sharedApplication].delegate;
appDelegate.screenIsLandscapeOnly= true;
appDelegate.screenIsPortraitOnly = false;
}
+(void) portraitLock
{
HCAAppDelegate* appDelegate = [UIApplication sharedApplication].delegate;
appDelegate.screenIsPortraitOnly = true;
appDelegate.screenIsLandscapeOnly = false;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
...
[HCAAppDelegate portraitLock];
}
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
NSUInteger orientations = UIInterfaceOrientationMaskPortrait;
if (self.screenIsPortraitOnly) {
return UIInterfaceOrientationMaskPortrait;
} else if (self.screenIsLandscapeOnly) {
return UIInterfaceOrientationMaskLandscape;
} else {
if(self.window.rootViewController) {
UIViewController *presentedViewController = [[(UINavigationController *)self.window.rootViewController viewControllers] lastObject];
orientations = [presentedViewController supportedInterfaceOrientations];
}
return orientations;
}
}
Media player is created as
-(void) _initPlayer
{
[HCAAppDelegate landscapeLock];
_moviePlayer = [[HCAMoviePlayerController alloc]init];
[_moviePlayer setControlStyle:MPMovieControlStyleDefault];
_moviePlayer.shouldAutoplay = YES;
[self.view addSubview:_moviePlayer.view];
[_moviePlayer setFullscreen:YES animated:YES];
}
and dismissed as
- (void) _finishPlay
{
...
[_moviePlayer.view removeFromSuperview];
[HCAAppDelegate portraitLock];
}
When player is initialized it goes to landscape, but when its dismissed it still remains in the landscape mode , why the portraitLock method did not work ?
Thanks!
After looking more into this issue I understood where the bug is. Will post the answer here to close the case and provide a working example of subj.
Adding mediaPlayer view to the existing view controller
[self.view addSubview:_moviePlayer.view];
works but after removing it
[_moviePlayer.view removeFromSuperview];
the portraitLock does not affect self.view
The working way is to create a new controller and present / dismiss it:
here is the code:
Presenting the view for FullScreen playback. Note that height/width is switched in the
line _moviePlayer.view setFrame:
UIViewController *movieVC = (UIViewController*) [storyboard instantiateViewControllerWithIdentifier:#"MoviePlayer"];
movieVC.view = [[UIView alloc] initWithFrame:CGRectMake(0,
0,
[[UIScreen mainScreen] applicationFrame].size.width,
[[UIScreen mainScreen] applicationFrame].size.height)];
[HCAAppDelegate landscapeLock];
[_moviePlayer.view setFrame:CGRectMake(0,
0,
movieVC.view.frame.size.height,
movieVC.view.frame.size.width)];
[movieVC.view addSubview:_moviePlayer.view];
[self.navigationController presentViewController:movieVC animated:YES completion:nil];
Dismissing the view:
[_moviePlayer stop];
[HCAAppDelegate portraitLock];
[self.navigationController dismissViewControllerAnimated:YES completion:nil];

MPMoviePlayerViewController in landscape / all orientations

My questions is really simple, tutorials and answers didn't fix my problem.
I have an app with settings:
I want support only Portrait/Upside Down orientations in all my viewControllers except when I want to play video via:
MPMoviePlayerViewController
Here is code:
MPMoviePlayerViewController *mp = [[MPMoviePlayerViewController alloc] initWithContentURL:[Videos videoURL:video.hash]];
if (mp) {
isVideoPlaying = YES;
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(videoFinishedPlaying:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:mp.moviePlayer];
[self presentMoviePlayerViewControllerAnimated:mp];
mp.moviePlayer.movieSourceType = MPMovieSourceTypeFile;
[mp.moviePlayer play];
[mp release];
}
When MPMoviePlayerViewController plays video I want support all orientations.
Need your help.
You should permit rotation by the following:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
}
IOS 6:
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAll;
}
put the code in the .m file where you call the player
Hi all I had same problem I resolved it -
You need to first change in appdelegate:
-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
if ([[[NowPlaying sharedManager] playerViewController] allowRotation])//Place your condition here
{
return UIInterfaceOrientationMaskAll;
}
return UIInterfaceOrientationMaskPortrait;
}
Register Notifications for the full screen control:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(moviePlayerWillEnterFullscreenNotification:)
name:MPMoviePlayerWillEnterFullscreenNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(moviePlayerWillExitFullscreenNotification:)
name:MPMoviePlayerWillExitFullscreenNotification
object:nil];
Then add line of code in the player controller:
- (void)moviePlayerWillEnterFullscreenNotification:(NSNotification *)notification
{
dispatch_async(dispatch_get_main_queue(), ^
{
self.allowRotation = YES;
});
}
- (void)moviePlayerWillExitFullscreenNotification:(NSNotification *)notification
{
self.allowRotation = NO;
[self.moviePlayerController setControlStyle:MPMovieControlStyleNone];
dispatch_async(dispatch_get_main_queue(), ^
{
//Managing GUI in pause condition
if (self.currentContent.contentType == TypeVideo && self.moviePlayerController.playbackState == MPMoviePlaybackStatePaused)
{
[self.moviePlayerController pause];
if (self.playButton.selected)
self.playButton.selected = NO;
}
self.view.transform = CGAffineTransformMakeRotation(0);
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];
self.view.bounds = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
});
}
This code is tested in iOS6 and iOS7 working fine. Thanks

MPMoviePlayer Controller view should autorotate to landscape right by default

I have two view controllers.One view has button, when user click on the button he will redirect to another view where MPMoviePlayer Controller is present.I want to show MPMoviePlayer controller view to LandsapeRight mode by Default.
I write the below code in buttonAction
-(void)buttonAction
{
tLive = [[toneTvlive alloc]init];
[self.navigationController pushViewController:tLive animated:YES];
}
and in the 2nd view i write the below code
- (void)viewDidLoad
{
[super viewDidLoad];
printf("\n hii");
self.navigationController.navigationBar.hidden = YES;
[[UIApplication sharedApplication]setStatusBarHidden:NO];
NSURL *mediaURL = [NSURL URLWithString:#""];
mp = [[MPMoviePlayerController alloc] initWithContentURL:mediaURL];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayBackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:nil];
//[mp setControlStyle:MPMovieControlStyleFullscreen];
[mp setMovieSourceType:MPMovieSourceTypeStreaming];
[mp setFullscreen:YES animated:YES];
[mp.view setFrame: CGRectMake(0,0, 480,320)];
[self.view addSubview:mp.view];
[mp prepareToPlay];
[mp play];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations.
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
while run the program first it shows the view in portrait mode only.It doesn't prompt the view to rotate in landscape,but after when i rotate the device once it works fine.Can anyone please help me to solve this.
If you're using iOS 6+ you can autorotate the view controller to landscape:
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscape;
}
- (BOOL)shouldAutorotate {
return YES;
}
If you're targeting earlier iOS versions, here's a good SO answer about the same thing.

MPMoviePlayerController fullscreen quirk in iPad

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.
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?
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];
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.
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.
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];
}
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.
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];
}
[[UIApplication sharedApplication] setStatusBarOrientation:UIDeviceOrientationPortrait animated:NO];
This code might help you.

Resources