I'm having trouble playing a video on the iPhone. I have a file in the app bundle and I am trying to play it in a MPMoviePlayerController but it is just displaying a black screen. This is the following code:
-(UIView*)createVideoPlayerOfWidth:(CGFloat)width
{
// The width for one of these can be half of the max width
//CGFloat widthAndHeight = width / 2.0f;
// TODO: Create a video player
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"myVideo" ofType:#"mov"]];
MPMoviePlayerController *playerController = [[MPMoviePlayerController alloc] initWithContentURL:url];
[playerController prepareToPlay];
[playerController setShouldAutoplay:NO];
[playerController setScalingMode:MPMovieScalingModeAspectFit];
[playerController setControlStyle:MPMovieControlStyleEmbedded];
[playerController setRepeatMode:MPMovieRepeatModeNone];
// Resize the thumbnail of the video
[[playerController view] setFrame:CGRectMake(0, 0, width, width)];
return [playerController view];
}
It is returning a valid URL (pathForResource would return nil if it couldn't find the file). I am displaying it to the screen by just adding a subView (the view returned by the function) to a scroll view. I've been trying to solve this for ages now and am getting nowhere. Any help is much appreciated.
Thanks!
Make sure you are retaining a reference to the MPMoviePlayerController instance:
If this is an ARC project, then playerController will be destroyed when createVideoPlayerOfWidth returns, and your video probably won't play. You should store the player in a strong instance variable or property.
You could add something like this to the top of your view controller file:
#interface MyViewController ()
#property (nonatomic,retain) MPMoviePlayerController *player;
#end
And insert this after you create the MPMoviewPlayerController instance:
self.player = playerController;
If you're not using ARC, this is probably not the problem, but you should still keep a reference in an instance variable, so that you can release it later.
Related
I'm trying to implement an AVPlayer into each row of a Collection cell but I don't find any good documentation.Any idea where I can find some?
Try this code
self.moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"something" ofType:#"mp4"]]];
[self.moviePlayer.view setFrame:CGRectMake(0, 0, 320, 320)];
[self.moviePlayer play];
[self.view addSubview:self.moviePlayer.view];
self.movieplayer is an instance of MPMoviePlayerController (not MPMoviePlayerViewController). In my experience it's important to declare it as a property (like so: #property (strong, nonatomic) MPMoviePlayerController *moviePlayer;) rather than a simple ivar, because sometimes it just doesn't work if it's an ivar
setting the frame is also important, because if we don't set it, the video will not appear at all. The frame can be anything as long as what you define is within the bounds of your view
Important: As above, when defining the URL use NSURL's URLWithString method if you want to access the file through a network and use NSURL's fileUrlWithPath if you have the file locally!
As the question says, on a iOS device if a user inputs a URL in uitextfield I want to generate a thumbnail capture of this URL. How can this be achieved? Unfortunately I don't have a clue where to start from.
Of course one way I can do this is to send this URL to backend & get the image screenshot from there. I know how one can do this kinda stuff using python or php. But I want to avoid the extra round trip to my backend servers.
I want something like - (uiimage *)screenCapture:(nsurl *)url
As per your question i think you'll want to manipulate the generated screenshot afterwards. You'll add a UIWebView programmatically to load the needed URL then take a snapshot of the loaded web page then remove the UIWebView
Here are the steps
a UIImageView to your viewController and connect it to your viewController class
#property (weak, nonatomic) IBOutlet UIImageView *image_Thumbnail;
having the URL in a variable named "webPageUrlString" add the following lines
UIWebView* webView = [[UIWebView alloc] initWithFrame:self.view.frame];
webView.backgroundColor = [UIColor redColor];
NSURL *websiteUrl = [NSURL URLWithString:**webPageUrlString**];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:websiteUrl];
[webView loadRequest: urlRequest];
webView.delegate = self;
[self.view addSubview:webView];
right now you have requested to load the URL but can't render the snapshot unless the web page is fully loaded,so you'll need to wait for the web page loading notification.In order to that you must subscribe to the webView delegate in the header file like that
#interface ViewController : UIViewController<UIWebViewDelegate>
Now you'll implement the "webViewDidFinishLoad" and take the snapshot you want then hide and remove the webView.
-(void)webViewDidFinishLoad:(UIWebView *)webView{
viewImage = [[UIImageView alloc] initWithFrame:self.view.frame];
viewImage.backgroundColor = [UIColor greenColor];
UIGraphicsBeginImageContext(webView.bounds.size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
viewImage.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[webView setAlpha:0];
[webView removeFromSuperview];
[self.view addSubview:viewImage];
}
Now you have the screenshot you want in the property called "viewImage" and you can do what ever you want with it ;)
I want to play a video in my iPhone app. I used this code:
- (void)viewDidLoad
{
[super viewDidLoad];
NSURL *movieUrl = [NSURL fileURLWithPath:
[[NSBundle mainBundle] pathForResource:#"Myvideo"
ofType:#"mp4"]];
//create a new instance of MPMoviePlayerController
MPMoviePlayerController* myMovie=[[MPMoviePlayerController alloc]
initWithContentURL:movieUrl];
//disable scaling of our movie
myMovie.scalingMode = MPMovieScalingModeNone;
//don't show any controls
// myMovie.movieControlMode = MPMovieControlModeHidden;
//you can specify at which time the movie should
//start playing (default is 0.0)
myMovie.initialPlaybackTime = 2.0;
//register a callback method which will be called
//after the movie finished
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(movieFinished:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:myMovie];
//start the movie (asynchronous method)
[myMovie play];
// Do any additional setup after loading the view from its nib.
}
Only the sound works with this code. Can someone help me please?
You need to allocate a frame to your movie and add it to the view. See here.
So you can add:
[myMoview.view setFrame: self.view.bounds]; // player's frame must match parent's
[self.view addSubview:myMovie.view];
Apple Technical Q&A 1240:
MPMoviePlayerController plays movie audio but not video
Q: I'm able to successfully play movies using MPMoviePlayerController on iOS 3.1.3. When I run this same code on the iPad and on the iPhone with iOS 4 I can hear the movie audio, but the video is no longer displayed. What's going on?
A: Starting with iPhone iOS 3.2, calling the -play: method still starts playback of the movie but it does not ensure that the movie is visible. In order to display a movie, you must get the new view property from your MPMoviePlayerController object and add that view to your view hierarchy. Here's a code snippet:
Listing 1 How to add the MPMoviePlayerController view property to your view hierarchy to play a movie.
#import <UIKit/UIKit.h>
#import <MediaPlayer/MediaPlayer.h>
MPMoviePlayerController *player = [[MPMoviePlayerController alloc] initWithContentURL:movieURL];
[[player view] setFrame:[myView bounds]]; // size to fit parent view exactly
[myView addSubview:[player view]];
[player play];
See Important Porting Tip for Using the Media Player Framework and the MPMoviePlayerController Class Reference for more information.
Howdy! I'm writing an iPad app, and I need to be able to play a video when a UIView loads. However, I was getting a BAD_EXC_ACCESS if I try to message my MPMoviePlayerController anywhere after I initialize it. I removed the MPMediaPlayerController from my *.h file, then declared it entirely in the implementation file, and now I'm getting the message at the bottom below my code. There are no issues in Build and Analyze about memory leaks (or any issues, for that matter), and I cannot find any posts about this. Here's my code:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
}
NSString *url = [[NSBundle mainBundle] pathForResource:#"p0600c0100cmpintro" ofType:#"m4v"];
MPMoviePlayerController *movie = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL fileURLWithPath:url]];
NSLog(#"%#", movie);
movie.view.frame = CGRectMake(5, 0, 1035, 768);
movie.view.contentMode = UIViewContentModeScaleToFill;
[[movie view] setCenter:CGPointMake(movie.view.center.x-10, movie.view.center.y)];
[movie setControlStyle:MPMovieControlStyleNone];
[movie setShouldAutoplay:YES];
[[self view] addSubview:[movie view]];
return self;
}
The NSLog of "movie" gives "MPMoviePlayerController: 0x1b77f0", but then the error message upon crash is "* -[MPMoviePlayerController playbackState]: message sent to deallocated instance 0x1473a0". Help?
According to the documentation it looks like the frame of the movie view needs to match the view of its parent. Also try moving your code out of the initWithNibName:bundle: into viewDidLoad:
- (void)viewDidLoad {
[super viewDidLoad];
UIView *movieContainer = [[UIView alloc] initWithFrame:CGRectMake(5, 0, 300, 400)];
//Do any other positioning of the view you would like
NSString *path = [[NSBundle mainBundle] pathForResource:#"p0600c0100cmpintro" ofType:#"m4v"];
NSURL *url = [NSURL fileURLWithPath:path];
MPMoviePlayerController *movie = [[MPMoviePlayerController alloc] initWithContentURL:url];
movie.view.frame = movieContainer.bounds; //Make sure this is the bounds of its parent view
movie.scalingMode = MPMovieScalingModeFill;
movie.controlStyle = MPMovieControlStyleNone;
movie.shouldAutoplay = YES;
[movieContainer addSubview:movie.view];
[self.view addSubview:movieContainer];
[movieContainer release];
}
One last suggestion would be to keep a reference of the movie so that you can dealloc it once the view controller gets deallocated
I would suggest creating your MoviePlayer in viewDidLoad, then in viewDidAppear make the movie play, for best results.
Alright, so I have another MPMoviePlayerController instance which was being deallocated earlier, but when I try to create another instance of MPMoviePlayerController, all the messages sent to this one were being sent to the deallocated instance, resulting in the memory problem. So I just removed the part where I released the first instance, and it works perfectly fine. My question now is this: is there a way to deallocate this first instance so that it isn't a burden on memory when it isn't needed? I feel that there should be a more elegant solution to this problem. I will need to play videos frequently in this application.
I found the solution a number of weeks ago and forgot about this post. I wasn't successfully releasing the MPMoviePlayerController. For those curious, in order to release an MPMoviePlayerController, we must first remove the notification from the NSNotificationCenter (if one was set), stop the movie (even if it's done playing), THEN release it. I wasn't doing this earlier in the application with my first MPMoviePlayerController, so it was trying to reference the deallocated instance. When the movie is done playing, here is the code to release the movie successfully:
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackStateDidChangeNotification object:movie];
[movie.view removeFromSuperview];
[movie stop];
[movie release];
I have this code trying to run a video on the iPhone 4 Simulator.
The problem is that looks like it loads the player but half a second later loads a back screen on top of the whole application disabling touch and everything, and it looks like it does not play the video also, because I can't hear anything.
Any ideas?!
MPMoviePlayerViewController *mp =
[[MPMoviePlayerViewController alloc] initWithContentURL:videoUrl];
if (mp) {
mp.moviePlayer.scalingMode = MPMovieScalingModeFill;
mp.moviePlayer.movieSourceType = MPMovieSourceTypeFile;
[mp.moviePlayer play];
[self presentMoviePlayerViewControllerAnimated:mp];
[mp release];
}
I believe the problem is caused by releasing the MPMoviePlayerViewController. Simply retain the controller until you are done with it.
Prior to the "[mp release];" add this line to save the value away.
self.moviePlayerViewController = mp;
Then update your dealloc method to do the release:
- (void)dealloc {
[_moviePlayerViewController release], _moviePlayerViewController = nil;
[super dealloc];
}
Add the synthesize to the top of your .m file:
#synthesize moviePlayerViewController = _moviePlayerViewController;
Add the defination to the #interface of your .h file:
MPMovieViewController *_moviePlayerViewController;
Add the property to your .h file:
#property (readwrite, retain) MPMovieViewController *moviePlayerViewController;
You may need some headers in your header:
#import <MediaPlayer/MediaPlayer.h>
#import <MediaPlayer/MPMoviePlayerViewController.h>
You may also need to balance your "presentMoviePlayer" call with the dismiss somewhere:
[self dismissMoviePlayerViewControllerAnimated];
Phew, code everywhere. Anyway, if you are finished with the resource early, you may be able to release it sooner by using NotificationManager to watch for MPMoviePlayerPlaybackDidFinishNotification. There are many examples of that, so I won't repeat it.
Hope this helps.
This is the code I'm using:
MPMoviePlayerViewController *movieViewController = [[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL URLWithString:contentUrl]];
movieViewController.moviePlayer.movieSourceType = MPMovieSourceTypeFile;
[self presentMoviePlayerViewControllerAnimated:movieViewController];
[movieViewController release];
It seems to work fine for me. Two notes:
Some simulators (like the current iOS 5.0) crash when playing a movie, but it works on a real device
if you leave out the movieSourceType part, a black screen is shown for about a second before the movie starts