Application stops when I hit the "Done" button - ios

So, when I hit the "Done" button, whenever I am in the Movie Player, my app goes back to the previous menu, while a loading sign is in the middle of the screen. Then my app stops completely, without any error messages.
Here's my code:
_streamPlayer = [[MPMoviePlayerController alloc] initWithContentURL:url];
if(self.streamPlayer != nil){
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayBackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:_streamPlayer];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(doneButtonClick:)
name:MPMoviePlayerDidExitFullscreenNotification
object:_streamPlayer];
EDIT: I implemented the 2 functions like this:
-(void) moviePlayBackDidFinish:(NSNotification*)notification {
NSNumber *reason = [[notification userInfo] objectForKey:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey];
switch ([reason intValue]) {
case MPMovieFinishReasonPlaybackEnded:
NSLog(#"Playback ended");
break;
case MPMovieFinishReasonPlaybackError:
[self alertWithMessage:NSLocalizedString(#"The video can't open!", #"The video can't open!")];
break;
case MPMovieFinishReasonUserExited:
NSLog(#"User Exited");
break;
default:
break;
}
}
-(IBAction) doneButtonClicked:(id)sender
{
[self.streamPlayer.view removeFromSuperview];
self.streamPlayer = nil;
}
I'm not sure about the second one! Still the same problem!
Any ideas?

Your code to add a notification center observer references a method named doneButtonClick:. However, the method you implemented is named doneButtonClicked: (note the 'ed' at the end!). As such, you'll get a crash when the notification comes in because the method you specified doesn't exit. You need to either:
Change the addObserver call to reference the actual method: #selector(doneButtonClicked:) or
Rename your method to match the addObserver call: - (IBAction)doneButtonClick:(id)sender
Incidentally, I'd rename the method and #selector reference to doneButtonTapped - users tap on a touch device, they don't 'click'.

I solved it!
I commented the second method (doneButtonClick:) and it's implementation and then, when the video player should stop playing, i added this:
[_streamPlayer stop];
[_streamPlayer.view removeFromSuperview];
[self dismissLoadingView];
[SVProgressHUD dismiss];

Related

Recover from buffering stopping MPMoviePlayer

I am not sure what code to add, so let me know what you need to see. I am using MPMoviePlayer in conjunction with Widevine. I am having an issue where the movie stops playing. I check the MoviePlaybackStates and rarely, if ever does it catch. Most of the time it just stops. I want to believe it has something to do with buffering. I am streaming the video, and widevine callbacks gives me no errors. Any ideas how I can track this down or what the issue is?
You should follow loadState instead of playbackState.
The way to do it is to observe MPMoviePlayerLoadStateDidChangeNotification notification, to see how's that buffering going.
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(loadStateChanged:) name:MPMoviePlayerLoadStateDidChangeNotification object:nil];
somewhere before initializing your player.
and
-(void)loadStateChanged:(NSNotification *)notif
{
NSString *loadState=#"";
switch (self.player.loadState) {
case MPMovieLoadStateUnknown: {
loadState=#"MPMovieLoadStateUnknown";
break;
}
case MPMovieLoadStatePlayable: {
loadState=#"MPMovieLoadStatePlayable";
break;
}
case MPMovieLoadStatePlaythroughOK: {
loadState=#"MPMovieLoadStatePlaythroughOK";
break;
}
case MPMovieLoadStateStalled: {
loadState=#"MPMovieLoadStateStalled";
break;
}
}
NSLog(#"%#", loadState);
}

Problems with applicationWillEnterForeground

My code for application will Enter Foreground is given below. I am working on the iOS simulator. What I am trying in my code is, when a player clicks home button while game is going on and returns back to the game after sometime, I want the game to be in pause state. Although my code pauses the game, but it does not pause it immediately. That is, when I go to my game again, there is 1 second of movement before everything pauses.
-(void)applicationWillEnterForeground:(UIApplication *)application
{ [[NSNotificationCenter defaultCenter] postNotificationName:#"didEnterForeground" object:self];
}
[[NSNotificationCenter defaultCenter] addObserver: self
selector: #selector(handleEnterFg)
name: #"didEnterForeground"
object: nil];
-(void) handleEnterFg
{
if (gameIsOver== NO)
{
[myTimer pause];
gamePause = YES;
self.scene.view.paused = YES;
}
}
-(void) handleEnterBg
{
if (gameIsOver== NO)
{
[bgPlayer pause];
[self childNodeWithName:#"pauseButton"].zPosition = -10;
[self childNodeWithName:#"playButton"].zPosition = 160;
}
}
Thank you!
You need to pause the game when you receive applicationWillEnterBackground if you want to pause it immediately.

iOS 7 MPMoviePlayerController seek forward button brings the video to the End and displays Black screen

I am facing an issue with MPMoviePlayerController in iOS 7. I enter the fullscreen and then click (just a single tap) on seek forward button (>>|) , and the video playback ends and gives a black screen with a text "Loading" on the header.
I registered notification for "MPMoviePlayerPlaybackStateDidChangeNotification".
**[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayerPlaybackStateDidChange:)
name:MPMoviePlayerPlaybackStateDidChangeNotification
object:self.player];**
It does not get fired on a single click of seek forward button.
Also on registration of "MPMoviePlayerPlaybackDidFinishNotification"
**[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayerPlaybackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:nil];**
I get "MPMovieFinishReasonPlaybackEnded" event fired on that single click of seek forward button.
Any one knows the reason why? Is this a bug in apple?
I need to either stop this behavior of showing a black screen on single click , or just disable single click of seek forward button so that nothing happens.
Any one knows how to achieve this?
I fixed this by removing the MPMoviePlayer object completely, setting it to nil, removing it from it's superview and re-adding it using the original video Url. Code below:
- (void)addPlayerForUrl:(NSURL *)url {
self.player = [[MPMoviePlayerController alloc] initWithContentURL:url];
self.player.view.frame = self.videoView.bounds;
self.player.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
self.player.controlStyle = MPMovieControlStyleDefault;
[self.videoView insertSubview:self.player.view atIndex:0];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayerLoadStateDidChangedNotification:)
name:MPMoviePlayerReadyForDisplayDidChangeNotification
object:self.player];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayerPlaybackStateDidChangeNotification:)
name:MPMoviePlayerPlaybackStateDidChangeNotification
object:self.player];
}
#pragma mark - Notifications
- (void)moviePlayerLoadStateDidChangedNotification:(NSNotification *)notification {
self.isVideoPreloaded = YES;
self.videoPlayButton.hidden = YES;
self.photoImageView.hidden = YES;
self.videoLoadingImageView.hidden = YES;
}
- (void)moviePlayerPlaybackStateDidChangeNotification:(NSNotification *)notification {
NSURL *url = self.player.contentURL;
switch (self.player.playbackState) {
case MPMoviePlaybackStateSeekingBackward:
case MPMoviePlaybackStateSeekingForward:
break;
case MPMoviePlaybackStatePlaying:
self.videoPlayButton.hidden = YES;
if (!self.isVideoPreloaded) {
self.videoLoadingImageView.hidden = NO;
[self.videoLoadingImageView startAnimating];
} else {
self.videoLoadingImageView.hidden = YES;
}
break;
case MPMoviePlaybackStatePaused:
case MPMoviePlaybackStateStopped:
self.videoPlayButton.hidden = NO;
self.videoLoadingImageView.hidden = YES;
[self.player endSeeking];
[self.player.view removeFromSuperview];
[self.player setFullscreen:NO];
self.player = nil;
[self addPlayerForUrl:url];
break;
default:
break;
}
}
Notice how I keep the NSURL, right before the switch statement in the moviePlayerPlaybackStateDidChangeNotification. That way, I can re-initialize and re-add the MPMoviePlayer object.
Btw, my mpmovieplayer is on a tableviewCell if you're wondering. Hope this helps and let me know if you have questions. Good luck!
MPMoviePlayerLoadStateDidChangeNotification will be called when you single tap on the fast-forward or rewind button. You should check the loadState and just give it the path to your video and prepareToPlay again.
- (void)moviePlayerLoadStateChanged:(NSNotification *)notification {
MPMoviePlayerController *moviePlayer = notification.object;
MPMovieLoadState loadState = moviePlayer.loadState;
if(loadState == MPMovieLoadStateUnknown) {
moviePlayer.contentURL = [NSURL fileURLWithPath:videoPath]
[moviePlayer prepareToPlay];
}
.....
}
The reason you're getting MPMovieFinishReasonPlaybackEnded is because playback reached the end of the video (sorry if this is obvious). So it seem's your seek forward actions are seeking all the way to the end of the video. You can check the playback state with MPMoviePlaybackStateSeekingForward.
A quick solution could be to create your own forward button that seek's ahead by a specified time (ie. 5 seconds). But perhaps this isn't the functionality you're looking for.

Notification Center gets called but value of UILabel is not updated in IOS

I am using push notifications in my code and whenever a notification comes, I want to update the value of a label in another ViewController.
My code in AppDelegate is:
- (void)addMessageFromRemoteNotification:(NSDictionary*)userInfo updateUI:(BOOL)updateUI
{
NSLog(#"Notification arrived");
//[mydeals setCode1_id:mydeals.code1_id withString:#"123456"];
mydeals=[[MyDealsViewController alloc]init];
NSDictionary* codeDetails=[[NSDictionary alloc] initWithObjectsAndKeys:#"123456",#"Code_id", nil];
[[NSNotificationCenter defaultCenter] postNotificationName:#"CodeArrived" object:self userInfo:codeDetails];
}
then in my other view controller I have this code:
#implementation MyDealsViewController
-(id) init
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(receiveCode:)
name:#"CodeArrived"
object:nil];
return self;
}
-(void) receiveCode:(NSNotification*)notification
{
NSLog(#"received Code: %#",notification.userInfo);
self.code1_id.text=[NSString stringWithFormat:#"%#",[[notification userInfo] valueForKey:#"Code_id"]];
}
the log is printed correctly but when I manually go into that screen I see the default value, like the label is not updated at all. What should I do?
You have to make sure that when you "manually go" to MyDealsViewController, whatever how you do it, it got to be the same instance of MyDealsViewController wich has been called receiveCode. Otherwise it's going to init with it's default values.
You might also try calling [self.code1_id setNeedsLayout];

iPad - MPMoviePlayer disappears after zooming out

I am using a MPMoviePlayer to stream a video URL.
The video starts in a view's frame after the user taps on it. That works ok. As the video is embedded, the default control places a Zoom in button.
When the user presses the zoom in, the video goes fullscreen ok, without interrupting playback.
However, when the user presses again the zoom out button, i have three problems:
The video zooms to a corner of the screen and then disappears,
instead of returning to the original position.
The video disappears after going to the corner, and playback ends,
instead of continue playing the video.
The MPMoviePlayerDidExitFullscreenNotification never gets called,
only the MPMoviePlayerWillExitFullscreenNotification is called. I have tried sending nil and the mediaPlayerController to the notification center.
Also when pressing the Done button the video goes to the corner of the screen and disappears.
My player is created by doing:
moviePlayer=[[MPMoviePlayerController alloc] init];
moviePlayer.movieSourceType = MPMovieSourceTypeStreaming;
moviePlayer.scalingMode = MPMovieScalingModeAspectFit;
moviePlayer.shouldAutoplay=YES;
moviePlayer.controlStyle=MPMovieControlStyleEmbedded;
moviePlayer.view.hidden = YES;
Then when the user taps on the view this happens:
- (void) playVideo {
NSURL *url=[NSURL URLWithString: _news.videoUrl];
moviePlayer.contentURL = url;
moviePlayer.view.hidden = NO;
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(moviePlayBackDidFinish:) name:MPMoviePlayerPlaybackDidFinishNotification object:moviePlayer];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(moviePlayerWillExitFullScreen:) name:MPMoviePlayerWillExitFullscreenNotification object:moviePlayer];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(moviePlayerDidExitFullScreen:) name:MPMoviePlayerDidExitFullscreenNotification object:moviePlayer];
[moviePlayer play];
}
- (void) moviePlayerWillExitFullScreen:(NSNotification*)notification {
NSLog(#"WILL EXIT FULLSCREEN");
}
- (void) moviePlayerDidExitFullScreen:(NSNotification*)notification {
NSLog(#"EXITED FULLSCREEN"); //NOT CALLED
}
- (void) moviePlayBackDidFinish:(NSNotification*)notification {
NSLog(#"FINISHED PLAYIIING");
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:moviePlayer];
moviePlayer.view.hidden = YES;
}
Well, on the meanwhile I will answer 3 of my 4 questions:
The video zooms to a corner of the screen and then disappears, instead of returning to the original position.
The video disappears after going to the corner, and playback ends, instead of continue playing the video.
Also when pressing the Done button the video goes to the corner of the screen and disappears.
The problem was that after exiting fullscreen mode the -viewWillAppearAnimated method is called. The layout was modified in that method and that's why the playback stopped and view was sent to corner.

Resources