MPMoviePlayerController seek forward button stops the video in IOS7? - ios

I am facing an issue with MPMoviePlayerController in iOS 7. When i single tap on the forward seek button the video stops and not allow to do anything like to play again full screen and slider change.
Here is my code.
remove the Observer for the MPMoviePlayerPlaybackDidFinishNotification
[[NSNotificationCenter defaultCenter] removeObserver:moviePlayerViewController name:MPMoviePlayerPlaybackDidFinishNotification object:moviePlayerViewController.moviePlayer];
and add New Notification MPMoviePlayerPlaybackDidFinishNotification
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(videoFinished:) name:MPMoviePlayerPlaybackDidFinishNotification object:nil];
Here is my custom method to handle the MPMoviePlayerPlaybackDidFinishNotification
-(void)videoFinished:(NSNotification*)aNotification{
MPMoviePlayerController *moviePlayer = [aNotification object];
NSLog(#"%f",moviePlayer.currentPlaybackTime);
int reason = [[[aNotification userInfo] valueForKey:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey] intValue];
if (reason == MPMovieFinishReasonPlaybackEnded) {
}else if (reason == MPMovieFinishReasonUserExited) {
[self performSelector:#selector(dismiss:) withObject:aNotification afterDelay:0.5];
}else if (reason == MPMovieFinishReasonPlaybackError) {
}
}
I need to stop this strange behaviour on single click and continue to play.
Anyone know how to do this?
Thanks.

I think there are no any notifications or event are available on user
interaction with the standard player buttons, and i have to implement
own UI for the player controls. by this way we can then determine the
actions for a single touch, long touch, etc. Then, we can add whatever
functionality like increasing the play rate, or simply seeking to a
time.

Related

which player ios calls when play html video?

I have this website which plays videos, then my ios app shows this website on an UIWebview. My question is that when ios plays video from this website, which player does ios use? I want to know the answer to this question because I want to get pause notification from the player, so I want to know which kind of notification to use. Thanks
Definitely when iOS plays a video from a website page using native controller, it most probably seems to be a Native iOS player that we can show using MPMoviePlayViewController .
The reason seems to be the VOD or streaming video service must be following Apple's guideline for HLS.
Here is code to listen to StateChange notification
MPMoviePlaybackState
Constants describing the current playback state of the movie player.
enum {
MPMoviePlaybackStateStopped,
MPMoviePlaybackStatePlaying,
MPMoviePlaybackStatePaused,
MPMoviePlaybackStateInterrupted,
MPMoviePlaybackStateSeekingForward,
MPMoviePlaybackStateSeekingBackward
};
typedef NSInteger MPMoviePlaybackState;
Register for the MPMoviePlayerPlaybackStateDidChangeNotification
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(MPMoviePlayerPlaybackStateDidChange:)
name:MPMoviePlayerPlaybackStateDidChangeNotification
object:nil];
//Check in this function MPMoviePlaybackState
(void)MPMoviePlayerPlaybackStateDidChange:(NSNotification *)notification
{
if (player.playbackState == MPMoviePlaybackStatePlaying)
{ //playing
}
if (player.playbackState == MPMoviePlaybackStateStopped)
{ //stopped
}if (player.playbackState == MPMoviePlaybackStatePaused)
{ //paused
}if (player.playbackState == MPMoviePlaybackStateInterrupted)
{ //interrupted
}if (player.playbackState == MPMoviePlaybackStateSeekingForward)
{ //seeking forward
}if (player.playbackState == MPMoviePlaybackStateSeekingBackward)
{ //seeking backward
}
}
Remove notification by
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:nil];
Refer :MPMoviePlaybackState

MPMoviePlayerController stop/freezes video when beginSeekingForward is pressed only on iOS 8+

I am using the MPMoviePlayerController to play some streaming videos of type .m3u from a url. They video player launches perfectly and the video starts playing perfectly as well, but as soon as I press the Seek Forward or Next or beginSeekingForward button the video complete stops/freezes. After that I can click Done to dismiss the player or scrub the progress bar and it will come back to play to video. But the I can't click on the play/pause or at least seems not to do anything.
I have spent quite sometime looking around online for answer or at least a hint so I can tackle this issue in the right direction but not luck. So, I really hope someone could help with this. Btw, this only happens on iOS 8+, currently I am testing it in iOS 8.1.
This is how I create the player and load the video to it.
NSURL *videoURL = [NSURL URLWithString:self.video.flvurl];
self.moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL: videoURL];
self.moviePlayer.controlStyle = MPMovieControlStyleFullscreen;
self.moviePlayer.movieSourceType = MPMovieSourceTypeStreaming;
self.moviePlayer.shouldAutoplay = NO;
self.moviePlayer.fullscreen = YES;
self.moviePlayer.repeatMode = YES;
self.moviePlayer.view.backgroundColor = [UIColor blackColor];
self.moviePlayer.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
self.moviePlayer.view.frame = self.containerView.frame;
[self.view addSubview:self.moviePlayer.view];
[self.moviePlayer prepareToPlay];
[self.moviePlayer play];
I have tried using multiple different notifications to see if I can catch this within one of them, but not luck at all. I have tested all of these notifications so far.. I have added this to the self.moviePlayer and also the self.moviePlayer.view not luck in either of them.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(willResignActive:)
name:UIApplicationWillResignActiveNotification
object:self.moviePlayer.view];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(videoPlaybackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:self.moviePlayer.view];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(videoStartedPlaying:)
name:MPMoviePlayerNowPlayingMovieDidChangeNotification
object:self.moviePlayer.view];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(videoLoadState:)
name:MPMoviePlayerLoadStateDidChangeNotification
object:self.moviePlayer.view];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(videoPlaybackState:)
name:MPMoviePlayerPlaybackStateDidChangeNotification
object:self.moviePlayer.view];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(videoPlaybackUserInfoKey:)
name:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey
object:self.moviePlayer.view];
Well, if you need more relevant code please let me know. I really need some help with this.. Thanks in advance.
This code worked for me, but just to get rid of freezing. Sign up for the MPMoviePlayerLoadStateDidChangeNotification, like you did above. In the callback method, I simply set the movie players contentURL to the original URL I had initialized it with at the start, and set the movie player to play again.
The functionality of this is when you tap the NEXT or BACK buttons in fullscreen, the video simply starts playing again from the start. That may not be ideal since the user might not expect this, but at least it will stop it from freezing. I'm currently trying to find a better workaround.
- (void) videoLoadState:(NSNotification *)notification
{
MPMovieLoadState loadState = moviePlayer.loadState;
if(loadState == MPMovieLoadStateUnknown)
{
NSLog(#"Movie Load state is unknown");
moviePlayer.contentURL = currentlyPlayingVideoURL;
[moviePlayer prepareToPlay];
}
}
If you check the value of MPMoviePlaybackState in this method, it will always be MPMoviePlaybackStateStopped when NEXT or BACK are pressed, so I'm not sure how to handle it...

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.

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.

How to stop MPMoviePlayerViewController's automatic dismiss on moviePlaybackDidFinish?

An MPMoviePlayerViewController which is presented modally through presentMoviePlayerViewControllerAnimated: automatically dismisses itself when it's content finishes playing.
I've tried to disable this, since I want to play other content afterwards. However, even if I register to the NSNotificationCenter with [[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(movieFinishedCallback:) name:MPMoviePlayerPlaybackDidFinishNotification object:playerVC.moviePlayer]; and set some other content, it still dismisses.
How can I stop MPMoviePlayerViewController from automatically dismissing itself?
UPDATE:
As a clarification, this question is only about removing the automatic dismissal and not about dealing with the disabled 'done' button. The selected answer reflects. This is by design, since we assume the developer adds their own means of dismissing the MPMoviePlayerViewController. However, #bickster's answer deals with the 'done' button as well.
Thanks to this blog article I figured out that MPMoviePlayerViewController automatically registers itself to the NSNotificationCenter upon creation. You have to first remove this registration and it will stop dismissing itself automatically.
// Initialize the movie player view controller with a video URL string
MPMoviePlayerViewController *playerVC = [[[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL URLWithString:aVideoUrl]] autorelease];
// Remove the movie player view controller from the "playback did finish" notification observers
[[NSNotificationCenter defaultCenter] removeObserver:playerVC name:MPMoviePlayerPlaybackDidFinishNotification object:playerVC.moviePlayer];
You can use this code to stop the viewcontroller from automatically dismissing and capture the event when the user clicks the "Done" button so you can dismiss the viewcontroller yourself.
Step 1. - alloc a MPMoviePlayerViewController
videoPlayer = [[MPMoviePlayerViewController alloc] initWithContentURL:[[NSURL alloc ]initWithString:[aURL];
Step 2. - Remove the default MPMoviePlayerPlaybackDidFinishNotification observer and add your own
[[NSNotificationCenter defaultCenter] removeObserver:videoPlayer
name:MPMoviePlayerPlaybackDidFinishNotification object:videoPlayer.moviePlayer];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(videoFinished:) name:MPMoviePlayerPlaybackDidFinishNotification object:videoPlayer.moviePlayer];
Step 3. - Present viewcontroler
[self presentMoviePlayerViewControllerAnimated:videoPlayer];
Step 4. - Add videoFinish: method
-(void)videoFinished:(NSNotification*)aNotification{
int value = [[aNotification.userInfo valueForKey:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey] intValue];
if (value == MPMovieFinishReasonUserExited) {
[self dismissMoviePlayerViewControllerAnimated];
}
}
You can try something like this.
when the mpmovieplayercontroller finishes playing a video and you recieve the notification in your method movieFinishedCallback: implemect
[playerVC.movieplayer setContentURL:// set the url of the file you want to play here];
[playerVC.moviePlayer play];
Hope this helps
Since "Done" button is not working anymore if I remove MPMoviePlayerPlaybackDidFinishNotification from NSNotificationCenter, I change repeat mode to MPMovieRepeatModeOne.
Then, everything's working fine except the video is repeated.
MPMoviePlayerViewController *playerVC = [[[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL URLWithString:aVideoUrl]] autorelease];
[playerVC.moviePlayer setRepeatMode:MPMovieRepeatModeOne];

Resources