I'm using the first answer from
iOS 4 + MPMoviePlayerController
to try and get MPMoviePlayerController to play. In the simulator (iPhone device with iOS4), I hear sound but no video. On the device (iPhone 3GS and iOS4), I don't get anything. Here's my code:
MPMoviePlayerController *moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL fileURLWithPath:moviePath]];
moviePlayer.movieControlMode = MPMovieControlModeDefault;
if ([moviePlayer respondsToSelector:#selector(view)]) {
moviePlayer.controlStyle = MPMovieControlStyleFullscreen;
[moviePlayer.view setFrame:self.view.bounds];
[self.view addSubview:moviePlayer.view];
}
[moviePlayer play];
Any ideas what I'm doing wrong?
I just tested the following code on iOS4 + iPhone 4 (and a 3GS)—it works fine. At first blush, I think your code's problem is not calling setFullscreen:animated on your MPMoviePlayerController instance.
- (void)willEnterFullscreen:(NSNotification*)notification {
NSLog(#"willEnterFullscreen");
}
- (void)enteredFullscreen:(NSNotification*)notification {
NSLog(#"enteredFullscreen");
}
- (void)willExitFullscreen:(NSNotification*)notification {
NSLog(#"willExitFullscreen");
}
- (void)exitedFullscreen:(NSNotification*)notification {
NSLog(#"exitedFullscreen");
[self.movieController.view removeFromSuperview];
self.movieController = nil;
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)playbackFinished:(NSNotification*)notification {
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;
}
[self.movieController setFullscreen:NO animated:YES];
}
- (void)showMovie {
[[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];
NSURL* movieURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"tron" ofType:#"mov"]];
self.movieController = [[MPMoviePlayerController alloc] initWithContentURL:movieURL];
if ([self.movieController respondsToSelector:#selector(view)]) {
self.movieController.view.frame = self.view.frame;
[self.view addSubview:movieController.view];
[self.movieController setFullscreen:YES animated:YES];
}
[self.movieController play];
}
// This method is set as the action for an on-screen button
- (void)movieTime:(id)sender {
[self showMovie];
}
For MPMoviePlayerController view is a property, not a method, so you can't use respondsToSelector: on it if it doesn't have methods synthesized or written for it (i.e. is declared #dynamic). Which I think is true for most readonly properties in UIKit.
Related
I’m creating my MPMoviePlayerViewController like so:
MPMoviePlayerViewController *playerView = [[MPMoviePlayerViewController alloc] initWithContentURL:videoURL];
[self presentMoviePlayerViewControllerAnimated:playerView];
It works fine until I press the home button: that way, after I reopen the app, the player view controller is gone and I’m seeing the view controller I originally called it from. The player doesn’t disappear but simply pauses (as it should) if I double-press the home button, opening the multitasking panel.
So how do I prevent this from happening (closing and reopening the app should bring me back to playing the video)?
UPD:
I noticed that the player doesn’t disappear if I close and reopen the app while the “Loading…” text is up. In that case, coming back to the app lets the player continue loading the video to eventually start playing. However closing the app after that (either when the video is playing or being paused) inevitably kills the player view controller…
Try like this:
MPMoviePlayerViewController *playerView = [[MPMoviePlayerViewController alloc] initWithContentURL:videoURL];
playerView.view.frame = self.view.frame;
[self presentMoviePlayerViewControllerAnimated:playerView];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(MPMoviePlayerDidExitFullscreen:) name:MPMoviePlayerDidExitFullscreenNotification object:nil];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(playbackStateChanged:)
name:MPMoviePlayerPlaybackStateDidChangeNotification
object:moviePlayerController];
[playerView.moviePlayer play];
after that adding these two methods:
- (void) movieFinishedCallback:(NSNotification*) aNotification
{
moviePlayerController = [aNotification object];
[moviePlayerController.moviePlayer stop];
[[NSNotificationCenter defaultCenter]
removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification
object:moviePlayerController];
[moviePlayerController autorelease];
NSLog(#"stopped?");
}
- (void)MPMoviePlayerDidExitFullscreen:(NSNotification *)notification
{
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerDidExitFullscreenNotification
object:nil];
[moviePlayerController.moviePlayer stop];
MPMoviePlayerController *player = [notification object];
[[NSNotificationCenter defaultCenter]
removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification
object:player];
[moviePlayerController dismissMoviePlayerViewControllerAnimated];
}
I found the answer here:
MPMoviePlayerViewController gets dismissed, when app resignes active state
The author of that question (and the answer) mentions however that his app was rejected for this.
you try this code---
- (void)willEnterFullscreen:(NSNotification*)notification {
NSLog(#"willEnterFullscreen");
}
- (void)enteredFullscreen:(NSNotification*)notification {
NSLog(#"enteredFullscreen");
}
- (void)willExitFullscreen:(NSNotification*)notification {
NSLog(#"willExitFullscreen");
}
- (void)exitedFullscreen:(NSNotification*)notification {
NSLog(#"exitedFullscreen");
[self.movieController.view removeFromSuperview];
self.movieController = nil;
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)playbackFinished:(NSNotification*)notification {
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;
}
[self.movieController setFullscreen:NO animated:YES];
}
- (void)showMovie {
[[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];
NSURL* movieURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"tron" ofType:#"mov"]];
self.movieController = [[MPMoviePlayerController alloc] initWithContentURL:movieURL];
self.movieController.view.frame = self.view.frame;
[self.view addSubview:movieController.view];
[self.movieController setFullscreen:YES animated:YES];
[self.movieController play];
}
MPMoviePlayerViewControllers dismiss when the app goes into the background, as Arnold stated, and can also dismiss when you leave the view controller view it's embedded in. To resolve both issues, try retaining the MPMoviePlayerViewController as an ivar or property and have it reset itself when the vc's viewWillAppear: is called or when the application re-enters the foreground, like:
- (void) viewDidLoad{
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(reset) name:UIApplicationWillEnterForegroundNotification object:nil];
}
- (void) viewWillAppear:(BOOL)animated{
[self reset];
}
- (void) reset{
[_mpmpvc.moviePlayer prepareToPlay];
[_mpmpvc.moviePlayer pause];
}
I am creating a MPMoviePlayerController object and streaming a video in full screen mode.
I am using a UIViewController to display the movie view.
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
//http://www.youtube.com/watch?feature=player_detailpage&v=ebeQaznNcmE
NSURL *url = [NSURL URLWithString:#"http://a1408.g.akamai.net/5/1408/1388/2005110405/1a1a1ad948be278cff2d96046ad90768d848b41947aa1986/sample_mpeg4.mp4"];
MPMoviePlayerController *mPlayer = [[MPMoviePlayerController alloc]initWithContentURL:url];
mPlayer.view.frame = gMainView.frame;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayBackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:mPlayer];
mPlayer.shouldAutoplay = YES;
mPlayer.controlStyle = MPMovieControlStyleFullscreen;
[gMainView addSubview:mPlayer.view];
[mPlayer prepareToPlay];
[mPlayer setFullscreen:YES animated:YES];
[mPlayer play];
}
- (void)moviePlayBackDidFinish:(NSNotification*)notification {
int reason = [[[notification userInfo] valueForKey:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey] intValue];
if (reason == MPMovieFinishReasonPlaybackEnded) {
//movie finished playing
}
else if (reason == MPMovieFinishReasonUserExited) {
//user hit the done button
MPMoviePlayerController *moviePlayer = [notification object];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:moviePlayer];
if ([moviePlayer respondsToSelector:#selector(setFullscreen:animated:)]) {
[moviePlayer.view removeFromSuperview];
}
[moviePlayer release];
}
else if (reason == MPMovieFinishReasonPlaybackError) {
//error
}
}
When clicking done, the video visual is removed from the screen, but the controls are not removed from the screen and the view is not removed from the screen.
The control does come to "//user hit the done button". It does execute the code to remove the view from superview, I checked by adding logs, but the controls are not removed from the screen and the view is not removed from the screen.
What am I doing wrong?
EDIT:
If I use MPMoviePlayerViewController then it doesn't even wait for me to press Done. Once the video is complete it automatically removes the view. But I don' want that.
EDIT:
If I remove "[mPlayer setFullscreen:YES animated:YES]" then when clicking on Done, the view is removed completely. But the video is not displayed in full screen and the status bar goes gray which is again what I don't want.
The below code worked for me, Hope it helps you too.
-(IBAction)playVedio:(id)sender{
mp = [[MPMoviePlayerViewController alloc] initWithContentURL:url];
[[mp moviePlayer] prepareToPlay];
[[mp moviePlayer] setUseApplicationAudioSession:NO];
[[mp moviePlayer] setShouldAutoplay:YES];
[[mp moviePlayer] setControlStyle:2];
[[mp moviePlayer] setRepeatMode:MPMovieRepeatModeOne];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(videoPlayBackDidFinish:) name:MPMoviePlayerPlaybackDidFinishNotification object:nil];
[self presentMoviePlayerViewControllerAnimated:mp];
}
-(void)videoPlayBackDidFinish:(NSNotification*)notification {
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:nil];
[mp.moviePlayer stop];
mp = nil;
[mp release];
[self dismissMoviePlayerViewControllerAnimated];
}
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
id presentedViewController = [window.rootViewController presentedViewController];
NSString *className = presentedViewController ? NSStringFromClass([presentedViewController class]) : nil;
if (window && [className isEqualToString:#"AVFullScreenViewController"]) {
return UIInterfaceOrientationMaskAll;
} else {
UIInterfaceOrientation interfaceOrientation = [UIApplication sharedApplication].statusBarOrientation;
if(UIInterfaceOrientationIsPortrait(interfaceOrientation))
{
}
else if(UIInterfaceOrientationIsLandscape(interfaceOrientation))
{
}
return UIInterfaceOrientationMaskPortrait;
CGRect frame = [UIScreen mainScreen].applicationFrame;
CGSize size = frame.size;
NSLog(#"%#", [NSString stringWithFormat:#"Rotation: %s [w=%f, h=%f]",
UIInterfaceOrientationIsPortrait(interfaceOrientation) ? "Portrait" : "Landscape",
size.width, size.height]);
}
}
I have problem with MPMoviePlayerViewController , when app enters background and then I launch it again or go another viewControllers the movie became black ! I have movie which plays in the background of my menus , here is my code :
EIDTED CODE :
-(void)viewDidLoad {
[self moviePlayer2];
}
- (void) moviePlayer2 {
NSString *path = [[NSBundle mainBundle] pathForResource:#"cloud" ofType:#"mp4"];
player = [[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL fileURLWithPath:path]];
player.view.userInteractionEnabled = YES;
player.moviePlayer.repeatMode = YES;
player.moviePlayer.scalingMode = MPMovieScalingModeFill;
player.moviePlayer.controlStyle = MPMovieControlStyleNone;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayBackStateChange:)
name:MPMoviePlayerPlaybackStateDidChangeNotification
object:[player moviePlayer]];
[[player moviePlayer] play];
[self.view addSubview:player.view];
}
-(void) moviePlayBackStateChange: (NSNotification *) note {
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackStateDidChangeNotification object:[player moviePlayer]];
[[player moviePlayer] play];
//[player release];
NSLog(#"FINISHED");
}
thank you .
I think you may need to add codes below:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayBackStateChange:)
name:MPMoviePlayerPlaybackStateDidChangeNotification
object:[player moviePlayer]];
and handle the movie state in the moviePlayBackStateChange method.
The movie will be paused when the movie is playing and the app enters in background, so you need to make the movie resume like below when the app come back from background. If not,the movie will keep the pause state. That's why your app becomes black.
[[player moviePlayer] play];
then the movie will continue to play.
adding two methods which you should invote when the app comes into background and backs from background:
-(void) pauseMovieInBackGround
{
[player moviePlayer] pause];
[player.view removeFromSuperview];
}
-(void) resumeMovieInFrontGround
{
[self.view addSubview:player.view];
[[player moviePlayer] play];
}
Hope this can help you guy.
Try changing this:
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:[player moviePlayer]];
[player release];
To this:
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:[player moviePlayer]];
[movieController.view removeFromSuperview];
[player release];
See if that works :D
I now have a strange problem when I try to play movie through MPMoviePlayerViewController on iOS 4.3.
It appears just a white screen and nothing happens. My code works well on iOS 4.2. So I created a new
OpenGLES project and just use my movie code, but it can not work either. So can anybody give some tips?
Thanks in advance.
My code is below:
//-------------------------------------TestViewController.h---------------------------------------
#import <MediaPlayer/MediaPlayer.h>
#interface TestViewController : UIViewController
{
bool _isMovieEnded;
MPMoviePlayerViewController* _theMovie;
}
- (void)playMovie:(NSString*)filename;
- (void)movieFinishedCallback:(NSNotification*)aNotification;
- (bool)isMovieEnd;
//-------------------------------------TestViewController.m---------------------------------------
- (void)playMovie:(NSString*)filename
{
NSURL* theURL = [NSURL fileURLWithPath:filename];
_theMovie = [[MPMoviePlayerViewController alloc] init];// initWithContentURL:theURL];
[_theMovie.moviePlayer setContentURL:theURL];
_theMovie.moviePlayer.scalingMode = MPMovieScalingModeAspectFill;
[_theMovie.moviePlayer setControlStyle:MPMovieControlStyleNone];
[_theMovie.moviePlayer setFullscreen:YES];
// register notification
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(movieFinishedCallback:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:_theMovie];
[[UIApplication sharedApplication] beginIgnoringInteractionEvents];
[_theMovie.moviePlayer play];
[self.view addSubview:_theMovie.view];
}
- (void)movieFinishedCallback:(NSNotification*)aNotification
{
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:_theMovie];
// release movie
[_theMovie.view removeFromSuperview];
[_theMovie release];
_isMovieEnded = true;
[self startAnimation];
[[UIApplication sharedApplication] endIgnoringInteractionEvents];
}
- (bool)isMovieEnd
{
return _isMovieEnded;
}
//-------------------------------------TestAppDelegate.m---------------------------------------
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
[self.window addSubview:self.viewController.view];
NSString* movieFile = [[NSBundle mainBundle] pathForResource:#"logo" ofType:#"mp4"];
[viewController playMovie:movieFile];
[viewController stopAnimation];
return YES;
}
// Determines if the movie is presented in the entire screen (obscuring all other application content). Default is NO.
// Setting this property to YES before the movie player's view is visible will have no effect.
#property(nonatomic, getter=isFullscreen) BOOL fullscreen;
- (void)setFullscreen:(BOOL)fullscreen animated:(BOOL)animated;
From MPMoviePlayerController.h
so here you are the code:
- (void)playVideoFromUrl:(NSString*)url {
MPMoviePlayerViewController *moviePlayer = [[[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL URLWithString:url]] autorelease];
[((UIWindow*)[[UIApplication sharedApplication].windows objectAtIndex:0]).rootViewController presentMoviePlayerViewControllerAnimated:moviePlayer];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(moviePlaybackComplete:)
name:MPMoviePlayerPlaybackDidFinishNotification object:moviePlayer];
[moviePlayer.moviePlayer setFullscreen:YES animated:YES];
[moviePlayer.moviePlayer setControlStyle:MPMovieControlStyleFullscreen];
}
- (void)moviePlaybackComplete:(NSNotification *)notification {
MPMoviePlayerViewController *moviePlayer = [notification object];
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:moviePlayer];
[((UIWindow*)[[UIApplication sharedApplication].windows objectAtIndex:0]).rootViewController dismissMoviePlayerViewControllerAnimated];
}
I make mpmovieplayerviewcontroller and load movie in it (from stream). Now I have call to setContentURL method that change URL and it works. Whenn app is first time started it shows view with button after button is pressed it opens movie player and load movie. But when I call code where is setContentURL player close it self first, go back to first view where I have to again click play button to again open player (so it remembers and load new URL). How to prevent player to not close it self when switching URL? This must be some small issue, please help :)
This is code when play button is clicked (first view)
-(void)initializeMovieFromStream:(NSString *)var
{
if(player != nil)
{
NSString *title = [[NSString alloc] initWithFormat:#"%#%#%#", #"http://"];
NSURL *nurl = [NSURL URLWithString:title];
NSLog(#"Switching channel...");
[player.moviePlayer setContentURL:nurl];
isMoviePaused = NO;
}
else
{
NSString *title = [[NSString alloc] initWithFormat:#"%#%#%#", #"http://"];
NSURL *nurl = [NSURL URLWithString:title];
player = [[MPMoviePlayerViewController alloc] initWithContentURL:nurl];
[player.moviePlayer.view.window setUserInteractionEnabled:YES];
player.moviePlayer.movieSourceType = MPMovieSourceTypeStreaming;
player.moviePlayer.controlStyle = MPMovieControlStyleNone;
}
[[NSNotificationCenter defaultCenter]
addObserver:self selector:#selector(movieFinishedPlaying:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:[player moviePlayer]];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(nowPlayingMovieDidChange:)
name:MPMoviePlayerNowPlayingMovieDidChangeNotification
object:nil];
[self presentModalViewController:player animated:YES];
//[self presentMoviePlayerViewControllerAnimated:player];
UIView *mv = player.view;
//[mv setFrame:CGRectMake(0, 0, 320, 480)];
[mv addSubview:myOverlayChannelPicker];
[mv bringSubviewToFront:myOverlayChannelPicker];
// register this class to observe TestNotification that comes from OverlayChannelPicker
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(receiveTestNotification:)
name:#"TestNotification"
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(pauseStreamNotificationHandler:)
name:#"notiPauseStream"
object:nil];
}
-(void) movieFinishedPlaying: (NSNotification *)note
{
[[NSNotificationCenter defaultCenter]
removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification
object:[player moviePlayer]];
//[player release];
}
When URL need to be switch I use this nitification handler
- (void) receiveTestNotification:(NSNotification *) notification
{
NSString *stringFromNote = (NSString *)[notification object];
[switchableChannel setString:stringFromNote];
[self initializeMovieFromStream:stringFromNote];
}
It is solved I just change animation property to NO.