Issue summary
Changing the orientation of an iPad device or simulator while playing a video using MPMoviePlayerViewController results in an inconsistent rotation state upon dismissal of the video player. This is a known bug in iPad SDK 3.2, documented at http://www.openradar.me/8012810
Sample project
I have prepared a minimal sample project using the View-based Application template from Xcode 3.2.2, using the following code to launch the player
NSURL *movieUrl = [NSURL URLWithString:#"http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8"];
MPMoviePlayerViewController *player = [[MPMoviePlayerViewController alloc] initWithContentURL:movieUrl];
[self presentMoviePlayerViewControllerAnimated:player];
[player release];
The code is available on GitHub at http://github.com/adamalex/FullScreenMovie or direct download using http://github.com/adamalex/FullScreenMovie/zipball/master
Steps to reproduce
Obtain the project using the information above
Launch the project with the iPad simulator or device
Tap the button to begin playing the video
Rotate the iPad by 90 degrees
Dismiss the video
Note the UIStatusBar is out of sync with the application UI
Objective
I have contacted Apple and they have confirmed this is a bug that is being investigated. I would like to discuss temporary workarounds that use public APIs safe for submission to the App Store. I am going to open a developer support case with Apple as well and will report back with my own progress.
Successful response from Apple Developer Technical Support!
This is a known bug and a we're received a number of duplicate bug reports and so iOS engineering is aware of the issue and we do have a temporary workaround as suggested by iOS engineering.
You will need to implement this in the view controller which presents the movie player.
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
[super didRotateFromInterfaceOrientation:fromInterfaceOrientation];
[self performSelector:#selector(fixStatusBar) withObject:nil afterDelay:0];
}
- (void)fixStatusBar {
[[UIApplication sharedApplication] setStatusBarOrientation:[self interfaceOrientation] animated:NO];
}
While this is somewhat ugly, it should fix the issue for now. It would be recommended to remove this code once the bug is fixed in the system.
This took care of the issue completely for me, and you can revisit http://github.com/adamalex/FullScreenMovie for the code with the fix applied.
This also solves an iPhone/iPodTouch rotation issue that I was struggling with. I am developing a universal app in which each view displays a different image depending on whether the device is in portrait or landscape orientation. Buttons are used to navigate between views.
If the app is running on the device and a portrait view is rotated to landscape, my image switching takes place. If the device is then placed flat on a table top and the button is tapped to display the next view, the view appears in landscape but shows the portrait image instead. I solved the problem by forcing a portrait view to appear by detecting for face up and down, but Apple's code solved this problem (as well as the similar movie problem I was also experiencing).
Many thanks for reporting the bug - I assumed it was just my bad coding...
Related
I used MPMoviePlayerViewController to play a video and when back to app, I need app force return portrait
I think the best way to solve this is by using
https://stackoverflow.com/a/13800907/620197
These are callbacks who only gets called when the user autorotates - you can tell the user to rotate the device and then the autorotate callback will be called and will show only the supported orientation.
If you still want force rotation i believe you need to dismiss the controller - try this and please do tell me if it worked out for you:
IOS 6 force device orientation to landscape
I have searched the web for a long time for a force rotation solution that will please me with no success, it almost looks like apple
Doesnt want us to be able to so this.
I am calling a youtube channel on a UIWebView. When user selects a video, device launches its video player as normal. However, when video ends or user finishes it returning to view, an offset is applied to whole app!! All views have an offset on top but this only happens on iPad and iPad simulator with compatibility mode, on iPhone and iPhone simulator not! How to solve it? Thank you.
Problem is that status bar dissapears after video execution.
[[UIApplication sharedApplication] setStatusBarHidden:NO]; problem is beeing solved when an event is fired using NSNotificationCenter
Has anything changed in 5.1 which would affect how a MPMoviePlayerViewController works regarding device orientation?
I started getting reports from users today that videos were playing only in portrait mode. I figured out that they were using 5.1 and I quickly upgraded a device to recreate the situation. My code has not changed and works perfectly in 4.x, 5.0, and 5.01.
All the views in my app display in portrait mode except when a user clicks on a video, the movie player is suppose to take over the whole screen and launch into landscape more. The app using the 5.0 SDK but targeting 4.0. Here is the code I am using to display a video:
VideoPlayer *vp = [[VideoPlayer alloc] initWithContentURL:movieURL];
vp.moviePlayer.movieSourceType = src;
vp.moviePlayer.controlStyle = MPMovieControlStyleFullscreen;
vp.moviePlayer.shouldAutoplay = TRUE;
[self presentMoviePlayerViewControllerAnimated:vp];
VideoPlayer is a subclass of MPMoviePlayerViewController where the shouldAutorotateToInterfaceOrientation is overridden like so:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIDeviceOrientationLandscapeLeft);
}
This pattern is recommended all over the internet and even by Apple. I don't understand why its not working under iOS 5.1 or why more people aren't complaining about this.
Any help will be greatly appreciated.
I had the same problem also - i was playing the movie on a opengl subview, (im making an interactive ebook in landscape mode so needed my movie - (in a uiview) to play in landscape also)
I corrected this by:
subclassing the open glview to a *viewcontroller then linking that *viewcontroller to the window
So while working with cocos2d i can now use all uikit in the correct orientation.
Sending all uikit views to my subclasses opengl view. (while making sure to add in my app delegate and checking that orientation is stated in plist too.)
"#if GAME_AUTOROTATION == kGameAutorotationUIViewController
[director setDeviceOrientation:kCCDeviceOrientationPortrait];
"#else
[director setDeviceOrientation:kCCDeviceOrientationLandscapeRight];
"#endif
hope this helps someone :) im very new at cocos2d so it took a while to figure out what i was doing wrong.
I had the same issue in iOS 5. The only way I was able to get it to work was to subclass MPMoviePlayerViewController.
#implementation MovieViewController
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
return UIInterfaceOrientationIsLandscape(interfaceOrientation);
} else {
return UIInterfaceOrientationIsPortrait(interfaceOrientation);
}
}
#end
It looks you have already tried to do this, but this block of code is working for me on the device with iOS 5.1. Not sure about the simulator.
I had a bunch of orientation issues after upgrading to iOS 5.1. For me, it was because the allowed orientations of sibling viewcontrollers up the chain resulted in no allowable orientation for a modal controller I was adding.
Do you have any cases in your view hierarchy where two subviews are added to a view? I was adding two subviews to my window in applicationDidFinishLaunching, and before iOS 5.1, they could have independent allowable orientations. ie, I could have one fixed in portrait orientation while the one on top rotated. Now, the other subview insists on portrait orientation.
My solution was to force the non-rotating view below:
[self.window insertSubview:self.nonRotatingViewController.view belowSubview:self.rotatingViewController.view];
This post helped me figure that out (and has some code):
iOS: Disable Autorotation for a Subview
This is a follow-on from: Overlay on top of Streaming MPMoviePlayerController
I've seen the various threads about checking for a new Window and then using that to apply my custom views to my fullscreen video however in SDK 4.1 this doesnt appear to be the case.
I have tried a timer and listening for UIWindowDidBecomeKeyNotification but in neither case does [[UIApplication sharedApplication] windows] ever contain more than 1 item.
I have tried adding my view to the players view property which works fine when displayed in place, but not when fullscreen, even if I add it in moviePlayBackDidEnterFullScreen event
I found a solution to this problem a few weeks ago:
It seems this method does not work on the iPad (I havent checked iPhone SDK 4>) so in order to get round it you can do the following.
After adding your video and setting to fullscreen you can add your controls directly to the UIWindow (e.g. [[[[UIApplication sharedApplication] windows] objectAtIndex:0] addSubView:myView]), they will then appear on top of your video video.
The only problem I have found with this is that they don't obey the orientation rules of the view and I have manually had to program the rotation code in the willRotateToInterfaceOrientation method of the view.
I have an app which uses a manager to offer up the relevant custom view for a selected item when selected.
The selection is done through one of 3 parent custom views
TableView
PageControl
Gallery (essentially another TableView)
One of the custom views displays a view with an embedded MPMovieControl on it.
This works fine however for some reason in the Gallery view if I have set the controlStyle of the video set to MPControlStyleNone the app crashes, well it locks up the simulator and Xcodes debugger doesnt even notice, just assumes its still running.
This line is the culprit
player.controlStyle = MPMovieControlStyleNone;
Without it, it works fine, but then I obviously have the unrequired controls displayed
iOS 2.0 through iOS 3.1 uses movieControlMode. Everything newer uses controlStyle. Test for newer and fall back to older.
if ([movie respondsToSelector:#selector(setControlStyle:)]) {
movie.controlStyle = MPMovieControlStyleNone;
} else {
movie.movieControlMode = MPMovieControlModeHidden;
}
May be this will work.
[player setControlStyle:MPMovieControlStyleNone];
Run the program using the profiler and check for NSZombies. Most likely the app is crashing due to a wrong release count or an autorelease and the symptom is your movie crashing when it might be something related to you starting the movie and needing it later to find it was released.