Why won't my movie play using MPMoviePlayerController? - iphone

I'm trying to get a basic movie to play in an iPhone app; however, I can't seem to get it to work. Here's my entire code:
#import <MediaPlayer/MediaPlayer.h>
#import "ViewController.h"
#implementation ViewController
- (IBAction)playMoviePressed:(id)sender
{
NSURL *url = [NSURL URLWithString:#"http://www.ebookfrenzy.com/ios_book/movie/movie.mov"];
MPMoviePlayerController *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:YES];
[moviePlayer prepareToPlay];
[moviePlayer play];
}
#end
I have one button on screen that calls playMoviePressed when it is tapped. I know that this method is getting called. I have also tried this with .mov and .mp4 local files that I have dragged into xcode.

I got your code to play the video by adding a frame for it:
[moviePlayer.view setFrame:CGRectMake(0, 0, 320, 200)];
However the video was choppy but that could be my internet connection though. Seeing that you're using an IBAction, you're probably using Interface Builder or Storyboard so the only thing that I can think that's preventing it from playing is that you're missing the connection to the IBOutlet.

If you want a full screen mode, you can simply use MPMoviePlayerViewController and do something like:
MPMoviePlayerViewController* viewController = [[MPMoviePlayerViewController alloc] initWithContentURL:url];
[self presentMoviePlayerViewControllerAnimated:viewController];

I figured it out. My problem was really dumb. Because I am not maintaining a strong pointer to my MPMoviePlayerViewController, it gets deallocated as soon as the method ends. A simple #property in the interface solves this.

Related

MPMoviePlayerController repeat mode not working in viewDidLoad

It seems that I'm having a problem with repeatmodeone: it does not repeat the video.
This is the code for the video I have in the implementation:
- (void)viewDidLoad{
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"Space Particle" ofType:#"mp4"]];
MPMoviePlayerViewController *playerController = [[MPMoviePlayerViewController alloc]initWithContentURL:url];
[self presentMoviePlayerViewControllerAnimated:playerController];
[playerController.moviePlayer prepareToPlay];
playerController.moviePlayer.movieSourceType = MPMovieSourceTypeFile;
playerController.moviePlayer.controlStyle = MPMovieControlStyleNone;
playerController.moviePlayer.scalingMode = MPMovieScalingModeAspectFill;
playerController.moviePlayer.repeatMode = MPMovieRepeatModeOne;
[MyView1 addSubview: playerController.view];
[playerController.moviePlayer play];
[playerController release];playerController=nil;
}
It works as an animated background with buttons above it. The video plays but when it finishes, it does not repeat.
I found out that, as an IbAction, it repeats, but as a viewDidLoad it doesn´t.
Note that the "MyView" outlet has been linked to a custom UIButton, and it´s in the button view where the movie plays.
The videos I'm using aren't large in size.
My objective is that the movie must repeat using the viewdidload method in order to auto play and repeat.
Please, is there anything I am doing wrong? Suggestions on how to solve it? Any help would be appreciated.
Try following code. This is working perfectly.
NSURL *fileUrl = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"Video" ofType:#"mp4"]];
MPMoviePlayerViewController *moviePlayerController = [[MPMoviePlayerViewController alloc]initWithContentURL:fileUrl];
[moviePlayerController.moviePlayer prepareToPlay];
[moviePlayerController.moviePlayer setRepeatMode:MPMovieRepeatModeOne];
[moviePlayerController.moviePlayer setControlStyle:MPMovieControlStyleEmbedded];
[self.view addSubview:moviePlayerController.view];
It's been deleted by ARC after the viewDidLoad function finished. You should hold the MPMoviePlayerController instance as a class member. NSNotification also solves the issue because it retains the object. Making it an instance variable will make notification solution redundant.
The same issue. I solved it with the next steps:
1) Subscribe to the end playback notification
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayBackDidFinished:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:self.moviePlayer];
2) Start playback manually in moviePlayBackDidFinished method

Trouble presenting MPMoviePlayerViewController, or MoviePlayerController in fullscreen

I'm trying to create a movie to play when my app starts up. The first view Controller is a UITabBarController. In the code for the view controller for the first tab, is where I put my movie. This dummy code works (setting the frame to be smaller than the full screen and just showing the video):
- (void)PlayOpeningMovie {
NSString *filepath = [[NSBundle mainBundle] pathForResource:#"test" ofType:#"m4v"];
NSURL *fileURL = [NSURL fileURLWithPath:filepath];
MPMoviePlayerController *moviePlayerController = [[MPMoviePlayerController alloc] initWithContentURL:fileURL];
// MPMoviePlayerViewController *moviePlayerController = [[MPMoviePlayerViewController alloc] initWithContentURL:fileURL];
[moviePlayerController.view setFrame:CGRectMake(120, 120, 300, 200)];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlaybackComplete:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:moviePlayerController];
[self.view addSubview:moviePlayerController.view];
// [moviePlayerController setFullscreen:YES];
// [self presentMoviePlayerViewControllerAnimated:moviePlayerController];
[moviePlayerController play];
// [[moviePlayerController moviePlayer] play];
}
However, if I switch it around, comment out the setFrame method, and use the fullscreen property, I do not see the movie.
I was also playing around with creating a MPMovieplayerViewController and presenting that modally with the method for the MPMoviePlayerViewControllers, but it never gets presented and I can't figure out why. I tried creating a dummy viewController with a yellow background as well, and presenting that modally and that does not work either.
I have tried adding a dummy UIView to the screen, and that works.
So for some reason, I can get small UIViews/MPMoviePlayers to show with addSubview. I cannot get the presentModal__ to work. I cannot get fullscreen mode to work for the MoviePlayerController. I'm really stumped as to why I cannot present modally from this view. Thanks.
[moviePlayerController setControlStyle:MPMovieControlStyleFullscreen];
[moviePlayerController setFullscreen:YES];
Just add this two lines to present it in full screen.

Switching view controllers at the end of a movie's playback?

In my app, there's a UIButton that the end user can push, which pushes a view controller that plays a video in a frame using MPMoviePlayerController.
I'd like to be able to detect when the video reaches it's end, and when that happens, push a new view controller. Though I can't seem to find the code that can do this.
Does anyone know how to do this?
The video playback code just looks like this:
//video stuff
CGRect myVideoRect = CGRectMake(0.0f, 145.0f, 320.0f, 160.0f);
movieUrl = [[NSBundle mainBundle] URLForResource:#"myMovie" withExtension:#"m4v"];
moviePlayerController = [[MPMoviePlayerController alloc] initWithContentURL:movieUrl];
[[moviePlayerController view] setFrame:myVideoRect];
moviePlayerController.controlStyle = MPMovieControlStyleNone;
[self.view addSubview:moviePlayerController.view];
[moviePlayerController play];
Thanks!
Register your view controller to listen to playbackdidfinish notification for the player:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(playbackFinished:) name:MPMoviePlayerPlaybackDidFinishNotification object:player];
Then implement a playbackFinished method where you can push a new view controller or perform any other action.

Release MPMoviePlayer when using a tabbarcontroller

I'm using a tabbarcontroller in which one of the views has an MPMoviePlayer. It works fine, except that if I change tab, the movie doesn't stop and keeps playing in the background. Then if I try to tab back to the movie tab, it crashes.
I think the only code I have to release the MPMoviePlayer is when it's finished playing, but I want it to be released when I change views instead. Then if I go back to the Movie tab, we start fresh.
In my .h file have set up as:
import < UIKit/UIKit.h>
import < MediaPlayer/MediaPlayer.h>
#interface SecondViewController : UIViewController {
MPMoviePlayerController *player;
}
#end
and in my .m file have:
- (void)viewDidLoad {
NSString *url = [[NSBundle mainBundle]
pathForResource:#"vid"
ofType:#"m4v"];
player = [[MPMoviePlayerController alloc]
initWithContentURL:[NSURL fileURLWithPath:url]];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(movieFinishedCallback:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:player];
//--called when the movie view and then add it to the View window--
player.view.frame = CGRectMake(10, 10, 300, 300);
[self.view addSubview:player.view];
//--play movie--
[player pause];
[super viewDidLoad];
}
//--called when the movie is done playing--
- (void) movieFinishedCallback:(NSNotification*) aNotification {
MPMoviePlayerController *moviePlayer = [aNotification object];
[[NSNotificationCenter defaultCenter]
removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:moviePlayer];
[moviePlayer.view removeFromSuperview];
[player release];
}
Any suggestions? Thank you :)
If you really want to release MPMoviePlayer at tab switch, then do it in viewWillDisappear or viewDidDisappear. Now it's left alive at background, as you described. When you come back to tab, you try to create it again.
Difficult to say what would be the exact reason for crash, there seems to be several possibilities. Next time write a "Why did this crash" question with a call stack.
Maybe you could think about just pause/resume, so you wouldn't need to reallocate new moviePlayer every time user changes tabs? Do alloc/release in viewDidLoad and viewDidUnload, but play/pause in viewWillAppear and viewWillDisappear.

Playing video in custom size screen - view in iPhone

Suppose user taps on a button and video begins to play. Now when video plays, it always in full screen mode.
Video should be played in a portrait mode (but normally video is played in landscape mode). How can I do this?
Just an update, the latest iPhone SDK 3.2+ will now allow the programmers to show the video in any desired size and Orientation, New MPMoviePlayerView is provided, which is a property of MPMoviePlayerController, this view will have the video, which you can add as a subview to your view.
#interface MPMoviePlayerController (extend)
-(void)setOrientation:(int)orientation animated:(BOOL)value;
#end
moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:movieUR];
[moviePlayer setOrientation:UIDeviceOrientationPortrait animated:NO];
if (moviePlayer)
{
[self.moviePlayer play];
}
This Solution will be rejected by Apple, as setOrientation for movie player is the Private API. You need to be careful, but it may work on Jailbroke iPhones.
From the documented docs i do not think this is possible using the built in media player
Try this out.
I found something new.
#interface MPMoviePlayerController (extend)
-(void)setOrientation:(int)orientation animated:(BOOL)value;
#end
moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:movieUR];
[moviePlayer setOrientation:UIDeviceOrientationPortrait animated:NO];
if (moviePlayer)
{
[self.moviePlayer play];
}
Here's what I did. Add NSNotification to notify you when preloading of the video finishes.
- (void)playVideoUrl:(NSString *)videoUrl {
NSURL *url = [NSURL URLWithString:videoUrl];
MPMoviePlayerController* theMovie=[[MPMoviePlayerController alloc]
initWithContentURL:url];
[[NSNotificationCenter defaultCenter] addObserver:self
//MPMoviePlayerContentPreloadDidFinishNotification
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(myMovieFinishedPreloading:)
name:MPMoviePlayerContentPreloadDidFinishNotification
object:theMovie];
// Movie playback is asynchronous, so this method returns immediately.
[theMovie play];
}
Callback selector:
-(void)myMovieFinishedPreloading:(NSNotification*)aNotification {
NSArray *windows = [[UIApplication sharedApplication] windows];
UIWindow *moviePlayerWindow = nil;
if ([windows count] > 1)
{
moviePlayerWindow = [[UIApplication sharedApplication] keyWindow];
}
CGAffineTransform transform = CGAffineTransformMakeScale(0.5, 0.5);
transform = CGAffineTransformRotate(transform, -90.0f*M_PI/180.0f);
[moviePlayerWindow setTransform:transform];
}