NSNotification, not receiving callback - iphone

Can't figure out why I'm not getting my callback - any advice?
-(void) playMovieWithURL:(NSURL *)url {
[currentVC.view removeFromSuperview];
MPMoviePlayerViewController *movieControl = [[MPMoviePlayerViewController alloc] initWithContentURL:url];
//register for playback finished call
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(movieFinished:) name:MPMoviePlayerDidExitFullscreenNotification object:movieControl];
[self presentMoviePlayerViewControllerAnimated:movieControl];
}
-(void) movieFinished:(NSNotification *)aNotification {
NSLog(#"received callback that movie finished");
MPMoviePlayerController *movie = [aNotification object];
[movie.view removeFromSuperview];
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerDidExitFullscreenNotification object:movie];
[movie release];
[self.view addSubview:currentVC.view];
}

Wild guess, but maybe you want MPMoviePlayerPlaybackDidFinishNotification instead of MPMoviePlayerDidExitFullscreenNotification ?

MPMoviePlayerController posts notifications
MPMoviePlayerViewController does NOT post notifications
So I suppose I'll just switch over to using MPMoviePlayerControllers in this particular case.

I don't know much about the MP API, but you're registering for the notification in a reasonable way. Are you sure that MPMoviePlayerDidExitFullscreenNotification is the notification you want? That (by name alone) doesn't appear to be equivalent to "movie finished".

Related

Adding a UIButton to view after video gets completed playing

As soon as i open my application i have to play a video, by the time the video is being completed i have to add a UIbutton on that video, is it possible, i have searched but i could not find a link, if anybody has passed this situation, and resolved it, can u kindly say me how to do this?
The code for adding the video is :
- (void)viewDidLoad {
NSString *url = [[NSBundle mainBundle] pathForResource:#"splash_screen"ofType:#"mp4"];
MPMoviePlayerController *player = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL fileURLWithPath:url]];
player.view.frame = self.view.bounds;
[self.view addSubview:player.view];
[player play];
[super viewDidLoad];
}
You can use -
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(movieFinished)
name:MPMoviePlayerPlaybackDidFinishNotification
object:nil];
This will call selector "movieFinished" once movie completed, after that you can make the changes that you want.
You can use MPMoviePlayerPlaybackDidFinishNotification notification. For more Info
You can add observer to notify the end of the movie.
The observer can be set as follows:
[[NSNotificationCenter defaultCenter]
addObserver: self
selector: #selector(myMovieFinishedCallback:)
name: MPMoviePlayerPlaybackDidFinishNotification
object: player];
For more info, see the Apple doc, Listing 2-1 Playing full-screen movies

iPhone: UIApplicationWillResignActiveNotification never called

I am playing a video in a view controller. When the user hits the hardware home button and the video is currently playing the app crashes with a EXC_BAD_ACCESS in the simulator.
I read that I should use the applicationWillResignActive message to stop the video from playing which should solve the crashing. So I am trying to register for this notifcation with the notification center, but my selector never gets called. What am I doing wrong?
The following code is in my media player view controller:
- (void) playMedia {
NSURL *mediaUrl = [NSURL fileURLWithPath:tmpFilePath isDirectory:FALSE];
player = [[MPMoviePlayerViewController alloc] initWithContentURL:mediaUrl];
player.moviePlayer.controlStyle = MPMovieControlStyleEmbedded;
player.view.frame = self.view.frame;
[self.view addSubview:player.view];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(applicationWillResignActive:)
name:UIApplicationWillResignActiveNotification
object:nil];
[player.moviePlayer play];
}
- (void)applicationWillResignActive:(NSNotification *)notification {
// never gets called!
NSLog(#"resign active");
[player.moviePlayer stop];
}
Note that if you have the UIApplicationExitsOnSuspend key set to true in your app's Info.plist, the applicationWillResignActive method is not called when the user hits the home button.
Not sure why that one isnt working for you, but im using
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(stopAction:) name:UIApplicationDidEnterBackgroundNotification object:nil];
with success in an Audio Player/Recorder.
possibly try implementing
- (void)applicationWillResignActive:(NSNotification *)notification {
}
in the app delegate and see if it calls.

My MoviePlayer doesn't respond to function

I am facing problem of memory leak and other MoviePlayer new initiation as my MoviePlayer doesn't respond to function, in which I am releasing that player on my done button.
(void) playMovieAtURL
{
MPMoviePlayerViewController *mpViewController = [[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL URLWithString:videoURL]];
mpViewController.view.backgroundColor = [UIColor blackColor];
[self presentMoviePlayerViewControllerAnimated:mpViewController];
[mpViewController.view setCenter:self.view.center];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(myMovieFinishedCallback:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:mpViewController];
}
// When the movie is done,release the controller. (Doesn't come in it.)
-(void)myMovieFinishedCallback:(NSNotification*)aNotification
{
MPMoviePlayerController* theMovie=[aNotification object];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:theMovie];
// Release the movie instance created in playMovieAtURL
[theMovie release];
}
Not sure it's your case, but this is what documentation says about MPMoviePlayerPlaybackDidFinishNotification:
This notification is not sent in cases
where the movie player is displaying
in fullscreen mode and the user taps
the Done button. In that instance, the
Done button causes movie playback to
pause while the player transitions out
of fullscreen mode. If you want to
detect this scenario in your code, you
should monitor other notifications
such as
MPMoviePlayerDidExitFullscreenNotification.
It seems that MPMoviePlayerPlaybackDidFinishNotification is called just when the movie stops by itself.
If you are using the Done button, you should use MPMoviePlayerDidExitFullscreenNotification instead.
I tried to solve it by passing nil and now it is returning me callbacks but still the movie won't releases, I will try ur suggestion also. Anyways my new code
-(void) playMovieAtURL
{
MPMoviePlayerViewController *mpViewController = [[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL URLWithString:videoURL]];
mpViewController.view.backgroundColor = [UIColor blackColor];
[self presentMoviePlayerViewControllerAnimated:mpViewController];
[mpViewController.view setCenter:self.view.center];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(myMovieFinishedCallback:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:nil];
}
// When the movie is done,release the controller.
-(void)myMovieFinishedCallback:(NSNotification*)aNotification
{
MPMoviePlayerController* theMovie=[aNotification object];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:nil];
// Release the movie instance created in playMovieAtURL
[theMovie release];
}

How do I make my NSNotification trigger a selector?

Here's the code:
- (void)viewDidLoad
{
[super viewDidLoad];
NSURL *musicURL = [NSURL URLWithString:#"http://live-three2.dmd2.ch/buureradio/buureradio.m3u"];
if([musicURL scheme])
{
MPMoviePlayerController *mp = [[MPMoviePlayerController alloc] initWithContentURL:musicURL];
if (mp)
{
// save the music player object
self.musicPlayer = mp;
[mp release];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(popBack:) name:#"MPMoviePlayerDidExitFullscreenNotification" object:nil];
// Play the music!
[self.musicPlayer play];
}
}
}
-(void)popBack:(NSNotification *)note
{
[self.navigationController popToRootViewControllerAnimated:YES];
}
The selector method never gets called. I just want to pop back to the root menu when the "Done" button is pressed on the movie player. I put an NSLog in the selector to check if it was even being called, nothing. The music plays fine. Any thoughts?
This should work
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(popBack:) name:MPMoviePlayerPlaybackDidFinishNotification object:nil];

How to release MPMoviePlayerController?

I have a couple of views that access the movie player. I've put the following code in a method in AppDelegate for these views. They send in the filename to play. The code works fine but I know a release is required somewhere. If I add the last line as a release or autorelease, the app will crash once the user presses done on the movieplayer.
MPMoviePlayerController *moviePlayer = [[MPMoviePlayerController alloc]
initWithContentURL:[NSURL fileURLWithPath:moviePath]];
moviePlayer.movieControlMode = MPMovieControlModeDefault;
[moviePlayer play];
//[moviePlayer release];
I get this error:
objc[51051]: FREED(id): message videoViewController sent to freed object=0x1069b30
Program received signal: “EXC_BAD_INSTRUCTION”.
How should I be releasing the player?
What I've found is that the MPMoviePlayerController has to be sent the stop message before you can safely release it. So I do it in handlePlaybackEnd - first I stop it, then I autorelease it. Calling release doesn't seem to work too well:
- (void) moviePlayBackDidFinish : (NSNotification *) notification
{
VideoPlayerController * player = notification.object;
[player stop];
[player autorelease];
}
The whole thing becomes a bit trickier in that the MPMoviePlayerPlaybackDidFinishNotification can get sent more than once, but calling stop/autorlease twice won't do you any good either. So you need to guard against that somehow.
Lastly, it seems to take a few iterations of the main run loop until you can safely create a new MPMoviePlayerController instance. If you do it too quickly, you'll get sound but no video. Great fun, huh?
To answer 4thSpace's comment on the answer above, you can remove the notification observer so you don't receive it multiple times:
- (void)moviePlayBackDidFinish:(NSNotification *)notification {
MPMoviePlayerController *theMovie = [notification object];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:theMovie];
[theMovie stop];
[theMovie release];
}
for iphone os 3.2
you need to call
[moviePlayer pause];
before calling
[moviePlayer stop];
Stopping and releasing was not enough for me if the player did not reach to its end.
My solution is setting the moviePlayer.initialPlaybackTime = -1
at the moviePlayBackDidFinish: before releasing it:
-(void)playMovie: (NSString *)urlString{
movieURL = [NSURL URLWithString:urlString];
moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:movieURL];
moviePlayer.initialPlaybackTime = 0;
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(moviePlayBackDidFinish: ) name:MPMoviePlayerPlaybackDidFinishNotification object:moviePlayer] ;
moviePlayer.scalingMode = MPMovieScalingModeAspectFit;
moviePlayer.movieControlMode = MPMovieControlModeDefault;
moviePlayer.backgroundColor = [UIColor blackColor];
[moviePlayer play];
}
-(void)moviePlayBackDidFinish: (NSNotification*)notification{
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:moviePlayer] ;
moviePlayer.initialPlaybackTime = -1;
[moviePlayer stop];
[moviePlayer release];
}
I had the same problem and I just realized I set the notification method with object:nil (it was a copy paste).
I was having multiple notifications although I shouldn't have had any notifications at all.
Here is my new notification set up code that fixed all (see the object:moviePlayer):
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlaybackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:moviePlayer];
Hope that helps. Now all my code is working properly.
This seemed to reduce the memory significantly. However for IOS 4.1 it seems fine.
- (void)videoFinishedCallback:(NSNotification *)aNotification
{
thePlayer = [aNotification object];
[[NSNotificationCenter defaultCenter]
removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification object:thePlayer];
thePlayer.initialPlaybackTime = -1;
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 30200
[thePlayer pause];
#endif
[thePlayer stop];
[thePlayer release];
}