Playing a video file saved in the app's documents directory - iphone

I have a video file saved in my app's local directory in the documents folder. I want to playback the file when the user clicks on the item in an embedded table view I created. My code for playing back the video is as follows:
NSString* documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString* path = [documentPath stringByAppendingPathComponent:#"DemoRecording.mp4"];
NSURL* movieURL = [NSURL fileURLWithPath: path];
[player.view setFrame: self.view.bounds];
[self.view addSubView: player.view];
[player play];
MPMoviePlayerViewController* moviePlayer = [[MPMoviePlayerViewController alloc] initWithContentURL: movieURL];
[self presentMoviePlayerViewControllerAnimated: moviePlayer];
The video doesn't play back. The path is correct and the file exists there.
I know this is a repetitive question. I have referred to these links:
Playing a Downloaded Video from the Documents Directory with Cocoa-Touch
MPMoviePlayer load and play movie saved in app documents
But couldn't find a definitive answer.
Please help me out on this one. I am using iOS 5.1.1, if that changes anything.
EDIT:
It does work. I had forgotten to pass the URL to the movie player.

you can play Video from Document Directory like this way:-
-(IBAction)playVideo
{
NSURL *vedioURL;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSArray *filePathsArray = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:documentsDirectory error:nil];
NSLog(#"files array %#", filePathsArray);
NSString *fullpath;
for ( NSString *apath in filePathsArray )
{
fullpath = [documentsDirectory stringByAppendingPathComponent:apath];
vedioURL =[NSURL fileURLWithPath:fullpath];
}
NSLog(#"vurl %#",vedioURL);
MPMoviePlayerViewController *videoPlayerView = [[MPMoviePlayerViewController alloc] initWithContentURL:vedioURL];
[self presentMoviePlayerViewControllerAnimated:videoPlayerView];
[videoPlayerView.moviePlayer play];
}
NOTE
Please note that don't Forget to include requested Framework or connect Delegate

The mistake in you was you missed / before DemoRecording.mp4
It should be
NSString* path = [documentPath stringByAppendingPathComponent:#"/DemoRecording.mp4"];
Also you are writing player statements before declaring it.

Related

Playing downloaded video data with AVPlayer?

I'm trying to download video from server, store it and then play it with AVPlayer. What I have so far is:
I use AFNetworking to download video data and I have it stored as NSData inside my NSDictionary of resources
I create my TargetOverlayView which is displaying resources content (images, text, playing audio and ...video - hopefully soon)
When it comes to show video I wrote method:
(void)playVideo:(NSData*)video{
NSLog(#"TargetOverlayView: playVideo");
if (!video) {
NSLog(#"TargetOV: nothing to play");
[vPlayerLayer removeFromSuperlayer];
vPlayerLayer = nil;
vPlayer = nil;
return;
}
//save nsdata into file
NSLog(#"{SAVE} saving video data into file...");
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"video.3gp"]];
[fileManager createFileAtPath:filePath contents:video attributes:nil];
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithURL:[NSURL URLWithString:#"http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8"]];
vPlayer = [[AVPlayer alloc] initWithPlayerItem:playerItem];//[AVPlayer playerWithPlayerItem:playerItem];
vPlayerLayer = [[AVPlayerLayer alloc] init];//[AVPlayerLayer playerLayerWithPlayer:vPlayer];
vPlayerLayer.player = vPlayer;
[vPlayerLayer setFrame:self.frame];
[vPlayerLayer setBackgroundColor:[[UIColor purpleColor] CGColor]];
[self.layer addSublayer:vPlayerLayer];
[vPlayer addObserver:self forKeyPath:#"status" options:0 context:NULL];
}
I added also observer so I know when to play it:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if ([keyPath isEqualToString:#"status"]) {
if (vPlayer.status == AVPlayerStatusReadyToPlay) {
NSLog(#"video ready!");
[vPlayer play];
} else if (vPlayer.status == AVPlayerStatusFailed) {
NSLog(#"vide faield: %#", [vPlayer.error localizedDescription]);
}
}
}
I wish I could just download mp4 and 3gp videos from server and play them, but only when I give this: http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8 Apple given link it works... I cannot manage to play downloaded 3gp data from filepath (is it possible at all to play 3gp or other formats?). Is there any way to play downloaded video? I don't need streaming (not roght now at least). Every help very appreciated.
EDIT:
I changed that bit about making file to:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir = [paths objectAtIndex:0];
NSString *filePath = [docDir stringByAppendingPathComponent:#"video.mp4"];
[video writeToFile:filePath atomically:YES];
and still not working...
EDIT2:
I typed in link to this file on server - then it worked (only works with mp4), but I need to download data and play vide from it, not just link to the resource...

Video is not playing using MPMoviePlayerContrller

how to play a video in iPhone sdk using MPMoviePlayerViewController,here i capture video through device and save that particular video in documents directory .
please tell me any one....
Get Document Directory Path:
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
Then you can use any of the directory listing APIs of NSFileManager.
NSError * error;
NSArray * directoryContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:documentsDirectory error:&error];
Now You have all contents at Directory Path (all videos stored) in array
NSURL *videoURL = [NSURL UrlWithString:[NSString stringWithFormat:#"%#/%#",documentsDirectory,[directoryContents objectAtIndex:0]]]; //check which url u want play as video name is in nsarray i have selected one random video name.
Use MovieControllerPlayer instance to play url:
MPMoviePlayerViewController *mpViewController = [[MPMoviePlayerViewController alloc] initWithContentURL:videoURL];
[self presentMoviePlayerViewControllerAnimated:mpViewController];
[mpViewController.view setCenter:yourView.center];
//[mpViewController release];
Hope useful.

How to play video using MPMoviePlayerController?

I am using the following code to play the video using the MPMoviePlayerController , but the video is not played. Can anyone tell me why ?
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:#"/one.mp4"];
NSString *mediaPath = [[[NSBundle mainBundle]resourcePath] stringByAppendingPathComponent:filePath];
MPMoviePlayerController *moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL fileURLWithPath:mediaPath]];
[[moviePlayer view] setFrame:[[self view] bounds]];
[[self view] addSubview: [moviePlayer view]];
moviePlayer.scalingMode = MPMovieScalingModeAspectFit;
[moviePlayer play];
It's pretty weird, but it seems to work okay if you make your MPMoviePlayerController a property instead of a local variable. Seems something is going on behind the scenes. I'm thinking it's related to ARC. Are you using ARC?
It's also an issue that you've over-appended your path:
// You've already got the full path to the documents directory here.
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:#"/one.mp4"];
// Now you're appending the full path to the documents directory to your bundle path
NSString *mediaPath = [[[NSBundle mainBundle]resourcePath] stringByAppendingPathComponent:filePath];
When I run your code in the simulator, the path looks like this:
/Users/mlong/Library/Application Support/iPhone
Simulator/5.1/Applications/8CFB9B94-BD6A-442C-A525-573FE343506D/VidoePlayer.app/Users/mlong/Library/Application Support/iPhone
Simulator/5.1/Applications/8CFB9B94-BD6A-442C-A525-573FE343506D/Documents/one.mp4
It should just be this:
/Users/mlong/Library/Application Support/iPhone
Simulator/5.1/Applications/8CFB9B94-BD6A-442C-A525-573FE343506D/Documents/one.mp4
So just delete this line:
NSString *mediaPath = [[[NSBundle mainBundle]resourcePath] stringByAppendingPathComponent:filePath];
And then change your player instantiation to this:
_moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL fileURLWithPath:filePath]];
[[_moviePlayer view] setFrame:[[self view] bounds]];
[[self view] addSubview: [_moviePlayer view]];
_moviePlayer.scalingMode = MPMovieScalingModeAspectFit;
[_moviePlayer play];
So you should add the MPMoviePlayerController as a property of your containing view controller.
All right, there is a big difference between the app bundle and the documents directory. I suggest you take a look at that.
First of all, Where is the video stored?
If your video is in the documents directory, don't append the documents directory path to the bundle path.
Just try with the filePath variable:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:#"/one.mp4"];
MPMoviePlayerController *moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL filePath]];
However, if the file is in the app bundle (you added it to your project in XCode), you should use what is in jinx response.
moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:url];
[moviePlayer.view setFrame:CGRectMake(//set rect frame)];
moviePlayer.controlStyle = MPMovieControlStyleDefault;
moviePlayer.shouldAutoplay=YES;
moviePlayer.repeatMode = NO;
[moviePlayer setFullscreen:YES animated:NO];
[moviePlayer prepareToPlay];
[self.view addsubview:movieplayer.view];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(MPMoviePlayerLoadStateDidChange:) name:MPMoviePlayerLoadStateDidChangeNotification object:nil];
- (void)MPMoviePlayerLoadStateDidChange:(NSNotification *)notification {
if ((moviePlayer.loadState & MPMovieLoadStatePlaythroughOK) == MPMovieLoadStatePlaythroughOK) {
//add your code
}
}
Try asking your bundle directly and not setting up the file path manually
NSString *path = [[NSBundle mainBundle] pathForResource:#"name" ofType:#"mov"];
Player is initialized with the URL of the video which we want to be played (It can be either a path of local file of a device or a live URL.) after that player is added as a sub view of current view.
Supported video formats by MPMoviePlayerController class are following
.mov .mpv .3gp .mp4
I am not sure how much you this article would help you out. I am new to this. I worked on the step by step instructions provided in this article
MPMoviePlayerController *moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL fileURLWithPath:mediaPath]];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(movieFinishedCallback:) name:MPMoviePlayerPlaybackDidFinishNotification object:moviePlayer];
hope Help it
It took me few mins to debug the problem but the answer is quite simple. Here is the deal:
If you want to MPMoviePlayerViewController to play from a web URL use this:
NSURL *url = [NSURL URLWithString:#"https://www.test.com/anyMovie.mp4"];
And if you want MPMoviePlayerViewController to play it from App Bundle use this:
NSString *moviePath = [[NSBundle mainBundle] pathForResource:#"anyMovie" ofType:#"m4v"];
NSURL *url = [NSURL fileURLWithPath:moviePath];
The Rest of it goes the same, except you have to set this property "movieSourceType" as follows:
MPMoviePlayerViewController *moviePlayerView = [[MPMoviePlayerViewController alloc] initWithContentURL:url];
moviePlayerView.moviePlayer.movieSourceType = MPMovieSourceTypeFile;
[self presentViewController:moviePlayerView animated:YES completion:^{}];

Saving/retrieving video files in iOS

I've been browsing around but couldn't find a solution to my problem. I'm trying to save some video files to my application's directory I do this as follows:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
// the path to write file
NSString *appFile = [documentsDirectory stringByAppendingPathComponent:#"myFile"];
NSLog(#"%#",appFile);
[[NSUserDefaults standardUserDefaults] setValue:appFile forKey:#"videoURL"];
[[NSUserDefaults standardUserDefaults]synchronize];
NSURL *videoURL = [info objectForKey:UIImagePickerControllerMediaURL];
NSData *webData = [NSData dataWithContentsOfURL:videoURL];
[webData writeToFile:appFile atomically:YES];
My question is, is this the proper way of saving the movie file and if yes how do I convert the NSData to a file that can be played back via MPMoviePlayer? Thanks for your help.
PS. I really don't want to use the photo library as the app is likely to hold a fair amount of videos.
If you really want to save it in the documents of your app, you'll have to use NSFileManager
it would probably look like something like that
NSString* completeFileName = [NSString stringWithFormat:#"%#",movieName];
NSString* filename = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:completeFileName];
[[NSFileManager defaultManager] createFileAtPath:filename contents:yourMovieData attributes:nil];
You also might need to use NSFileHandle
To read the video in your MPMoviePlayer, if think you can make an NSURL like this
[NSURL fileURLWithPath:path isDirectory:NO];
then you give that url to your MPMoviePlayer.
I hope this will help you.

save mp3 data in file on iphone

I'm developing an iPhone application and i need to download and Save mp3 media on the iPhone and play it,
I fished the downloading work and i put the data in NSMutableData variable But How can i save these data as mp3 file
any advice :)
If you want to save it to your applications Documents directory with a .mp3 file extension you can use the following:
NSString *mp3FileName = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask,
YES) lastObject]
stringByAppendingPathComponent:#"MyFileName.mp3"];
[[NSFileManager defaultManager] createFileAtPath:mp3FileName
contents:mp3Data
attributes:nil];
Where mp3Data is your NSMutableData. I use code similar to the above for saving PDF documents, custom file formats, jpgs and all sorts. I've not had cause to try mp3 yet but there's no reason why it shouldn't.
To read the file back into NSData to send to AVAudioPlayer:
NSString *mp3FileName = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask,
YES) lastObject]
stringByAppendingPathComponent:#"MyFileName.mp3"];
NSData *mp3Data = [NSData dataWithContentsOfFile:mp3FileName];
avAudioPlayer.data = mp3Data;
Above para of code untested, never had cause to use sounds in my apps.
here is the correct soulution appending up on #Diziet comment
'//prepare data to save in file
NSData *fileData=[[NSData alloc]initWithData:(NSData *)receivedData];
NSString *mp3FileName = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES) lastObject]stringByAppendingPathComponent:#"MyFileName.mp3"];
//create the file
[[NSFileManager defaultManager] createFileAtPath:mp3FileName contents:receivedData attributes:nil];
//load the file for playing
NSString *FileNamePath = [[NSString alloc] initWithString:#"MyFileName.mp3"];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *appSettingsPath = [documentsDirectory stringByAppendingPathComponent:FileNamePath];
NSURL *url=[[NSURL alloc]initWithString:appSettingsPath ];
player=[[AVAudioPlayer alloc]initWithContentsOfURL:url error:NULL];
player.delegate=self;
[player play];'