How to know when the playControllerBar of moviePlayer will be dismiss? - iphone

as the title,when i play movie using moviePlayer I want to know when the playControllerBar will be dismiss,so that i can control my view added in moviePlayer .
Is there anyone know that?
Tell me ,thanks .

I'm not 100% sure if I understand you correctly.
I assume that what you want to do is:
play a movie
add a custom view (overlay) on top of the (running) movie.
assuming what i just wrote down, I think you have to consider the following things:
adding a custom overlay on top of MPMoviePlayerViewController is (as far as I'm concerned) only allowed/possible if the standard player controls are set to none:
[moviePlayerViewController.moviePlayer setControlStyle:MPMovieControlStyleNone];
adding your custom overlay on top of the player is basically the same addSubview procedure as on any other view
[moviePlayerViewController.view addSubview:overlay];
the above code / concept will work on 3.2 and later, as i just read now you're obviously developing for 3.0
rather then deleting the first part of my answer i will now explain how to achieve the same effect on 3.0
on 3.0 it's a bit trickier (as you sure know by now).
MPMoviePlayerController is not a view Controller and works only in fullscreen-mode. Once the movie starts playing, the keyWindow changes! so We make use of that by implementing the following:
1) within your Class that encapsulates the MPMoviePlayerController, start listening to the UIWindowDidBecomeKeyNotification by doing the following:
[[NSNotificationCenter defaultCenter] addObserver: self
selector: #selector(keyWindowChanged:)
name: UIWindowDidBecomeKeyNotification
object: nil];
2) withing your keyWindowChanged: Method you can add your overlay, the following snipplet is exactly how I implemented it:
- (void)keyWindowChanged: (id) sender {
//NSLog(#"keyWindowChanged");
[[NSNotificationCenter defaultCenter] removeObserver: self name: UIWindowDidBecomeKeyNotification object: nil];
UIWindow *moviePlayerWindow = [[UIApplication sharedApplication] keyWindow];
[moviePlayerWindow addSubview: overlayController.view];
[overlayController performSelector:#selector(fadeIn)];
}
again, this only works if the MovieControllMode is "hidden" by doing that:
[newMPController setMovieControlMode: MPMovieControlModeHidden];
I hope I could help.

Related

Status Bar keeps showing up when dismissing MPMoviePlayerViewController

I'm making an app where I need to play a movie from my camera roll. I'm using MPMoviePlayerViewController to do is, and displaying it with:
[self presentMoviePlayerViewControllerAnimated:theMovie];
I want it to run in fullscreen mode:
[theMovie.moviePlayer setControlStyle:MPMovieControlStyleFullscreen];
This is where the issue comes up. I don't want the Options to be displayed upon launch, so I decided to set the control style to MPMovieControlStyleNone initially. But I still want the options to be available, so after searching around I found this option:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(enterFullScreenMode)
name:MPMoviePlayerLoadStateDidChangeNotification object:nil];
And in this method I change the control state to MPMovieControlStyleFullscreen. This causes the status bar to be displayed in my app AFTER I dismiss the movie and return to my parent view controller. My application doesn't use the status bar at all. I've tried this:
[[UIApplication sharedApplication] setStatusBarHidden:YES];
And it didn't work. I should point out this issue only shows up if I start with control state None and then switch to Fullscreen while the movie is playing, but I need to do this because I don't want the options to show up upon launch. I'm open to any ideas. Please help me eliminate the status bar once and for all.
Thanks guys :)

iOS presentMoviePlayerViewControllerAnimated can't be called twice using the same viewController

So I'm trying to present a MPMoviePlayerViewController using the method presentMoviePlayerViewControllerAnimated in my own view controller.
However, once I clicked the blue Done button on the top left, when I present the same viewController again (so that I can resume a video without having to create another instance of MPMoviePlayerViewController), the controls will no longer work if you let them disappear on their own after a few seconds. The controls will still function if you interact with them before they disappear, but once they fade away on their own, you can no longer bring them back up when tapping the video. This happens on both the device and the simulator.
Simplified code:
- (void) startPlayback
{
if (self.videoViewController == nil)
{
self.videoViewController = [[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL URLWithString:self.videoUrl]];
}
// present the video player
[self presentMoviePlayerViewControllerAnimated:self.videoViewController];
}
assume that startPlayback is a delegate method or something in a view controller, and it's being triggered by a button. Self would refer to the view controller in this case.
So with this, it will bring up the video player which works perfectly. Then, once I wait a bit, the controls will disappear and I can bring them back by tapping the video. I can then dismiss this video player using the Done button on the top left. Once I dismiss it, and I can then bring back the video view controller. The video will still be playing, but now, when I wait a bit and the controls disappear, I can no longer bring up the controls by tapping the screen, effectively trapping myself in the video player.
I have found various solutions into hooking into the Done button, but it hasn't really allowed me to reuse the video player. For example:
// Remove the observer so that the blue button doesn't close the viewController
[[NSNotificationCenter defaultCenter] removeObserver:self.videoViewController name:MPMoviePlayerPlaybackDidFinishNotification object:self.videoViewController.moviePlayer];
// Add itself as an observer
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(movieEnded:) name:MPMoviePlayerPlaybackDidFinishNotification
object:self.videoViewController.moviePlayer];
In my movieEnded:, I can then dismiss the movie view controller via:
[self dismissMoviePlayerViewControllerAnimated];
But when I try to present the viewController again, the video player just gets stuck Loading... forever.
Any ideas?

Playing subsequent movies in one MPMoviePlayerViewController

I am having a difficulty with the MPMoviePlayViewController.
I insatiate the controller, assign the url and show the player using:
[self presentMoviePlayerViewControllerAnimated:[appDelegate movieController]];
Then when the movie finished I dismiss it:
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:nil];
[self dismissMoviePlayerViewControllerAnimated];
The movie player is alloc in my AppDelegate.
There are some other listeners on MPMoviePlayerPlaybackDidFinishNotification. This is for the case where there might e.g. only be audio and it shows a play/pause button and counters in table cells.
The problem is that when I load a second movie in the same MPMovieViewController, it appears fine but the controls are not working correctly. They are work as long as they are visible, but as soon as they disappear there is no may of getting them back and therefore to dismiss the movie player.Sometimes closing and opening the App works, but sometimes it doesn't and I need to 'kill' the App in order to be able to start again.
Is there a way to play subsequent video's in the MoviePlayer while the controls still work?
Any suggestions how to 'reset' the Player in a way that I can prevent the other listeners from given a DEALLOC as they are listening for the action?
you dont need to dismiss the player you just need to set the new url... or maybe I missunderstood your problem...
Try adding this to your setup movie player controller
moviePlayerController.view.userInteractionEnabled = YES;

Responding to MPMoviePlayerController notifications during background media playback

I have an app that streams video from the net and plays it using an MPMoviePlayerController object for playback on the device or via AirPlay.
The app supports background operation and has the 'audio' option listed within the required UIBackgroundModes key in its plist file.
When playing over AirPlay, the app can successfully be pushed to the background and the video continues to play properly. So far, so good.
According to the Apple documentation:
Including the audio key tells the system frameworks that they should
continue playing and make the necessary callbacks to the app at
appropriate intervals. If the app does not include this key, any audio
being played by the app stops when the app moves to the background.
However, these callbacks are not being made.
The app uses two types of callback: those associated with notifications MPMoviePlayerController and AVPlayer send during playback together with timer based callbacks that monitor the playback position and performance stats for monitoring purposes.
Looking at Apple's notes, I would certainly expect to receive the first type of callback so that the app can respond to MPMoviePlayerPlaybackStateDidChangeNotification, MPMoviePlayerPlaybackDidFinishNotification and MPMoviePlayerLoadStateDidChangeNotification, but this doesn't happen.
Does anyone know if it is possible to receive these during background AirPlay playback and, if so, how was this achieved?
**Please note: the app works correctly when running in the foreground and receives the notifications fine. It is only when pushed to the background and playing over AirPlay that the notifications are not received.
Likewise, the video plays over AirPlay in the background properly. It is only the notifications which are not received**
I had this issue and have fixed it though it was a few months back. I could send you my entire class for movie playback if this doesn't work. Note it is using the navigation controller model.
NOTE: This is tested on iPad 2 not on the iPhone.
I show my VC like this:
- (IBAction)playMovie:(id)sender {
MovieVC* movController = [[MovieVC alloc] initWithID:2];
movController.view.backgroundColor = [UIColor blackColor];
AppDelegate *appDel = [[UIApplication sharedApplication] delegate];
[appDel.navigationController pushViewController:movController animated:NO];
[movController release];
}
Then in my MovieVC view controller class i set up the video playback like this:
- (void)initMoviePlayer {
mMoviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:[self getMovieURL]];
mMoviePlayer.allowsAirPlay = YES;
mMoviePlayer.view.frame = [self.view bounds];
mMoviePlayer.view.backgroundColor = [UIColor clearColor];
mMoviePlayer.shouldAutoplay = YES;
mMoviePlayer.fullscreen = YES;
mMoviePlayer.scalingMode = MPMovieScalingModeAspectFit;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePreloadDidFinish:)
name:MPMoviePlayerLoadStateDidChangeNotification
object:mMoviePlayer];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayBackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:nil];
}
This fixed it for me, if it doesn't fix comment and ill edit with the entire class file.
In one of my projects I did what you did, and it worked for me.
Two differences in my project :
I am not streaming via airPlay (device playback only),
I am just playing audio files.
My step-by-step :
Add the audio option to UIBackgroundModes in the plist file,
Register to the NotificationCenter for MPMoviePlayerPlaybackDidFinishNotification and MPMoviePlayerPlaybackStateDidChangeNotification with the following code :
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(playbackStateChanged:)
name:MPMoviePlayerPlaybackStateDidChangeNotification
object:moviePlayer];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(playbackEnded:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:moviePlayer];
It works like a charm.
For completeness, I ought to add that at present I believe there is no solution to this problem.
I've discussed it directly with Apple via tech support and there was no practical work-around available.
This functionality was needed to allow the app to record stats about the playback of the stream at regular intervals. While this is fine when the video is played on the device's screen and over AirPlay while the app is in the foreground, it isn't possible to do with the app in the background.
The solution I've gone with instead is to disable the idle timer during all types of playback and to re-enable afterwards using:
[UIApplication sharedApplication].idleTimerDisabled = YES;
and
[UIApplication sharedApplication].idleTimerDisabled = NO;
While this isn't a solution to the original question, it's a workaround for avoiding the issue in the first place.

New View when device is rotated

I want to call "presentmodalviewcontroller" when the iPhone / iPod Touch is rotated to landscape mode with a flip animation. When it gets rotated back to portrait, I want to present the first view again, again with the flip animation.
Weren't able to find something working on the web :(
I'm sure you can help me :)
Thanks a lot !
Sebastian
Try listening for the UIDeviceOrientationDidChangeNotification notification:
[[NSNotificationCenter defaultCenter] addObserver: self selector: #selector(deviceOrientationDidChange:) name: UIDeviceOrientationDidChangeNotification object: nil];
When you get on it, present your controller.
In your UIViewController, accept all interface orientations:
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
And your controller will start receiving rotation messages, like:
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration
and
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
Where you can react to rotation and do things like present/dismiss modal viewcontrollers.