MPMoviePlayerController and let the user replay - objective-c

I have an iOS app with a MPMoviePlayerController, I need to play a video from an URL. Everything seems to work fine, but when the playback ends the MPMoviePlayerController shows a weird image and it takes AGES to replay the video...
This is what I have so far:
mp = [[MPMoviePlayerController alloc] initWithContentURL:movieURL];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayerLoadStateChanged:)
name:MPMoviePlayerLoadStateDidChangeNotification
object:nil];
And the moviePlayerLoadStateChanged and moviePlayBackDidFinish look like this:
- (void) moviePlayerLoadStateChanged:(NSNotification*)notification
{
if ([mp loadState] != MPMovieLoadStateUnknown)
{
[[NSNotificationCenter defaultCenter]removeObserver:self
name:MPMoviePlayerLoadStateDidChangeNotification
object:nil];
[mp setControlStyle:MPMovieControlStyleEmbedded];
[mp setFullscreen:NO];
[mp.view setFrame:CGRectMake(10, 54, 300, 200)];
[mp setShouldAutoplay:NO];
[mp prepareToPlay];
[[self view] addSubview:[self.mp view]];
}
}
I don't know what that Image is, but I would like to replace it... also I think it takes so much because it's loading the video from a URL, I don't know how to add a loading, or a spinner... Any idea?

You could set the repeatMode property of your MPMoviePlayerController to MPMovieRepeatModeOne
by using:
mp = [[MPMoviePlayerViewController alloc]
initWithContentURL:[NSURL fileURLWithPath:path]];///Put your path to your resource
mp.moviePlayer.repeatMode = MPMovieRepeatModeOne;
I hope this helps if i understood your question correctly.
If not i recommend checking out the documentation HERE
Happy coding:)

Related

Objective C : How to Insert text in Movie Player View?

I am making a Apache Cordova Application.
On this Application, I used the plugin : Cordova Streaming Media plugin
Link is : https://github.com/nchutchind/Streaming-Media-Cordova-Plugin
I want to insert a "Hello World!" label on my movie but I don't know how to do that.
I think the script is : StreamingMedia.m
Link is : https://github.com/nchutchind/Streaming-Media-Cordova-Plugin/blob/master/src/ios/StreamingMedia.m
And function is : startPlayer()
Can you tell me where is my error :
-(void)startPlayer:(NSString*)uri {
NSURL *url = [NSURL URLWithString:uri];
moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:url];
// Listen for playback finishing
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayBackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:moviePlayer];
// Listen for click on the "Done" button
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(doneButtonClick:)
name:MPMoviePlayerWillExitFullscreenNotification
object:nil];
// Listen for orientation change
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification
object:nil];
moviePlayer.controlStyle = MPMovieControlStyleDefault;
moviePlayer.shouldAutoplay = YES;
if (imageView != nil) {
[moviePlayer.backgroundView setAutoresizesSubviews:YES];
[moviePlayer.backgroundView addSubview:imageView];
}
moviePlayer.backgroundView.backgroundColor = backgroundColor;
[self.viewController.view addSubview:moviePlayer.view];
// Note: animating does a fade to black, which may not match background color
[moviePlayer setFullscreen:YES animated:NO];
// Here my code :
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 100, 0, 0)];
label.text = #"Hello World!";
CGRect frame = label.frame;
frame.origin.x = 100;
frame.origin.y = 50;
label.frame = frame;
[self.viewController.view addSubview:label];
}
Thank You!
You have two choices:
You can add a view to the app window/root controller view.
Create custom controller and add to his view MPMoviePlayerController like
subView.
Errors:
Your UILabel has 0x0 sizes. Just set up sizes :)
You send _rangeSlider to back of view via sendSubviewToBack. Remove it and it's start working.
And it seems you can just add subview to the MPMoviePlayerController view.

EXC_BAD_ACCESS when movie played the second time

I am using mpmovieplayercontroller to play a movie in my game. When the user taps the screen I run a method that replaces the current layer containing the movie with the game main menu. It works fine the first time, but when I try to play the video the second time from the main menu I get an EXC_BAD_ACCESS error on the line
int retVal = UIApplicationMain(argc, argv, nil, #"AppController");
in the main.m.
Please find the relevant code below.
-(void)playVideo {
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"movie" ofType:#"mp4"]];
moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:url];
moviePlayer.repeatMode = MPMovieRepeatModeOne;
// Register to receive a notification when the movie has finished playing.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayBackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:moviePlayer];
if ([moviePlayer respondsToSelector:#selector(setFullscreen:animated:)]) {
// Use the new 3.2 style API
moviePlayer.controlStyle = MPMovieControlStyleNone;
moviePlayer.shouldAutoplay = YES;
// This does blows up in cocos2d, so we'll resize manually
[moviePlayer setFullscreen:YES animated:YES];
CGSize winSize = [[CCDirector sharedDirector] winSize];
moviePlayer.view.frame = CGRectMake(0, 0, winSize.width, winSize.height); //width and height are swapped after rotation
[[[CCDirector sharedDirector] view] addSubview:moviePlayer.view ];
[moviePlayer play];
UITapGestureRecognizer * tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTap:)];
tapGestureRecognizer.delegate = (id)self;
tapGestureRecognizer.numberOfTapsRequired = 1;
[[[CCDirector sharedDirector] view] addGestureRecognizer:tapGestureRecognizer];
[tapGestureRecognizer release];
} else {
// Use the old 2.0 style API
moviePlayer.controlStyle = MPMovieControlStyleNone;
[moviePlayer play];
}
}
- (void)handleTap:(UITapGestureRecognizer *)gesture {
[moviePlayer stop];
[[MenuManager sharedMenuManager] runMenu:kMMenuLayer];
}
// this enables you to handle multiple recognizers on single view
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
-(void)moviePlayBackDidFinish:(NSNotification*)notification {
moviePlayer = [notification object];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:moviePlayer];
// If the moviePlayer.view was added to the openGL view, it needs to be removed
if ([moviePlayer respondsToSelector:#selector(setFullscreen:animated:)]) {
[moviePlayer.view removeFromSuperview];
CCLOG(#"this block is okay");
}
[moviePlayer release];
}
Please help.
The reason why you're getting the message is sent to a deallocated instance is because you've not removed the tapGestureRecognizer from the view. I believe your MenuManager singleton replaces the current layer with another, but since the tapGestureRecognizer is still part of the view it will try to access the handleTap, which by this time is deallocated. Add the following line before singleton call in handleTap.
[[[CCDirector sharedDirector] view] removeGestureRecognizer:tapGestureRecognizer];

disable user interaction in MPMoviePlayerController

I need to disable total user interaction during a play of a litle video, i already tried to set the style of the control to none : MPMovieControlStyleNone, and put a UIView above the MPMoviePlayerController, but when i pinch the video disappears, and the sound still playing, like i dismissed the video, but it still playing on the background, plus the user interaction is disabled.
Heres how i do:
-(IBAction)startGame:(id)sender
{
NSURL * url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"Teste" ofType:#"m4v"]];
moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:url];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayBackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:moviePlayer];
moviePlayer.controlStyle = MPMovieControlStyleNone;
moviePlayer.shouldAutoplay = YES;
[self.view addSubview:moviePlayer.view];
[moviePlayer setFullscreen:YES animated:YES];
mBlankView = [[UIView alloc] initWithFrame:moviePlayer.view.frame];
mBlankView.userInteractionEnabled = NO;
[mBlankView setMultipleTouchEnabled:NO];
[mBlankView setBackgroundColor:[UIColor clearColor]];
[self.view addSubview:mBlankView];
}
To disable Movieplayer control completely u need to disable your movieplayers view userinteraction as follows:
moviePlayer.view.userInteractionEnabled = NO;

Can not play video from URL in iPhone app?

I'm having a problem playing the video from URL-based. This is my code:
-(void)clickplay
{
NSURL *fileURL = [NSURL URLWithString:#"http://km.support.apple.com/library/APPLE/APPLECARE_ALLGEOS/HT1211/sample_iTunes.mov"];
MPMoviePlayerController *moviePlayerController = [[MPMoviePlayerController alloc]initWithContentURL:fileURL];
[moviePlayerController.view setFrame:CGRectMake(0, 70, 320, 270)];
[self.view addSubview:moviePlayerController.view];
moviePlayerController.fullscreen = YES;
[moviePlayerController play];
}
It compiles successfully and the player did pop out but it just keeps loading forever... I have tried changing the URL several times to no effect. Can anyone please help me to solve this problem?
You'll need to retain a reference to the moviePlayerController. It's getting released and preventing any delegated messages from being invoked. Probably the easiest place to put it is in the class that contains the - (void)clickplay implementation. That is, add a new instance variable called moviePlayerController and assign it the newly created MPMoviePlayerController object in clickplay.
videoURL=[NSURL URLWithString:URL]];
videoPlayer = [[MPMoviePlayerController alloc] initWithContentURL:videoURL];
videoPlayer.view.frame = CGRectMake(0,0, 320, 480);
[videoPlayer prepareToPlay];
[self.view addSubview:videoPlayer.view];
[videoPlayer play];
videoPlayer.movieControlMode = MPMovieControlModeHidden;
// Register to receive a notification when the movie has finished playing.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayBackComplete:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:videoPlayer];
/* configuring notification*/
- (void)moviePlayBackComplete:(NSNotification *)notification
{
[videoPlayer stop];
}
This my answer in regards with playing .3gp file with iPhone .....I have successfully played .3gp file with iphone sdk with using MpMoviePlayerController and my answer link is:
Link: https://stackoverflow.com/a/13088808/1092219
hope you will got help from my answer.........!! :))))))

Disappearing status bar at the top after MPMoviePlayerController is closed

Having an interesting little problem with my iPhone app. I have a view with a table and each cell, when clicked, plays a video fullscreen then when you press done, the video stops and goes back to the table view. The only problem is, when you press done within the first 2 or 3 seconds of the video loading, when the view goes back to the table view, the bar at the top of the screen that tells the time and battery strength etc is no longer there, its just a white space. But if you press done after the first few seconds, then when you go back to the table view, everything is absolutely fine! I have absolutely no idea why this is happening and the only thing I found on the internet is this which is some guy with pretty much exactly the same problem as me:
http://www.iphonedevsdk.com/forum/iphone-sdk-development/53020-disappearing-status-bar.html
This lead me to try using:
[UIApplication sharedApplication].statusBarHidden = NO;
However this lead nowhere either.
The code that is executed when they click on a video:
NSString *path = [[NSBundle mainBundle] pathForResource:currentTitle ofType:#"m4v"];
NSURL *url = [NSURL fileURLWithPath:path];
movieController = [[MPMoviePlayerController alloc] initWithContentURL:url];
[movieController setControlStyle:MPMovieControlStyleFullscreen];
[movieController setFullscreen:YES];
movieController.view.frame = self.view.bounds;
[self.view addSubview:movieController.view];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(playbackFinished:) name:MPMoviePlayerPlaybackDidFinishNotification object:nil];
And the code that executes either when the video is done or when the user clicks done is:
NSLog(#"movieController moviePlayBackDidFinish");
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:nil];
[movieController setFullscreen:NO animated:NO];
[movieController.view removeFromSuperview];
[movieController release];
LiveEventsView *liveEventsView = [[LiveEventsView alloc] initWithNibName:#"LiveEventsView" bundle:nil];
UIView *currentView = self.view;
UIView *theWindow = [currentView superview];
UIView *newView = liveEventsView.view;
newView.frame = CGRectMake(0, 20, 320, 460);
[currentView removeFromSuperview];
[theWindow addSubview:newView];
[UIApplication sharedApplication].statusBarHidden = NO;
If anybody can shed any light on this situation, I would be very grateful as it is extremely frustrating!
Thanks,
Matt
Maybe the animation from when the video view disappears is causing a timing issue with the status bar animation.
try delaying the statusBarHidden = NO call by a few seconds.
NSInteger delay = 3;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, delay * NSEC_PER_SEC), dispatch_get_current_queue(), ^{
[UIApplication sharedApplication].statusBarHidden = NO;
});
You can just set the delay to be a float instead. So it would be
float delay = 0.1;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, delay * NSEC_PER_SEC), dispatch_get_current_queue(), ^{
[UIApplication sharedApplication].statusBarHidden = NO;
[UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleBlackOpaque;
});
I had the same problem and solved it by modifying richerd's code a bit. 0.1 second is acceptable imo. I also had to change the status bar style since it returned a BlackTranslucent bar style and the original was BlackOpaque style. But works fine now.
I've found that with the given solutions the content often disappears beneath the status bar. This approach fixes it.
Register for MPMoviePlayerWillExitFullscreenNotification
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayerWillExitFullscreen:)
name:MPMoviePlayerWillExitFullscreenNotification
object:self.moviePlayer];
And then reset the status bar visibility AND remove and re-add the rootViewController from the main window, this will make sure that the bounds of the view are correct again.
- (void)moviePlayerWillExitFullscreen:(NSNotification *)notification {
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationSlide];
AppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
id rootViewController = appDelegate.window.rootViewController;
appDelegate.window.rootViewController = nil;
appDelegate.window.rootViewController = rootViewController;
}