I have a class that plays a repeating background music loop with an AVAudioPlayer, and on specific occasion, plays a full-screen video with its own sound track using MPMoviePlayerController. In order to to have only one track at a time, I stop the background music before launching the video:
-(void)startVideo{
[backgroundMusic stop];
MPMoviePlayerViewController *mp = [[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"videofile" ofType:#"m4v"]]];
[self presentMoviePlayerViewControllerAnimated:mp];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(videoOver) name:MPMoviePlayerPlaybackDidFinishNotification object:nil];
[mp.moviePlayer play];
[mp release];
}
-(void)videoOver{
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:nil];
if(![backgroundMusic play]){
NSLog(#"bad: can't resume bg music!");
[backgroundMusic release];
backgroundMusic = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"videofile" ofType:#"m4v"]] error:NULL];
backgroundMusic.delegate = self;
backgroundMusic.numberOfLoops = -1;
[backgroundMusic play];
}
}
The resumption worked fine without recreating the AVAudioPlayer object (i.e. the play method returned YES) on analogous code on os versions up to and including 3.2. But on iOS4, the play method always returns NO, and has to recreate the object. Why is that, and can I get to resume the background track properly (I have cases where the solution used above is unacceptable.)?
Figured this out. It turns out that in iOS 3.2 and above, when a video finishes playing, it goes into MPMoviePlaybackStatePaused state rather than MPMoviePlaybackStateStopped, and in order to make it release the hardware, you have to explicitly call the stop method on MPMoviePlayerController after it finishes playing before trying to resume AVAudioPlayer.
Related
I'm trying to implement a notification in to my movie player, so that once the movie is done playing, it will exit fullscreen. The code is have so far i posted below. The IBAction is hooked up to a button. Also on a side note, i have been trying to figure out how to get the "play symbol" on top of my movie view, so that the user just have to press that and the video will start. Anybody know how to implement that?
- (void)viewDidLoad
{
//Video player
NSString *url = [[NSBundle mainBundle] pathForResource:self.navigationItem.title ofType:#"mov"];
_player = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL fileURLWithPath: url]];
_player.view.frame = CGRectMake(350, 200, 400, 400);
[self.view addSubview:_player.view];
}
- (IBAction)playMovie
{
[_player play];
}
You can detect when your movie finishes playing by registering for an MPMoviePlayerPlaybackDidFinishNotification notification in your viewDidLoad method:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(playerPlaybackDidFinish:) name:MPMoviePlayerPlaybackDidFinishNotification object:_player];
And then perform whatever action you want to do in the callback method you specified when registering:
- (void) playerPlaybackDidFinish:(NSNotification*)notification
{
// movie finished playing
_player.fullscreen = NO;
}
I am trying to play streaming file from particular URL using MPMoviePlayerController. It is working fine when I load the player but I need to keep it running when application enter into the background mode (Multitasking). This is what I am doing:
-(void) playAudio :(NSString *)playAudioURL
{
//NSURLRequest *audioFile = [[NSURLRequest alloc] initWithURL: [NSURL URLWithString:self.playAudioURL] cachePolicy: NSURLRequestUseProtocolCachePolicy timeoutInterval: 10];
MPMoviePlayerController *mediaPlayer = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL URLWithString:playAudioURL]];
mediaPlayer.scalingMode = MPMovieScalingModeAspectFill;
mediaPlayer.scalingMode = MPMovieScalingModeAspectFill;
mediaPlayer.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"Home-bg.png"]];
//[self.view addSubview:mediaPlayer.view];
mediaPlayer.fullscreen = YES;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(myMovieFinishedCallback:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:mediaPlayer];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(videoPreloadCallback:)
name:MPMoviePlayerContentPreloadDidFinishNotification
object:mediaPlayer];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(moviePlayerPlaybackStateDidChange:) name:MPMoviePlayerPlaybackStateDidChangeNotification object:nil];
[mediaPlayer play];
}
Now when I press iPhone home button while running the audio, it pauses the streaming until I load back the Application. I need to keep it running when app enter into background.
In your plist file, did you set the UIBackgroundModes key to audio ? Without this, your application will not play any sound in background
Note that in iOS5, UIBackgroundModes is now referenced as Required background modes when you edit your plist file.
See mpmovieplayercontroller-multitasking-problem
I have encountered a problem with the MPMoviePlayerController in 3.1.2.
If I cancel the player while it is still loading, the player closes. However, the video starts playing a few moments later in the background. The only ways to stop it are to play another video or close the app. This seems to work fine in 3.2+.
Here's what I'm doing:
- (void)loadMoviePlayer
{
// Register to receive a notification when the movie has finished playing.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayBackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:nil];
if ([NSClassFromString(#"MPMoviePlayerController") instancesRespondToSelector:#selector(view)])
{
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 30200
// running iOS 3.2 or better
MPMoviePlayerViewController *moviePlayer = [[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL URLWithString:#"http://www.mysite.com/myvideo.m3u8"]];
[moviePlayer.view setBackgroundColor:[UIColor blackColor]];
[moviePlayer.moviePlayer setControlStyle:MPMovieControlStyleFullscreen];
// [moviePlayer.moviePlayer setControlStyle:MPMovieControlStyleNone];
[self presentMoviePlayerViewControllerAnimated:moviePlayer];
[moviePlayer.moviePlayer prepareToPlay];
[moviePlayer.moviePlayer play];
#endif
}
else
{
MPMoviePlayerController *mMPPlayer = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL URLWithString:#"http://www.mysite.com/myvideo.m3u8"]];
mMPPlayer.scalingMode=MPMovieScalingModeFill;
mMPPlayer.backgroundColor=[UIColor blackColor];
[mMPPlayer play];
}
}
- (void) moviePlayBackDidFinish:(NSNotification*)notification
{
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackOpaque];
[[UIApplication sharedApplication] setStatusBarHidden:NO];
// Remove observer
[[NSNotificationCenter defaultCenter]
removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:nil];
[self dismissModalViewControllerAnimated:YES];
}
I added moviePlayBackDidFinish this morning. It gets called when I hit cancel, but dismissModalViewControllerAnimated doesn't seem to do anything. I also tried removeFromSuperView, but my player will not respond.
So, how can I make sure the player does not play after hitting "cancel"?
Thanks in advance.
You may have come across an old bug in MPMoviePlayerController. Back in the days, we actually had to play an almost empty (black, silence) M4V after playing proper content to be sure the player does not attempt to continue playback in the background when stopping at certain stages. That bug manifests in audible sound but no picture of the aborted/stopped video.
There are however a few more things worth trying when stopping (assuming your instance of MPMoviePlayerController is called moviePlayer);
set the current playback position to the complete movie duration moviePlayer.currentPlaybackTime = moviePlayer.duration;
send another stop within your notification handler [moviePlayer stop];
In my case, I found that setting the following line would eventually stop the movie player from playing:
moviePlayer.contentURL = nil;
(with moviePlayer your instance of MPMoviePlayerController).
i used all the examples and source code out there for displaying application content to external VGA display. while playing video in inside of the application am getting bellow thing in external device. any suggestion.... am i missing somthing.. but in device it showing actual window in fine way..
Hello All here am answering to my own question.
robterrell's TVOutManager will not play any video to external device by simply doing [[TvOutManager sharedinstance] startTvOut] and [[TvOutManager sharedinstance]s topTVOut];
here we have add the instance of player to tvoutWindow.
[tvoutWindow addSubview:player's instance];
but here thing is the video is not displayed in device,
but you can control external window player from device.
cheers.
NSString *url = [[NSBundle mainBundle] pathForResource:#"Overview" ofType:#"mov"];
player = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL fileURLWithPath:url]];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(movieFinishedCallback:)name:MPMoviePlayerPlaybackDidFinishNotification object:player];
//---play partial screen---
player.view.frame = CGRectMake(35, 450, 430, 300);
[self.view addSubview:player.view];
[player play];
- (void) movieFinishedCallback:(NSNotification*) aNotification {
[[TVOutManager sharedInstance] startTVOut];
player = [aNotification object];
[[NSNotificationCenter defaultCenter]
removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:player];
[player stop];
}
this the code am added in mainviewController class in robterrell's TVOutManager sample application. after connecting device into external device. while switching mirror video on am not getting anything..
I have following code that I use to play a selected portion of a movie clip. The movie plays okay. But the scrubber bar does not reflect the correct start stop time. Also, the forward and rewind buttons take the clip beyond the segment that was specified. Why is this and can we fix it?
TIA.
MPMoviePlayerViewController *mp =
[[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL fileURLWithPath:movieFile] ];
[mp.moviePlayer setInitialPlaybackTime:21];
[mp.moviePlayer setEndPlaybackTime:48];
[self presentMoviePlayerViewControllerAnimated:mp];
[self shouldAutorotateToInterfaceOrientation:YES];
//NSLog(#"Movie Player Controller View = %#", mp.moviePlayer.view);
//NSLog(#"Movie Player Controller Parent View = %#", mp.parentViewController);
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayBackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:[mp moviePlayer]];
[mp.moviePlayer play];