Playing downloaded video data with AVPlayer? - iphone

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...

Related

How can i play video (By Name) from document directory ?

In my application i store my video in document directory with name is 'video2.MOV' and i want to play it.
Here problem is that i am not able to get this video (name is 'video2.MOV') from document directory.
My Code :
-(void)playVideo:(NSTimer *)theTimer
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:#"video2.MOV"];
NSLog(#"filePath - %#",filePath);
NSString *content = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:NULL];
NSLog(#"contentPath - %#",content);
MPMoviePlayerViewController *videoPlayerView = [[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL URLWithString:content]];
[[CCDirector sharedDirector] presentMoviePlayerViewControllerAnimated:videoPlayerView];
[videoPlayerView.moviePlayer play];
}
In console, each time i got contentPath is NULL, so may be i am not able to play video.
Here, What is my mistake. please give me suggestion on this issue.
Try this:
- (NSString*)GetDocumentFilePath:(NSString*)filename
{
NSLog(#"%#",filename);
// NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); //1
NSString *documentsDirectory = [paths objectAtIndex:0]; //2
NSString* file = [[NSString alloc]initWithFormat:#"%#",filename];
NSString* path = [documentsDirectory stringByAppendingPathComponent:file];
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath: path]) //4
{
//NSString *bundle = [[NSBundle mainBundle] pathForResource:filename ofType:#"plist"]; //5
//[fileManager copyItemAtPath:bundle toPath:path error:&error]; //6
}
return path;
}
and get file path like this:
NSURL *URL = [NSURL fileURLWithPath:[self GetDoucmentPath:path]];
MPMoviePlayerController* theMovie=[[MPMoviePlayerController alloc] initWithContentURL:pptURL];
theMovie.scalingMode=MPMovieScalingModeAspectFill;
theMovie.view.frame = CGRectMake(60, 20, 700, 500);
theMovie.view.center = self.view.center;
//[self.view addSubview:theMovie.view];
// Register for the playback finished notification.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(onStop)
name:MPMoviePlayerPlaybackDidFinishNotification
object:theMovie];
// Movie playback is asynchronous, so this method returns immediately.
[self.view addSubview:theMovie.view];
[theMovie play];
Hope it Helps!!
Instead of using content use filePath instead to get to the movie file:
MPMoviePlayerViewController *videoPlayerView = [[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL fileURLWithPath:filePath]];

save the audio from url locally for play later

How can i save the audio from url locally for play later. I can stream the audio using avplayer but can't save it locally and play later .I tried with avurlasset. Can anyone help me?
This is my code by which i tried to save locally:
here i streamed the audio using avplayer
//code for saving the locally
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([keyPath isEqualToString:#"status"])
{
AVPlayerItem * item = (AVPlayerItem *)object;
if (item.status == AVPlayerItemStatusReadyToPlay)
{
NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *myPathDocs = [documentsDirectory stringByAppendingPathComponent: #"audio.m4a"];
asset=player.currentItem.asset;
NSURL *url1 = [NSURL fileURLWithPath:myPathDocs];
// 5 - Create exporter
AVAssetExportSession *assetEx = [[AVAssetExportSession alloc] initWithAsset:player.currentItem.asset presetName:AVAssetExportPresetAppleM4A];//tried with asset2 also
assetEx.outputURL=[NSURL fileURLWithPath:myPathDocs];
assetEx.outputFileType = AVFileTypeAppleM4A;
assetEx.shouldOptimizeForNetworkUse = YES;
[assetEx exportAsynchronouslyWithCompletionHandler:^{
int status = assetEx.status;
dispatch_async(dispatch_get_main_queue(), ^{
[self exportDidFinish:assetEx];
});
}];
}
}
}
but there is no file created in the documents directory.

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

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.

MPMoviePlayerController doesn't play newly saved video file

I'm using an imagePickerController to record video. In the imagePickerController:didFinishPickingMediaWithInfo: function I'm trying to set the video to a previously defined MPMoviePlayerController:
if ([mediaType isEqualToString:(NSString *)kUTTypeMovie]){
NSURL *movieUrl = [info objectForKey:UIImagePickerControllerMediaURL];
[self.moviePlayer setContentURL:movieUrl]];
}
This is working fine and the video is indeed playing.
But I want to save the file for later use. When I do this and use the saved file for the moviePlayer, nothing happens:
I've tried this (saving the data to a new file)
NSString *directory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *newPath = [directory stringByAppendingPathComponent:#"myMovie.mov"];
NSData *videoData = [NSData dataWithContentsOfURL:movieUrl];
[videoData writeToFile:newPath atomically:NO];
[self.moviePlayer setContentURL:[NSURL URLWithString:newPath]];
or this (copying the temp video file to my document folder)
NSString *directory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *newPath = [directory stringByAppendingPathComponent:#"myMovie.mov"];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error = nil;
[fileManager copyItemAtPath:[videoUrl path] toPath:newPath error:&error];
[self.moviePlayer setContentURL:[NSURL URLWithString:newPath]];
Without any success, even though the file at newPath does exist... What am I doing wrong?
Ok I finally found the issue. The problem was not in fact with the MPMoviePlayerController but with the line:
[self.moviePlayer setContentURL:[NSURL URLWithString:newPath]];
I fixed it by replacing that line with:
[self.moviePlayer setContentURL:[NSURL fileURLWithPath:newPath isDirectory:NO]];
Hope that will help someone else!
use the code below:
NSData *movieData;
NSError *dataReadingError = nil;
movieData = [NSData dataWithContentsOfURL: movieURL options:NSDataReadingMapped error:&dataReadingError];
if(movieData != nil)
NSLog(#"Successfully loaded the data.");
else
NSLog(#"Failed to load the data with error = %#", dataReadingError);

Play a video before it finish to download

In my app i download an video from the web and i want to play will it downloaded.
I am using :
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;
to save the data i get to a file with:
if (currentBytes == 0) {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *fileName = [NSString stringWithFormat:#"%#.mp4", [[paths objectAtIndex:0] stringByAppendingPathComponent:#"1"]];
[[NSFileManager defaultManager] createFileAtPath:fileName contents:data attributes:nil];
handle = [[NSFileHandle fileHandleForUpdatingAtPath:fileName] retain];
[handle seekToEndOfFile];
}else {
if (!data) {
NSLog(#"");
}
[handle writeData:data];
}
currentBytes++;
and then when i got to 50% from the video that was downloaded i want to start play it with AVPlayer :
if ((percentComplete > 50)&&(flag == NO)) {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *fileName = [NSString stringWithFormat:#"%#.mp4", [[paths objectAtIndex:0] stringByAppendingPathComponent:#"1"]];
audioPlayer = [[AVPlayer playerWithURL:[NSURL fileURLWithPath:fileName]] retain];
avPlayerLayer = [[AVPlayerLayer playerLayerWithPlayer:audioPlayer] retain];
[avPlayerLayer setFrame:self.view.bounds];
[audioPlayer play];
[[self.view layer] addSublayer:avPlayerLayer];
flag = YES;
}
any idea why it won't work ?
you can't play a video like that. if you are downloading the way you do , you need to wait until finish.
if we think about the way you want , you are talking about streaming a video to your application. so to do that here's an example : http://geobray.com/2010/03/26/live-tv-streaming-to-iphone-with-http/
and it shows how to create streaming files i guess.
hope this helps..