I am using the following code to play video files in MPMoviePlayerController
NSString* filePath = [[NSBundle mainBundle] pathForResource:#"one" ofType:#"mp4"];
NSURL* url = [NSURL fileURLWithPath:filePath];
_movie = [[MPMoviePlayerController alloc] initWithContentURL:url];
[_movie.view setFrame:self.view.bounds];
[self.view addSubview:_movie.view];
_movie.fullscreen=YES;
_movie.controlStyle=MPMovieControlStyleFullscreen;
[_movie prepareToPlay];
[_movie play];
and
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(close:)name:MPMoviePlayerPlaybackDidFinishNotification object:_movie];
and
- (void) close:(NSNotification *)notification {
int reason = [[[notification userInfo] valueForKey:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey] intValue];
if(reason == MPMoviePlaybackStateStopped) {
NSLog(#"Stop");
}
else if (reason == MPMovieFinishReasonPlaybackEnded) {
NSLog(#"Playback Ended ");
}
else if (reason == MPMovieFinishReasonUserExited) {
NSLog(#"Exited");
[_movie.view removeFromSuperview];
}
else if (reason == MPMovieFinishReasonPlaybackError) {
//error
NSLog(#"Error");
}
}
I am able to get the Notification , and the Movieplayer is not removing from the superview.
What could be the problem ??
Try this follow instructions:
when I listen to MPMoviePlayerWillExitFullscreenNotification.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(doneButtonClick:)
name:MPMoviePlayerWillExitFullscreenNotification
object:_movie];
And selector method:
-(void)doneButtonClick:(NSNotification*)aNotification{
[_movie.view removeFromSuperview];
}
(or)
Better way to use mpmovieplayerviewcontroller in below tutorial
http://mobiledevelopertips.com/video/getting-mpmovieplayercontroller-to-cooperate-with-ios4-3-2-ipad-and-earlier-versions-of-iphone-sdk.html
Related
I wanted to play a video as background of my view so I decided to use MPMoviePlayerController to play endless video and I made something like that:
NSString *pathForFile = [[NSBundle mainBundle] pathForResource:#"clear" ofType:#"mp4"];
player = [[MPMoviePlayerController alloc] init];
player.shouldAutoplay = YES;
player.repeatMode = MPMovieRepeatModeNone;
player.fullscreen = YES;
player.movieSourceType = MPMovieSourceTypeFile;
player.scalingMode = MPMovieScalingModeAspectFill;
player.contentURL =[NSURL fileURLWithPath:pathForFile];
player.controlStyle = MPMovieControlStyleNone;
[player.view setFrame:self.view.bounds];
[player.view setUserInteractionEnabled:NO];
[player.view setAlpha:0.0f];
[self.view addSubview:player.view];
[self.view sendSubviewToBack:player.view];
[player prepareToPlay];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayerDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:player];
- (void)moviePlayerDidFinish:(NSNotification *)note {
if (note.object == player) {
NSInteger reason = [[note.userInfo objectForKey:#"MPMoviePlayerPlaybackDidFinishReasonUserInfoKey"] integerValue];
if (reason == MPMovieFinishReasonPlaybackEnded) {
[player play];
}
}
My method called every time the video ends, but player don't playing video again. What am I doing wrong?
Thanks in advance.
- (void)moviePlayerDidFinish:(NSNotification *)note {
if (note.object == player) {
NSInteger reason = [[note.userInfo objectForKey:#"MPMoviePlayerPlaybackDidFinishReasonUserInfoKey"] integerValue];
if (reason == MPMovieFinishReasonPlaybackEnded) {
player.seekToTime[kCMTimeZero];
// you must have to give time to start video again so use seekToTime
[player play];
}
}
}
I have a youtube video that plays in a uiwebview in my app. The cell signal is not very good in most areas I am using the app.
How can I cache the youtube video for better performance when playing the video?
Try this
I start downloading the video file with a NSURLConnection
I then implement the received data delegate method like the following.
- (void)connection:(NSURLConnection *)aConnection didReceiveData:(NSData *)aData
{
bytesFetched += aData.length;
if( bytesFetched > kBytesRequiredBeforeStart && !hasCachedData ) // kBytesRequiredBeforeStart = 160000
{
[[NSNotificationCenter defaultCenter] postNotificationName:kVideoURLCacheHasDataNotification object:self];
hasCachedData = YES;
}
[self.fileHandle writeData:aData]; // this file handle is not closed until after the video has finished downloading
}
The fileHandle is created like this
- (NSFileHandle *)fileHandle
{
if( fileHandle == nil )
{
NSError * theError = nil;
cachedURL = [[NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingFormat:#"/%#", kTempFileName]] retain];
[[NSFileManager defaultManager] createFileAtPath:[self.cachedURL path] contents:nil attributes:nil];
fileHandle = [[NSFileHandle fileHandleForWritingToURL:self.cachedURL error:&theError] retain];
if( fileHandle == nil )
[[NSNotificationCenter defaultCenter] postNotificationName:kVideoURLCacheErrorOccuredNotification object:self];
}
return fileHandle;
}
*I also have a did finish delegate handling method like this*
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
if( hasCachedData == NO )
{
[[NSNotificationCenter defaultCenter] postNotificationName:kVideoURLCacheHasDataNotification object:self];
hasCachedData = YES;
}
hasFinishedCaching = YES;
[[NSNotificationCenter defaultCenter] postNotificationName:kVideoURLCacheDidFinishLoadingNotification object:self];
}
I then have a method to observer the notification like the following
- (void)videoURLCacheHasDataNotification:(NSNotification *)aNotification
{
[self.videoController play];
}
where the videoController is an instance of MPMoviePlayerController created like below, cachedURL is the same one defined above.
- (MPMoviePlayerController *)videoController
{
if( videoController == nil )
{
NSURL * theURL = self.videoURLCache.cachedURL;
NSLog( #"Video URL = '%#'", theURL );
videoController = [[MPMoviePlayerController alloc] initWithContentURL:theURL];
videoController.shouldAutoplay = NO;
[videoController setFullscreen:NO animated:NO];
videoController.view.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin|UIViewAutoresizingFlexibleHeight;
videoController.repeatMode = MPMovieRepeatModeOne;
videoController.controlStyle = MPMovieControlStyleEmbedded;
videoController.view.frame = self.videoView.bounds;
[videoView addSubview:self.videoController.view];
}
NSParameterAssert(videoController != nil);
return videoController;
}
here is my code
- (void)viewDidLoad
{
...
NSString *filepath = [[NSBundle mainBundle] pathForResource:#"movie" ofType:#"mov"];
NSURL *fileURL = [NSURL fileURLWithPath:filepath];
_moviePlayerController = [[MPMoviePlayerController alloc] initWithContentURL:fileURL];
[self.view addSubview:_moviePlayerController.view];
_moviePlayerController.fullscreen = YES;
_moviePlayerController.scalingMode = MPMovieScalingModeAspectFit;
_moviePlayerController.controlStyle=MPMovieControlStyleDefault;
[_moviePlayerController play];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(movieIsOver:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:nil];
}
- (void)movieIsOver:(NSNotification *)notification
{
NSLog(#"movie is over");
[[NSNotificationCenter defaultCenter] removeObserver:self];
[self.moviePlayerController.view removeFromSuperview];//moviePlayerController is MPMoviePlayerController
}
When the movie plays to the end, I can't see "movie is over" log and the moviePlayerController.view isn't removed. I don't know why.
EDIT:
MPMoviePlayerPlaybackDidFinishNotification works well.I see the "movie is over" log.The problem is moviePlayerController.view isn't removed.
I found out the solution:add
_moviePlayerController.fullscreen = NO;
before removing view from superview
Instead of adding _moviePlayerController.view as subview
[self.view addSubview:_moviePlayerController.view];
you can present _moviePlayerController just like this :
[self presentMoviePlayerViewControllerAnimated: _moviePlayerController];
and in movieIsOver method you simply dismiss
[self dismissMoviePlayerViewControllerAnimated];
I hope its help
I have been browsing through Google for various explanations but I STILL couldn't figure out when this code fires the screen is pitch black. Anyone able to spot a mistake?
UPDATE
- (IBAction)playVideo:(id)sender {
NSURL *videoUrl = [[DataStore singletonInstance] getVideoUrl:self withUuid:self.eventDetailVC.event.uuid];
if ([videoUrl checkResourceIsReachableAndReturnError:nil] == NO) {
NSLog(#"Video doesn't not exist.");
return;
}
MPMoviePlayerController *player = [[MPMoviePlayerController alloc] initWithContentURL:videoUrl];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayBackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:player];
[previewView addSubview:player.view];
player.view.frame = previewView.bounds;
player.controlStyle = MPMovieControlStyleDefault;
[player play];
}
- (void)moviePlayBackDidFinish:(NSNotification*)notification {
NSLog(#"moviePlayBackDidFinish: called");
MPMoviePlayerController *player = [notification object];
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification
object:player];
// Checking for errors
NSDictionary *notiUserInfo = [notification userInfo];
if (notiUserInfo != nil) {
NSError *errorInfo = [notiUserInfo objectForKey:#"error"];
if ([[errorInfo domain] isEqualToString:#"MediaPlayerErrorDomain"]) {
UIAlertView *notice = [[UIAlertView alloc] initWithTitle:#"Error"
message:[errorInfo localizedDescription]
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[notice show];
return;
}
}
// Remove from view
[player.view removeFromSuperview];
[player stop];
}
FYI moviePlayBackDidFinish is NOT called at all. I don't know why.
Create property for MPMoviePlayerController, because you retain view after adding it as subview, but not retain controller.
#property (strong, nonatomic) MPMoviePlayerController *player;
...
#synthesize player = _player;
...
- (IBAction)playVideo:(id)sender
{
NSURL *videoUrl = [[DataStore singletonInstance] getVideoUrl:self withUuid:self.eventDetailVC.event.uuid];
if ([videoUrl checkResourceIsReachableAndReturnError:nil] == NO)
{
NSLog(#"Video doesn't not exist.");
return;
}
self.player = [[MPMoviePlayerController alloc] initWithContentURL:videoUrl];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayBackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:nil];
[previewView addSubview:_player.view];
_player.view.frame = previewView.bounds;
_player.controlStyle = MPMovieControlStyleDefault;
[_player play];
}
- (void)moviePlayBackDidFinish:(NSNotification*)notification
{
NSLog(#"moviePlayBackDidFinish: called");
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification
object:nil];
// Checking for errors
NSDictionary *notiUserInfo = [notification userInfo];
if (notiUserInfo != nil)
{
NSError *errorInfo = [notiUserInfo objectForKey:#"error"];
if ([[errorInfo domain] isEqualToString:#"MediaPlayerErrorDomain"])
{
UIAlertView *notice = [[UIAlertView alloc] initWithTitle:#"Error"
message:[errorInfo localizedDescription]
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[notice show];
return;
}
}
// Remove from view
[_player.view removeFromSuperview];
[_player stop];
self.player = nil;
}
Following code used to save videos to photo Album.
else if ([mediaType isEqualToString:(NSString *)kUTTypeMovie])
{
NSString *sourcePath = [[info objectForKey:#"UIImagePickerControllerMediaURL"]relativePath];
UISaveVideoAtPathToSavedPhotosAlbum(sourcePath,nil,nil,nil);
}
If it is video i want to play it if it is image i want to display it.
Help Me.
with the code check if is image or video :
NSString *mediaType1 = [info objectForKey:UIImagePickerControllerMediaType];
NSLog(#"mediaType : %#",mediaType1);
if ([mediaType1 isEqualToString:#"public.image"])
{
//Show Image
}
else
{
//show Video
}
To Play the video check the URL.
EDIT:
NSString *moviePath = [bundle pathForResource:#"IMG_0017" ofType:#"MOV"];
NSLog(#"moviePath : %#",moviePath);
// NSURL *movieURL = [[NSURL fileURLWithPath:moviePath] retain];
NSURL *movieURL = [NSURL URLWithString:strValURL];
NSLog(#"movieURL : %#",movieURL);
if ([[[UIDevice currentDevice] systemVersion] doubleValue] >= 3.2)
{
NSLog(#"> 3.2");
MPMoviePlayerViewController *mp = [[MPMoviePlayerViewController alloc] initWithContentURL:movieURL];
if (mp)
{
[self presentMoviePlayerViewControllerAnimated:mp];
mp.moviePlayer.movieSourceType = MPMovieSourceTypeFile;
[mp.moviePlayer play];
[mp release];
}
}
else if ([[[UIDevice currentDevice] systemVersion] doubleValue] < 3.2)
{
NSLog(#"< 3.2");
theMovie = [[MPMoviePlayerController alloc] initWithContentURL: movieURL];
theMovie.scalingMode = MPMovieScalingModeAspectFill;
[[NSNotificationCenter defaultCenter]
addObserver: self
selector: #selector(myMovieFinishedCallback:)
name: MPMoviePlayerPlaybackDidFinishNotification
object: theMovie];
[theMovie play];
}
- (void) moviePlayBackDidFinish:(NSNotification*)notification
{
MPMoviePlayerViewController *moviePlayer = [notification object];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:moviePlayer];
[moviePlayer release];
[self.navigationController setNavigationBarHidden:NO animated:YES];
}
- (void) movieFinishedCallback:(NSNotification*) aNotification
{
MPMoviePlayerController *player = [aNotification object];
[[NSNotificationCenter defaultCenter]
removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:player];
[player autorelease];
}
In your - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info method, you can get the url of the video and play it:
#property (nonatomic,retain) MPMoviePlayerController *moviePlayerController;
if ([mediaType isEqualToString:#"public.movie"])
{
NSURL *aURL = [info objectForKey:UIImagePickerControllerMediaURL];//get the url
// and init the video player using this url
_moviePlayerController = [[MPMoviePlayerController alloc] initWithContentURL:aURL];
[self.view _moviePlayerController.view];
_moviePlayerController.useApplicationAudioSession = NO;
_moviePlayerController.fullscreen = YES;
[_moviePlayerController play];
}
Of course, you'll have to import the MediaPlayer.framework
EDIT: A majority of Cocoa projects now use arc, so the above code would require you retain the MPMoviePlayerController instance yourself (as mentioned in this answer).