I try to get a MPMoviePlayerController to work, but have a strange problem. When playing I click the done button and there seems an infinite look triggered:
2012-02-13 15:18:04.395 iDomsPortalDev[7376:12203] playbackFinished.
Reason: User Exited 2012-02-13 15:18:04.395 iDomsPortalDev[7376:12203]
playbackFinished. Reason: User Exited 2012-02-13 15:18:04.395
iDomsPortalDev[7376:12203] playbackFinished. Reason: User Exited
I use the following notifications on starting:
- (void) showMoviePlayer {
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(willEnterFullscreen:) name:MPMoviePlayerWillEnterFullscreenNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(willExitFullscreen:) name:MPMoviePlayerWillExitFullscreenNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(enteredFullscreen:) name:MPMoviePlayerDidEnterFullscreenNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(exitedFullscreen:) name:MPMoviePlayerDidExitFullscreenNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(playbackFinished:) name:MPMoviePlayerPlaybackDidFinishNotification object:nil];
id appDelegate = (iDomsAppDelegate *)[[UIApplication sharedApplication] delegate];
//[[self navigationController] presentMoviePlayerViewControllerAnimated:[appDelegate movieController]];
[[appDelegate moviePlayer].view setFrame: self.view.bounds];
[self.view addSubview:[appDelegate moviePlayer].view];
[[appDelegate moviePlayer] setFullscreen:YES animated:YES];
}
and the following listeners:
#pragma mark - Movieplayer feedback
- (void)willEnterFullscreen:(NSNotification*)notification {
NSLog(#"willEnterFullscreen");
}
- (void)enteredFullscreen:(NSNotification*)notification {
NSLog(#"enteredFullscreen");
}
- (void)willExitFullscreen:(NSNotification*)notification {
NSLog(#"willExitFullscreen");
}
- (void)exitedFullscreen:(NSNotification*)notification {
NSLog(#"exitedFullscreen");
iDomsAppDelegate *appDelegate = (iDomsAppDelegate *)[[UIApplication sharedApplication] delegate];
[[appDelegate moviePlayer].view removeFromSuperview];
[[appDelegate moviePlayer] release];
[appDelegate setMovieController:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)playbackFinished:(NSNotification*)notification {
iDomsAppDelegate *appDelegate = (iDomsAppDelegate *)[[UIApplication sharedApplication] delegate];
NSNumber* reason = [[notification userInfo] objectForKey:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey];
switch ([reason intValue]) {
case MPMovieFinishReasonPlaybackEnded:
NSLog(#"playbackFinished. Reason: Playback Ended");
break;
case MPMovieFinishReasonPlaybackError:
NSLog(#"playbackFinished. Reason: Playback Error");
break;
case MPMovieFinishReasonUserExited:
NSLog(#"playbackFinished. Reason: User Exited");
break;
default:
break;
}
[[appDelegate moviePlayer] setFullscreen:NO animated:YES];
}
Only the PlayBackFinished selector is called (infinite times), so there must be something stupid I do (running in the simulator with iOS5)
I found the problem, it seemed to have been setting the fullscreen option which caused it:
[[appDelegate moviePlayer] setFullscreen:YES animated:YES];
Related
This is my AlertView code :
- (void)initializeAlertControllerForOneButtonWithTitle:(NSString *)title withMessage:(NSString *)msg withYesButtonTitle:(NSString *)yesButtonTitle withYesButtonAction:(id)yesButtonAction
{
UIAlertController * alert = [UIAlertController
alertControllerWithTitle:title
message:msg
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* yesBtn = [UIAlertAction
actionWithTitle:yesButtonTitle
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
if (self.activityIndicator.animating) {
[self.activityIndicator stopAnimating];
}
if ([title isEqualToString:#"Wrong Password!"]) {
self.editTextField.text = #"";
[self.editTextField becomeFirstResponder];
}
}];
[alert addAction:yesBtn];
[self presentViewController:alert animated:YES completion:nil];
}
I am trying to fire this alert in my NSNotificatoin Response method. My Notification Response code :
- (void)receiveSMSVerificationResponse:(NSNotification *)notification
{
SMSVerificationDigitClassModel *smsVerificationDigitClassModel = [[SMSVerificationDigitClassModel alloc] init];
smsVerificationDigitClassModel = [notification object];
if (smsVerificationDigitClassModel.viewControllerName == ViewControllerNameProfileInfoEditViewController) {
if ([self alreadyRegisteredPhoneNumber:smsVerificationDigitClassModel.phoneNumber] == YES) {
NSLog(#"jogajog");
[self initializeAlertControllerForOneButtonWithTitle:#"Already Registered!" withMessage:kAlreadyRegisteredPhoneNumberMSGForChangePhoneNumber withYesButtonTitle:#"Ok" withYesButtonAction:nil];
} else {
if ([AdditionalClasses internetConnectionCheck] == YES) {
self.userModelClass.phone_number = smsVerificationDigitClassModel.phoneNumber;
[self updateUserModel:self.userModelClass];
} else {
[self noInternetConnectionAlert];
}
}
//Check if that phone number is already used
// udate phone numner in server
// update phone number in core data
//[self goToSignUpViewControllerWithPhoneNumber:smsVerificationDigitClassModel.phoneNumber];
}
}
I check it from break point, this line [self initializeAlertControllerForOneButtonWithTitle:#"Already Registered!" withMessage:kAlreadyRegisteredPhoneNumberMSGForChangePhoneNumber withYesButtonTitle:#"Ok" withYesButtonAction:nil]; is actually calling, but the alert view is not popping up. It says:
"Warning: Attempt to present on whose view is not in the window hierarchy!"
I have tried to add notification observer methods :
- (void)addNotificationObserver
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(receiveUserModelResponse:) name:#"sendUpdateRequestToServerForPhoneNumberWithUserModel" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(receiveSMSVerificationResponse:) name:#"SMSVerificationForPhoneNumber" object:nil];
}
In viewDidLoad, viewDidAppear & in viewWillAppear and removeObserver in dealloc,
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"sendUpdateRequestToServerForPhoneNumberWithUserModel" object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"SMSVerificationForPhoneNumber" object:nil];
}
but it is not showing at all. So, how do I change my window hierarchy! in this viewController. If you understand, please reply back. A lot of thanks in advance.
Call the initializeAlertControllerForOneButtonWithTitle method inside a main queue dispatch queue block.
All UI operation should be on main threat.
dispatch_async(dispatch_get_main_queue(), ^{
[self initializeAlertControllerForOneButtonWithTitle:#"Already Registered!" withMessage:kAlreadyRegisteredPhoneNumberMSGForChangePhoneNumber withYesButtonTitle:#"Ok" withYesButtonAction:nil];
});
In iOS 7, if i want to get UIWebView QuickTime "Done" event.
I can use NSNotification to get it.
This is my code.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(playerWillExitFullscreen:)
name:#"UIMoviePlayerControllerWillExitFullscreenNotification"
object:nil];
[_videoWebView loadRequest:[NSURLRequest requestWithURL:_contentURL]];
And use this function, i can get Done event in UIWebView.
- (void)playerWillExitFullscreen:(NSNotification *)notification
But in iOS 8, the notification is not work...(The notification name is hidden solution in iOS 7.)
So how can i get it(Done event) in iOS8 ?
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(youTubeStarted:) name:UIWindowDidBecomeVisibleNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(youTubeFinished:) name:UIWindowDidBecomeHiddenNotification object:nil];
-(void)youTubeStarted:(NSNotification *)notification
{
// Entered Fullscreen code goes here..
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
appDelegate.fullScreenVideoIsPlaying = YES;
NSLog(#"%f %f",webViewForWebSite.frame.origin.x,webViewForWebSite.frame.origin.y);
}
-(void)youTubeFinished:(NSNotification *)notification{
// Left fullscreen code goes here...
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
appDelegate.fullScreenVideoIsPlaying = NO;
//CODE BELOW FORCES APP BACK TO PORTRAIT ORIENTATION ONCE YOU LEAVE VIDEO.
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];
//present/dismiss viewcontroller in order to activate rotating.
UIViewController *mVC = [[UIViewController alloc] init];
[self presentViewController:mVC animated:NO completion:Nil];
// [self presentModalViewController:mVC animated:NO];
[self dismissViewControllerAnimated:NO completion:Nil];
// [self dismissModalViewControllerAnimated:NO];
}
I'm trying to get a movie that plays to dismiss on its own without having to hit the "Done" button. I think it's a recent iOS 6 problem since I'm following a tutorial exactly and when I insert NSLogs the NSNotification and removeFromSuperview are being recognized but the movie stays there once it has ended. Here's my code, please help:
- (IBAction)playMovie:(id)sender
{
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle]
pathForResource:#"RomneyFlipSequence1" ofType:#"mov"]];
_moviePlayer =
[[MPMoviePlayerController alloc]
initWithContentURL:url];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayBackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:_moviePlayer];
_moviePlayer.controlStyle = MPMovieControlStyleDefault;
_moviePlayer.shouldAutoplay = YES;
[self.view addSubview:_moviePlayer.view];
[_moviePlayer setFullscreen:YES animated:NO];
}
- (void) moviePlayBackDidFinish:(NSNotification*)notification {
MPMoviePlayerController *player = [notification object];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:player];
if ([player
respondsToSelector:#selector(setFullscreen:animated:)])
{
[player.view removeFromSuperview];
}
}
#end
You entered the player into fullscreen mode.
[_moviePlayer setFullscreen:YES animated:NO];
Reading other solutions in SO it seems that when you press "Done" the player is taken out of fullscreen first, and then the notification is thrown. After reading this answer, adding
[_moviePlayer setFullscreen:NO animated:YES];
before your removeFromSuperview call will solve your problem.
If the above doesn't work, in addition you may try stoping the player first so the full code will be
-(void)removePlayer:(MPMoviePlayerController *)player{
NSLog(#"Playback Finished");
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:_moviePlayer];
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerDidExitFullscreenNotification object:_moviePlayer];
[_moviePlayer stop]; // <-- May not be needed
if ([_moviePlayer respondsToSelector:#selector(setFullscreen:animated:)])
{
[_moviePlayer setFullscreen:NO animated:YES];
[_moviePlayer.view removeFromSuperview];
}
_moviePlayer=nil;
}
I use the same method for both notifications "Done" and "PlayBackFinished"
Hope this helps.
You had added _moviePlayer.view as a view and you are trying to remove player.view
i think this will do it :
- (void) moviePlayBackDidFinish:(NSNotification*)notification {
MPMoviePlayerController *player = [notification object];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:player];
if ([player
respondsToSelector:#selector(setFullscreen:animated:)])
{
[_moviePlayer.view removeFromSuperview];
}
}
In one of my apps i want to play a video file from local.so iam using the below code for playing the file.
-(IBAction)playMovie{
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle]pathForResource:#"Myvideo" ofType:#"mov"]];
MPMoviePlayerController *moviePlayer=[[[MPMoviePlayerController alloc]initWithContentURL:url]autorelease];
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(moviePlayBackDidFinish:) name:MPMoviePlayerPlaybackDidFinishNotification object:moviePlayer];
moviePlayer.controlStyle = MPMovieControlStyleEmbedded;
moviePlayer.shouldAutoplay = YES;
[self.view addSubview:moviePlayer.view];
[moviePlayer setFullscreen:YES animated:YES];
//[moviePlayer release];
}
-(void) moviePlayBackDidFinish:(NSNotification*)notification {
MPMoviePlayerController *moviePlayer = [notification object];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:moviePlayer];
if ([moviePlayer
respondsToSelector:#selector(setFullscreen:animated:)])
{
[moviePlayer.view removeFromSuperview];
}
[moviePlayer release];
}
when i go to analyse or do profile for the above code there shows a warning potential leak happening at 2 places i.e,
[moviePlayer setFullscreen:YES animated:YES];
//[moviePlayer release];
one more is leak is at this part
{
[moviePlayer.view removeFromSuperview];
}
[moviePlayer release]
so how to avoid this memory leak.Even i tried giving autorelease the NSURL Line in the begining of the code,when i do autorelease leak wont happen but video wont play.so how to solve this issue can anyone help??
try this in moviePlayBackDidFinish method, may be it will help
if (videoPlayer) {
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification object:videoPlayer];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerLoadStateDidChangeNotification object:videoPlayer];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMovieMediaTypesAvailableNotification object:videoPlayer];
[videoPlayer pause];
videoPlayer.initialPlaybackTime = -1;
[videoPlayer stop];
[videoPlayer.view removeFromSuperview];
[videoPlayer release];
videoPlayer = nil;
}
When my app goes to background and back, modal view closes. Why is this happend? I tried with pause on and off. I have ARC enabled, if it is a useful info.
MPMoviePlayerViewController * player = [[MPMoviePlayerViewController alloc] initWithContentURL:targetURL];
[player.moviePlayer prepareToPlay];
[self presentMoviePlayerViewControllerAnimated:player];
In case anyone else stumbles across this (as I did before I found my own solution), I was able to prevent MPMoviePlayerViewController from exiting when the app backgrounds by subclassing it and removing it as an observer of UIApplicationDidEnterBackgroundNotification:
- (id)initWithContentURL:(NSURL *)contentURL {
self = [super initWithContentURL:contentURL];
if (self){
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidEnterBackgroundNotification object:nil];
}
return self;
}
You don't need to subclass MPMoviePlayerViewController - just do following after creating MPMoviePlayerViewController instance.
[[NSNotificationCenter defaultCenter] removeObserver:self.moviePlayerViewController name:UIApplicationDidEnterBackgroundNotification object:nil];
Here is full code that can help you
// Call this to start initialization and play movie
-(void)prepareMoviePlayer:(NSURL *)moviePath
{
moviePlayerViewController = [[MPMoviePlayerViewController alloc] initWithContentURL:moviePath];
if ([[moviePlayerViewController moviePlayer] respondsToSelector:#selector(loadState)])
{
[[moviePlayerViewController moviePlayer] setControlStyle:MPMovieControlStyleNone];
[[moviePlayerViewController moviePlayer] setFullscreen:YES];
[[moviePlayerViewController moviePlayer] prepareToPlay];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayerLoadStateDidChange:)
name:MPMoviePlayerLoadStateDidChangeNotification
object:nil];
}
}
- (void) addPlayer
{
[[[moviePlayerViewController moviePlayer] view] setFrame:self.view.bounds];
[[self view] addSubview:[[moviePlayerViewController moviePlayer] view]];
}
static NSTimeInterval t;
// Call this on applicationWillResignActive
-(void) pauseMovieInBackGround
{
[[moviePlayerViewController moviePlayer] pause];
t = [[moviePlayerViewController moviePlayer] currentPlaybackTime];
[moviePlayerViewController.view removeFromSuperview];
}
// Call this on applicationWillEnterForeground
-(void) resumeMovieInFrontGround
{
[self addPlayer];
[[moviePlayerViewController moviePlayer] stop];
[[moviePlayerViewController moviePlayer] setInitialPlaybackTime:t];
[[moviePlayerViewController moviePlayer] play];
}
-(void)moviePlayerLoadStateDidChange:(NSNotification *)notification
{
if([[moviePlayerViewController moviePlayer] loadState] != MPMovieLoadStateUnknown)
{
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerLoadStateDidChangeNotification
object:nil];
[self addPlayer];
[[moviePlayerViewController moviePlayer] play];
}
}
-(void)videoPlayBackDidFinish:(NSNotification*)notification
{
[self dismissMoviePlayerViewControllerAnimated];
}
I am coming across this issue.
I've tried ChrisH's answer, but it didn't work for me until I put removeObserver into viewDidLoad() instead of init().
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidEnterBackgroundNotification object:nil];
}
Then it works. Enjoy it.