I have a MPMoviePlayerController subclass that should show the controls when playback is finished. I have attached a responder to the MPMoviePlayerPlaybackDidFinishNotification notification and tried setting the control style as follows:
[self setControlStyle:MPMovieControlStyleEmbedded];
This is not working. In essence, at the end of the video I want to controls to show.
How can I show controls programatically?
NOTE: The controller is NOT in fullscreen mode.
Kindly find my full Code about this , it's working with me
add .h class add this
#property(strong,nonatomic) MPMoviePlayerViewController * moviePlayer;
at .m class add this code "pass the movie URl"
-(void) playMovie:(NSString *)filePath
{
NSURL *theOutputURL = [NSURL fileURLWithPath:filePath];
if(_moviePlayer)
[_moviePlayer.moviePlayer setContentURL:theOutputURL];
else
_moviePlayer = [[MPMoviePlayerViewController alloc] initWithContentURL:theOutputURL];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(myMovieFinishedCallback:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:_moviePlayer.moviePlayer];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(moviePlayerPlaybackStateDidChange:) name:MPMoviePlayerPlaybackStateDidChangeNotification object:_moviePlayer.moviePlayer];
if (![_moviePlayer.moviePlayer isPreparedToPlay])
[_moviePlayer.moviePlayer prepareToPlay];
_moviePlayer.moviePlayer.movieSourceType = MPMovieSourceTypeFile;
[_moviePlayer.moviePlayer setFullscreen:YES];
_moviePlayer.moviePlayer.controlStyle=MPMovieControlStyleEmbedded;
[_moviePlayer.moviePlayer setContentURL:theOutputURL];
_moviePlayer.view.frame = CGRectMake(0, 0, [[UIScreen mainScreen]bounds].size.width, [[UIScreen mainScreen]bounds].size.height);
[_moviePlayer shouldAutorotateToInterfaceOrientation: AVCaptureVideoOrientationLandscapeRight];
[self.view addSubview:_moviePlayer.view];
}
- (void) moviePlayerPlaybackStateDidChange: (NSNotification *) notification {
if (_moviePlayer.moviePlayer.playbackState == MPMoviePlaybackStateStopped) {
[_moviePlayer.moviePlayer setContentURL:[_moviePlayer.moviePlayer contentURL]];
[_moviePlayer.moviePlayer play];
}
}
-(void)myMovieFinishedCallback:(NSNotification*)aNotification
{
// to add your code after playback is finished
}
Related
I have a ViewController which displays the information about the selected show, and the play button of the MPMoviePlayerController is there. Now, the issue is when I clicked on the full screen of the player then clicked done. It is supposed to go back to the ViewController which displays the info, but it isn't. But it is going in to the viewDidLoad of the ViewController and it doesn't display anything at all. I feel like something is on the top of the ViewController or something like that
Here's how I remove the player controller
- (void)dealloc
{
self.delegate = nil;
self.activityIndicator = nil;
[self deregisterMoviePlayerNotifications];
[self.player.view removeFromSuperview];
[self removeFromSuperview];
[self stopVideo];
self.player = nil;
}
You should use AVPlayerViewController as MPMoviePlayerController is deprecated. You can use this code on play button
-(void)playButton{
AVPlayer *player = [[AVPlayer alloc]initWithURL:urlVideo];
AVPlayerViewController *controller = [[AVPlayerViewController alloc]init];
controller.player = player;
controller.videoGravity = AVLayerVideoGravityResizeAspectFill;
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(playerItemDidReachEnd:) name:AVPlayerItemDidPlayToEndTimeNotification object:player.currentItem];
controller.videoGravity = AVLayerVideoGravityResizeAspect;
[self presentViewController:controller animated:YES completion:nil];
[player play];
}
-(void)playerItemDidReachEnd:(NSNotification*)notification{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[self dismissViewControllerAnimated:YES completion:nil];
}
Note : Don't forget to add AVFoundation.framework.
I use a MPMoviePlayerController to play a video from Internet.
player = [player initWithContentURL:[NSURL URLWithString:videoURL]];
player.view.frame = CGRectMake(0, 0, videoView.frame.size.width, videoView.frame.size.height - 20);
[player setControlStyle:MPMovieControlStyleEmbedded];
player.scalingMode = MPMovieScalingModeAspectFit;
[player prepareToPlay];
player.shouldAutoplay = NO;
[videoView addSubview:player.view];
I notified that after I clicked the full screen button (2-arrows-button), I was navigated to the full size video screen. I couldn't restore down the screen by touching the Done button. I even used NSNotification but can't resolve the problem. Here is the Notification code:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(movieEventFullscreenHandler:)
name:MPMoviePlayerWillEnterFullscreenNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(movieEventFullscreenHandler:)
name:MPMoviePlayerDidEnterFullscreenNotification
object:nil];
}
- (void)movieEventFullscreenHandler:(NSNotification*)notification {
[player setFullscreen:NO animated:NO];
[player setControlStyle:MPMovieControlStyleEmbedded];
}
How can I dismiss that video screen by touching the Done button? Thanks guys.
You can use the notification of MPMoviePlayerPlaybackDidFinishNotification to observe the done button.
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(playObserver:)name:MPMoviePlayerPlaybackDidFinishNotification object:nil];
and then,make a judge of quitting.
- (void) playObserver:(NSNotification *)notification
{
MPMoviePlayerController* player = moviePlayerView.moviePlayer;
if (player == [notification object]) {
if (_invalidVideoCount > MOVIE_TRY_TIMES) {
[self dismissViewController];
}
_invalidVideoCount++;
int reason = [[[notification userInfo] objectForKey:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey] intValue];
//Whether continuous playback
if (![SINGLETON_CALL(SystemInfoManager) boolValueForKey:UserContinuousPlayEnableKey]) {
[self playFinishWithForce:YES];
return;
}
switch (reason) {
case MPMovieFinishReasonUserExited:
[self playFinishWithForce:YES];
break;
case MPMovieFinishReasonPlaybackError:
[self playFinishWithForce:YES];
break;
case MPMovieFinishReasonPlaybackEnded:
movieTryTimes = 0;
[self playFinishWithForce:NO];
break;
default:
break;
}
}
}
and the last.
- (void)playFinishWithForce:(BOOL)force
{
FileInfoItem *item = ARRAY_OBJECT_AT_INDEX(_playlist, _currentIndex);
BOOL quit = force || !item;
if (quit) {
[self dismissViewController];
} else {
[self playMovieWithItem:item];
}
}
Also you can use the notification of MPMoviePlayerPlaybackStateDidChangeNotification to make any observe.something detail see MPMoviePlayerController.h or https://developer.apple.com/library/ios/documentation/MediaPlayer/Reference/MPMoviePlayerController_Class/Reference/Reference.html
I have found the problem. That's I laid [player stop] in the viewWillDisAppear so can't handle the notification. I fixed temporary by changing it to [player pause]. I appreciated any kind of your helps.
I'm working on application for video streaming. It is built with ARC for iOS5.
To display view I use MPMoviePlayerViewController this way:
.h
#interface EpisodesTableViewController : UITableViewController<EpisodeUrlResolverDelegate> {
NSTimeInterval playbackTime;
EpisodeUrlResolver *episodeUrlResolver;
}
#property (strong, nonatomic) MPMoviePlayerViewController *player;
#end
.m
#implementation EpisodesTableViewController
#synthesize episodes, player;
- (void)viewDidLoad
{
[super viewDidLoad];
episodeUrlResolver = [[Soap4MeEpisodeUrlResolver alloc] init];
[episodeUrlResolver setDelegate:self];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(willEnterForeground) name:#"WillEnterForeground" object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(willEnterBackground) name:#"WillEnterBackground" object:nil];
}
- (void)viewDidUnload
{
episodeUrlResolver = nil;
player = nil;
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"WillEnterForeground" object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"WillEnterBackground" object:nil];
[super viewDidUnload];
}
- (void)url:(NSURL *)url WasResolvedForEpisode:(Episode *)episode {
player = [[MPMoviePlayerViewController alloc] initWithContentURL:url];
player.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
player.moviePlayer.allowsAirPlay = YES;
[self presentModalViewController:player animated:YES];
}
- (void)willEnterBackground {
if (player) {
playbackTime = player.moviePlayer.currentPlaybackTime;
}
}
- (void)willEnterForeground {
if (!player)
return;
if(player.moviePlayer.playbackState == MPMoviePlaybackStateInterrupted || player.moviePlayer.playbackState == MPMoviePlaybackStateStopped || player.moviePlayer.playbackState == MPMoviePlaybackStatePaused)
{
[self continuePlayback];
}
}
- (void)continuePlayback {
[self presentModalViewController:player animated:YES];
[player.moviePlayer setInitialPlaybackTime:playbackTime];
NSLog(#"%f", player.moviePlayer.initialPlaybackTime);
[player.moviePlayer play];
}
Few words about presented code:
when url for video is resolved I create the MPMoviePlayerViewController object for video playback. Playback is started. Then when app is going background with home button MPMoviePlayerViewController automatically pauses playback and dissapears from screen (weird behavior, as for me). Thats why I have to save playback time when app is going background and show existing MPMoviePlayerViewController again with restored playback time when app is back to foreground.
It works fine when user presses home button and then is going back to application.
But it doesn't work when user locks the device. WillEnterBackground notification is fired when
applicationWillEnterForeground is called, so for locking event it is called too.
But in case when user locks the device MPMoviePlayerViewController wasn't being dismissed properly as in situation when user presses home button. It is hidden from the screen, but calling the code
[self presentModalViewController:player animated:YES];
throws the exception
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Application tried to present modally an active controller <EpisodesTableViewController: 0x91b3950>.'
I tried to change the code to dismiss controller:
- (void)willEnterForeground {
if (!player)
return;
if(player.moviePlayer.playbackState == MPMoviePlaybackStateInterrupted || player.moviePlayer.playbackState == MPMoviePlaybackStateStopped || player.moviePlayer.playbackState == MPMoviePlaybackStatePaused)
{
if (self.presentedViewController) {
[self dismissViewControllerAnimated:YES completion:^{
[self continuePlayback];
}];
}
else {
[self continuePlayback];
}
}
}
Now it doesn't throw the exception, but displays warning
wait_fences: failed to receive reply: 10004003
Also completion block is never called.
How to properly to solve the background/foreground continue playing with modally displayed MPMoviePlayerViewController?
Thanks for replies.
I solved the problem.
Method -willEnterBackground should look like:
- (void)willEnterBackground {
if (player) {
playbackTime = player.moviePlayer.currentPlaybackTime;
[self dismissModalViewControllerAnimated:NO];
}
}
We have to dismiss MPMoviePlayerViewController manually when app is entering background mode.
Pay attention to use only
[self dismissModalViewControllerAnimated:NO];
instead of
[self dismissMoviePlayerViewControllerAnimated];
Thats because MPMoviePlayerViewController was shown with
[self presentModalViewController:player animated:YES];
I am facing a problem in ipad video incorporating. My code works fine I mean it plays the video, but once the video reaches to its end. The callback method is not called.
This method is called when play video button is pressed.
-(IBAction) playVideo : (id) sender
{
[self initPlayingVideo:#"toyVid.mp4"];
}
This method handles the playing of video.
-(void) initPlayingVideo: (NSString *) videoFile
{
NSString *moviePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:videoFile];
theMovie = [[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL fileURLWithPath:moviePath]];
theMovie.moviePlayer.scalingMode = MPMovieScalingModeAspectFit;
theMovie.moviePlayer.controlStyle = MPMovieControlStyleFullscreen;
[self.view addSubview:theMovie.view];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(videoPlayerDidFinishPlaying
name:MPMoviePlayerPlaybackDidFinishNotification
object:theMovie];
videoPlayer = [theMovie moviePlayer];
[videoPlayer play];
}
This is the callback method.
-(void) videoPlayerDidFinishPlaying: (NSNotification*)aNotification
{
theMovie = [aNotification object];
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:theMovie.moviePlayer];
[videoPlayer stop];
[theMovie.moviePlayer release];
[videoPlayer release];
[theMovie.view removeFromSuperview];
}
Where I am doing mistake? Please guide.
Regards
Ranjan
Did you miss the : and ) in your selector? I guess ) may be your typo otherwise you cannot compile your codes. Your selection takes one parameter. It should be:
selector:#selector(videoPlayerDidFinishPlaying:)
That will match to your instance method. I guess you don't have one without parameter.
I'm trying to use the MPMoviePlayerController class on the iPad.
Here's my code:
multimediaPlayer = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL fileURLWithPath:path]];
multimediaPlayer.movieControlMode = MPMovieControlModeDefault;
[multimediaPlayer play];
and this works very well on the iPhone but it don't want to run on the iPad. I hear the sound of the video, but the movie doesn't playing.
Why it can be this problem?
Below code working perfect for my application. Hope it would do same for you.
The main thing is to set the frame of mpMoviePlayerController's frame. if you don't do it, it would almost not show the video.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[[UIApplication sharedApplication] setStatusBarHidden:YES];
// Register to receive a notification when the movie has finished playing.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayBackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:nil];
// Register to receive a notification when the movie scaling mode has changed.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(movieScalingModeDidChange:)
name:MPMoviePlayerScalingModeDidChangeNotification
object:nil];
kDomain = [NSString stringWithString:#"http://www.virtua-book.com/"];
[navigationController setNavigationBarHidden:YES];
NSURL *ur=[[NSURL alloc] initFileURLWithPath:[[NSBundle mainBundle] pathForResource:#"IPAD" ofType:#"mp4"]];
mpMCtr=[[MPMoviePlayerController alloc] initWithContentURL:ur];
mpMCtr.fullscreen=YES;
[mpMCtr setScalingMode:MPMovieScalingModeFill];
[mpMCtr setShouldAutoplay:YES];
[mpMCtr setControlStyle:MPMovieControlStyleNone];
[mpMCtr setMovieSourceType:MPMovieSourceTypeFile];
mpMCtr.view.frame = CGRectMake(0, 0, 1024, 768);
[mpMCtr setRepeatMode:MPMovieRepeatModeNone];
[mpMCtr play];
[ur release];
// Override point for customization after app launch
[navigationController.view addSubview:mpMCtr.view];
[window addSubview:[navigationController view]];
[window makeKeyAndVisible];
return YES;
}
// Notification called when the movie finished playing.
- (void) moviePlayBackDidFinish:(NSNotification*)notification
{
[mpMCtr.view removeFromSuperview];
}
To fix back/forward (or previous/next) buttons you should do the following:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(moviePlayerPlaybackStateDidChange:) name:MPMoviePlayerPlaybackStateDidChangeNotification object:nil];
...
- (void) moviePlayerPlaybackStateDidChange: (NSNotification *) notification {
if (moviePlayer.playbackState == MPMoviePlaybackStateStopped) {
[moviePlayer setContentURL:[moviePlayer contentURL]];
[moviePlayer play];
}
}
Something along these lines is probably what you want to do:
MPMoviePlayerViewController *mpvc = [[MPMoviePlayerViewController alloc] initWithContentUrl:movieUrl];
[self presentMoviePlayerViewController:mpvc];
MPMoviePlayerViewController *mp = [[MPMoviePlayerViewController alloc]initWithContentURL:movieURL];
mp.moviePlayer.controlStyle = 2;
Ok, guys, I found that this: is deprecated.
The solution is multimediaPlayer.controlStyle = MPMovieControlStyleDefault; but it still doesn't work.