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.
Related
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;
}];
}
}
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
I'm playing a video from an MPMoviePlayer (not fullscreen), when I enter fullscreen the video keeps playing and fullscreen is shown.
But when I close fullscreen again, I can only see the black background on the place the 'small' video was playing. It doesnt respond to touches or anything.
I never call stop on my player and there is no viewdiddissapear (or similar) function declared.
The movieplayer also isnt released.
I want the video to continue playing when i close fullscreen. Any thoughts?
**EDIT
It works on an iPad 1, but not on an iPad 2... strange... I need it to function on all though.
Movieplayer initialization:
NSURL *fileURL = [NSURL fileURLWithPath:filePath];
self.moviePlayer = [[MPMoviePlayerController alloc] init];
self.moviePlayer.movieSourceType = MPMovieSourceTypeFile;
self.moviePlayer.controlStyle = MPMovieControlStyleEmbedded;
self.moviePlayer.contentURL = fileURL;
self.moviePlayer.backgroundView.backgroundColor = [UIColor blackColor];
self.moviePlayer.shouldAutoplay = YES;
[self.moviePlayer.view setFrame:CGRectMake(1024, floorf((self.view.bounds.size.height / 2) - (318 / 2)), 425, 318)];
[self.moviePlayer prepareToPlay];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(MPMoviePlayerLoadStateDidChange:)
name:MPMoviePlayerLoadStateDidChangeNotification
object:self.moviePlayer];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(MPMoviePlayerDidFinish:)
name:MPMoviePlayerPlaybackStateDidChangeNotification
object:self.moviePlayer];
[self.view addSubview:self.moviePlayer.view];
[self.view bringSubviewToFront:self.moviePlayer.view];
[UIView animateWithDuration:0.25
delay:0.0
options:UIViewAnimationCurveEaseOut
animations:^{
self.moviePlayer.view.transform = CGAffineTransformIdentity;
self.moviePlayer.view.position = CGPointMake(floorf(787 - (self.moviePlayer.view.frame.size.width / 2)),
self.moviePlayer.view.position.y);
}
completion:nil];
Notifications
- (void)MPMoviePlayerLoadStateDidChange:(NSNotification *)notification
{
NSLog(#"Loadstate changed");
if((self.moviePlayer.loadState & MPMovieLoadStatePlaythroughOK) == MPMovieLoadStatePlaythroughOK)
{
[self.moviePlayer play];
}
}
- (void)MPMoviePlayerDidFinish:(NSNotification *)notification
{
MPMovieFinishReason finishReason = (MPMovieFinishReason) [notification.userInfo objectForKey:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey];
switch(finishReason)
{
case MPMovieFinishReasonPlaybackError: NSLog(#"Stopped playback due to error");
case MPMovieFinishReasonPlaybackEnded: NSLog(#"I just quitted");
case MPMovieFinishReasonUserExited: NSLog(#"User quitted");
}
}
It's my first post, and may be it may seem incorrect.
So, I've to make rotation in cocos2d on iPad (5.1)
I use 2 different videos to each orientation.
And there I have 2 problems:
The app starts in portrait mode, and plays video normally. I call (play) the video 5-10 times, when video finishs I rotate simulator. The view rotates, BUT when I call (play) video - it shows white screen and the next message:
"WARNING: under normal conditions, _fillInQueueWithExtraSpace:ignoreExistingItems: should not be re-entered."
Then If I rotate screen again (several times) - and play it in landscape mode - it plays video well.
Also vice versa. When I start from landscape mode
The View rotating problem.
When I rotate view to the left/right landscape (from portrait) - can't rotate view backward. So I can rotate only in clockwise or counter clockwise. How to fix it?
-(id) init {
pathToVideoP = [[NSBundle mainBundle] pathForResource:#"video_portrait" ofType:#"mp4"];
pathToVideoL = [[NSBundle mainBundle] pathForResource:#"video_landscape" ofType:#"mp4"];
theMovieP = [[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL fileURLWithPath:pathToVideoP]];
theMovieL = [[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL fileURLWithPath:pathToVideoL]];
}
-(void) playVideoButtonClicked {
movieButton.visible = FALSE;
if (sharedManager.isPortrait){
theMovie = theMovieP;
} else {
theMovie = theMovieL;
}
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(movieFinishedCallback:) name:MPMoviePlayerPlaybackDidFinishNotification object:[theMovie moviePlayer]];
CGSize size = [[CCDirector sharedDirector] winSize];
[[[CCDirector sharedDirector] openGLView] addSubview:theMovie.view];
player = [self.theMovie moviePlayer];
player.controlStyle = MPMovieControlStyleNone;
[theMovie moviePlayer].view.backgroundColor = [UIColor whiteColor];
theMovie.view.frame = CGRectMake(0, 0, size.width, size.height);
if (sharedManager.isPortrait) {
CGAffineTransform transform = player.view.transform;
player.view.transform = transform;
}
else if (sharedManager.changeOrientation)
{
CGAffineTransform transform = player.view.transform;
transform = CGAffineTransformRotate(transform, (-M_PI/2 ));
player.view.transform = transform;
}
sharedManager.changeOrientation = NO;
player.backgroundView.backgroundColor = [UIColor whiteColor];
theMovie.view.backgroundColor = [UIColor whiteColor];
player.view.userInteractionEnabled = NO;
player.scalingMode = MPMovieScalingModeNone;
[player play];
}
-(void) moviePreloadDidFinish:(id)sender {
}
-(void) movieFinishedCallback:(NSNotification*) aNotification {
theMovie = [aNotification object];
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:theMovie];
[player stop];
[theMovie.view removeFromSuperview];
movieButton.visible = TRUE;
}
Add this line of code After creating Player Object.
player = [self.theMovie moviePlayer];
player.controlStyle = MPMovieControlStyleNone;
It's necessary in below version of iOS 6.0. May be it's helpful.
[player prepareToPlay];
I am developing an iPad app where I am playing the videos stored within the app itself. I am representing the list of videos in a table view. When I select a row, the video
corresponding to that row plays. But while performing this, sometimes screen goes black , no video is visible but only audio is playing.
I am aware that making the video play in fullscreen mode or using the MPMoviePlayerViewController eliminates this problem. But my requirement is that I don't want to play the movie in fullscreen initially. Please guide me on how this can be achieved.
-(void)playMovie {
MPMoviePlayerController *movieController = [[MPMoviePlayerController alloc] initWithContentURL:movieUrl];
self.moviePalyer = movieController;
[movieController release];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(moviePalyerDidFinish:) name:MPMoviePlayerPlaybackDidFinishNotification object: self.moviePalyer];
self.moviePalyer.view.frame = CGRectMake(240, 0, 561, 313);
self.moviePalyer.view.backgroundColor = [UIColor clearColor];
[self.moviePalyer prepareToPlay];
[self.view addSubview: self.moviePalyer.view];
[self.moviePalyer play];
}
-(void)moviePalyerDidFinish:(NSNotification*)notification
{
[moviePalyer.view removeFromSuperview];
[moviePalyer stop];
moviePalyer.initialPlaybackTime = -1.0;
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:moviePalyer];
[moviePalyer release];
moviePalyer = nil;
}
NOTE: This is on ipad simulator
I have solved the issue. Previously I was creating the MPMoviePlayerController for each of the row selection, and releasing it in the moviedidfinish notification method .But now, instead of creating movieplayercontroller for every row selection, I am reusing the MPMoviePlayerControler object which has been already created.
Following is the Code snippet:
-(void)playMovie
{
if(self.moviePalyer == nil)
{
MPMoviePlayerController *movieController = [[MPMoviePlayerController alloc] initWithContentURL:url];
self.moviePalyer = movieController;
[movieController release];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(moviePalyerDidFinish:) name:MPMoviePlayerPlaybackDidFinishNotification object:self.moviePalyer];
self.moviePalyer.repeatMode = MPMovieRepeatModeOne;
self.moviePalyer.view.frame = CGRectMake(240, 0, 561, 313);
self.moviePalyer.view.backgroundColor = [UIColor clearColor];
}
else
{
[self.moviePalyer setContentURL:url];
[self stopMovie];
}
[self.view addSubview: self.moviePalyer.view];
[self.moviePalyer play];
}
-(void)stopMovie
{
[self.moviePalyer.view removeFromSuperview];
[self.moviePalyer stop];
self.moviePalyer.initialPlaybackTime = -1.0;
}
I am releasing the moviePlayer object in the dealloc method.
Hope this helps who is having the same issue.