MPMoviePlayer closing fullscreen causes black view/block - ios

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");
}
}

Related

Issue while playing video in full screen mode using MPMoviePlayerViewController

I have a problem while playing a video in full screen mode using MPMoviePlayerViewController (works perfectly in normal mode).
CODE:
if (PlayV) {
self.previewView.hidden=NO;
self.videoController =[[MPMoviePlayerController alloc] initWithContentURL:self.videoURL];
[self.videoController.view setFrame:self.previewView .frame];
self.videoController.view.center=self.playBtn.center;
[self.previewView addSubview:self.videoController.view];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(videoPlayBackDidFinish:) name:MPMoviePlayerPlaybackDidFinishNotification object:self.videoController];
self.videoController.scalingMode = MPMovieScalingModeAspectFit;
self.videoController.controlStyle = MPMovieControlStyleNone;
[self.videoController play];
}
I got the solution. Add this line of code in playBtnAction method:
- (IBAction)playBtnAction:(id)sender {
[self.videoController setFullscreen:YES animated:YES];
}
and then add this line of code in your videoPlayBackDidFinish.
MPMoviePlayerController *player=[notification object];
if ([player respondsToSelector:#selector(setFullscreen:animated:)]) {
[player.view removeFromSuperview];
}
This code will check if the video is in fullscreen mode and bring it back to normal mode.
moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL fileURLWithPath:imagepath]]; //moviePlayer declared in .h and set URL
moviePlayer.view.frame = CGRectMake(364, 89, 660, 668); //set custom frame
moviePlayer.controlStyle = MPMovieControlStyleDefault;
moviePlayer.shouldAutoplay = YES;
[self.view addSubview:moviePlayer.view]; //add to view
[moviePlayer setFullscreen:NO animated:YES];
This may help you.

IOS movie player unknown load state after playing a video once MPMoviePlayerController

I am trying to figure out why I am getting a flash of black screen after I play a video through once. I figured out that when the load state is MPMovieLoadStatePlayable there is no black screen and the video plays through smoothly. However, after the video plays through once the load state becomes MPMovieLoadStateUnknown. I noticed that when the load state is unknown there is a flash of black screen, probably because it has to first call prepareToPlay.
Here is is how I am setting up my video:
- (void)setVideo:(PFObject *)aVideo {
video = aVideo;
if(self.moviePlayer) {
self.moviePlayer = nil;
}
// Get the profile image
PFUser *user = [self.video objectForKey:kFTPostUserKey];
PFFile *profilePictureSmall = [user objectForKey:kFTUserProfilePicSmallKey];
NSString *authorName = [user objectForKey:kFTUserDisplayNameKey];
// Get the video file
PFFile *videoFile = [video objectForKey:kFTPostVideoKey];
NSURL *url = [NSURL URLWithString:videoFile.url];
self.moviePlayer = [[MPMoviePlayerController alloc] init];
[self.moviePlayer.view setFrame:CGRectMake(0.0f,0.0f,320.0f,320.0f)];
[self.moviePlayer setControlStyle:MPMovieControlStyleNone];
[self.moviePlayer setScalingMode:MPMovieScalingModeAspectFill];
[self.moviePlayer setMovieSourceType:MPMovieSourceTypeFile];
[self.moviePlayer setContentURL:url];
[self.moviePlayer requestThumbnailImagesAtTimes:#[ #0.1f, #1.0f ] timeOption:MPMovieTimeOptionExact];
[self.moviePlayer setShouldAutoplay:NO];
[self.moviePlayer.view setBackgroundColor:[UIColor clearColor]];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(movieFinishedCallBack)
name:MPMoviePlayerPlaybackDidFinishNotification
object:self.moviePlayer];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayerStateChange:)
name:MPMoviePlayerPlaybackStateDidChangeNotification
object:self.moviePlayer];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(loadStateDidChange:)
name:MPMoviePlayerLoadStateDidChangeNotification
object:self.moviePlayer];
}
Here are the functions:
- (void)didTapVideoPlayButtonAction:(UIButton *)sender{
[self.playButton setHidden:YES];
[self.moviePlayer prepareToPlay];
[self.moviePlayer requestThumbnailImagesAtTimes:#[ #0.1f, #1.0f ] timeOption:MPMovieTimeOptionExact];
[self.moviePlayer play];
}
-(void)movieFinishedCallBack{
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:self.moviePlayer];
}
-(void)loadStateDidChange:(NSNotification *)notification{
//NSLog(#"loadStateDidChange: %#",notification);
if (self.moviePlayer.loadState == MPMovieLoadStatePlayable) {
NSLog(#"loadState... MPMovieLoadStatePlayable");
}
if (self.moviePlayer.loadState == MPMovieLoadStatePlaythroughOK) {
NSLog(#"loadState... MPMovieLoadStatePlaythroughOK");
}
if (self.moviePlayer.loadState == MPMovieLoadStateStalled) {
NSLog(#"loadState... MPMovieLoadStateStalled");
}
if (self.moviePlayer.loadState == MPMovieLoadStateUnknown) {
NSLog(#"loadState... MPMovieLoadStateUnknown");
//[self.moviePlayer prepareToPlay];
}
}
-(void)moviePlayerStateChange:(NSNotification *)notification{
//NSLog(#"moviePlayerStateChange: %#",notification);
if (self.moviePlayer.playbackState == MPMoviePlaybackStatePlaying){
[self.imageView addSubview:self.moviePlayer.view];
}
if (self.moviePlayer.playbackState == MPMoviePlaybackStateStopped){
NSLog(#"moviePlayer... Stopped");
[self.playButton setHidden:NO];
//[self.moviePlayer.view removeFromSuperview];
[self.moviePlayer prepareToPlay];
}
if (self.moviePlayer.playbackState == MPMoviePlaybackStatePaused){
NSLog(#"moviePlayer... Paused");
[self.moviePlayer stop];
}
f (self.moviePlayer.playbackState == MPMoviePlaybackStateInterrupted){
NSLog(#"moviePlayer... Interrupted");
[self.moviePlayer stop];
}
if (self.moviePlayer.playbackState == MPMoviePlaybackStateSeekingForward){
NSLog(#"moviePlayer... Forward");
}
if (self.moviePlayer.playbackState == MPMoviePlaybackStateSeekingBackward){
NSLog(#"moviePlayer... Backward");
}
}
I think that the solution would be, calling prepareToPlay from within the statement:
if (self.moviePlayer.loadState == MPMovieLoadStateUnknown)
I tried this but it did not prepare the player for play. Any thoughts/advice/help?
The fact that the video can play once but then can't play again later is not some built-in feature of MPMoviePlayerController — I've never had an MPMoviePlayerController of mine behave like that — so you should look for something else that might be happening so as to wreck the state of your MPMoviePlayerController, such as changing its contentURL to a bad value (which is usually the cause of MPLoadStateUnknown. Two things come to mind:
I notice that the method where you configure your MPMoviePlayerController is no ordinary method; it is, in fact, a setter for a property (video). This could be involved in the problem, because it means that every time any code anywhere says video = //... you are running this method, which means tearing down the entire movie player and making a new one. Now suppose some code somewhere else says video = nil or some other bad value. That would certainly make your movie player view go black and prevent further playing. I suggest breakpointing this method to see if that's happening. And then set up a better architecture: A setter should just set the property and no more. The configuration of your movie player should happen just once and needs to happen in a method of its own.
Watch out for a situation where you accidentally generate more than on MPMoviePlayerController. There is a law that "There Can Be Only One" - if another MPMoviePlayerController comes along and calls prepareToPlay, all other MPMoviePlayerControllers are disabled.
(Finally, although this is not the direct source of your problem, note that you are determining the load state incorrectly. You are using equality, but this can easily fail, because the load state is a bit mask; you have to use logical-and to compare masks.)

MPMoviePlayerController scaling mode issues after exit full screen

i am just playing a video by using MPMoviePlayerController...my code is
-(void)playMovie:(NSURL *)url
{
moviePlayer =
[[MPMoviePlayerController alloc]
initWithContentURL:url];
if (IDIOM==IPAD) {
[moviePlayer.view setFrame:CGRectMake(22,100, 720, 300)];
}
else
{
(IS_IPHONE_5)? [moviePlayer.view setFrame:CGRectMake(22, 70, 280, 150)]:[moviePlayer.view setFrame:CGRectMake(22, 40, 260, 140)];
}
[_scrollView addSubview:moviePlayer.view];
moviePlayer.scalingMode =MPMovieScalingModeFill;
[moviePlayer prepareToPlay];
[moviePlayer play];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(moviePlayerDidEnterFullscreen:) name:MPMoviePlayerDidEnterFullscreenNotification object:Nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(moviePlayerDidExitFullScreen:) name:MPMoviePlayerDidExitFullscreenNotification object:Nil];
}
-(void)moviePlayerDidEnterFullscreen :(id)sender
{
NSLog(#"fullscreen");
[moviePlayer play];
moviePlayer.scalingMode =MPMovieScalingModeFill;
}
- (void) moviePlayerDidExitFullScreen:(id)sender {
NSLog(#"exit full screen");
[moviePlayer play];
moviePlayer.scalingMode =MPMovieScalingModeFill;
}
here when i play initially video will be in "MPMovieScalingModeFill" mode...but my problem is that if i press full screen it shows video on full screen ..when i press exit "full screen" then my video mode goes to "MPMovieScalingModeAspectFit" mode.but i need to be always in "MPMovieScalingModeFill" mode .whats wrong with my code..Please help me...
I believe this will generate the MPMoviePlayerScalingModeDidChangeNotification.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(movieScalingModeDidChange:)
name:MPMoviePlayerScalingModeDidChangeNotification
object:nil];
Source :Apple Doc
MPMoviePlayerScalingModeDidChangeNotification
Posted when the scaling mode of a movie player has changed. There is no userInfo dictionary.
Scaling mode can change programmatically or by user interaction. To set or retrieve the scaling mode of a movie player, access its scalingMode property. The movie player whose state has changed is available as the object associated with the notification.
First set the ScalingMode to None and then set the ScalingMode to AspectFill
Swift Code :
NSNotificationCenter.defaultCenter().addObserver(self, selector: "moviePlayerExitFullscreen:", name: MPMoviePlayerDidExitFullscreenNotification, object: self.moviePlayer)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "moviePlayerEnterFullscreen:", name: MPMoviePlayerWillEnterFullscreenNotification, object: self.moviePlayer)
func moviePlayerEnterFullscreen (notification : NSNotification)
{
self.moviePlayer.scalingMode = MPMovieScalingMode.None
self.moviePlayer.scalingMode = MPMovieScalingMode.AspectFill
}
func moviePlayerExitFullscreen (notification : NSNotification)
{
self.moviePlayer.scalingMode = MPMovieScalingMode.None
self.moviePlayer.scalingMode = MPMovieScalingMode.AspectFill
}
This isn't the "ideal" solution, but it works! Basically, once you exit full screen the MPMoviePlayerController instance gets all screwed up and resetting the scaling property to MPMovieScalingModeFill won't help no matter where or when you do it (I've tried all sorts of stuff and after an hour gave up). Easiest solution is to remove the MPMoviePlayerController and simply allocate a new instance of MPMoviePlayerController each time full screen is exited (not ideal, but totally works):
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:NO];
if (self.moviePlayer != nil)
[self.moviePlayer.view removeFromSuperview];
self.moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:self.videoURL];
self.moviePlayer.view.frame = CGRectMake(#, #, #, #);
self.moviePlayer.movieSourceType = MPMovieSourceTypeFile;
self.moviePlayer.shouldAutoplay = NO;
[self.moviePlayer setContentURL:self.videoURL];
[self.moviePlayer prepareToPlay];
[self.moviePlayer setScalingMode:MPMovieScalingModeFill];
[self.view addSubview:self.moviePlayer.view];
}
PS: Don't forget to call super on viewDidAppear or suffer all sorts of unforeseeable mayhem (a very common mistake in iOS development)

Got the message "WARNING: under normal conditions, _fillInQueueWithExtraSpace:.." and MPMoviePlayer rotation not work in iPad IOS 5.1

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

Mpmovieplayercontroller in iPad - No Video only audio

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.

Resources