save the audio from url locally for play later - iphone

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.

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]];

Could not save .mp4 video file to iphone camera roll?

I received the video file contents in the format of NSData and I am playing that file in MPMoviePlayerController successfully with following code
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *FileExtension=[[NSString alloc]init];
if([contentType hasPrefix:#"video"] || [contentType isEqualToString:#"application/video"]) {
FileExtension=#"mov";
//FileExtension=#"mp4";
}
else
{
FileExtension=[contentType lastPathComponent];
}
//appFile is type of NSString.
appFile = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"MyFile.%#",FileExtension]];
//videoData is type of NSData
[videoData writeToFile:appFile atomically:YES];
NSURL *fileURL = [NSURL fileURLWithPath:appFile isDirectory:NO];
moviePlayerController = [[MPMoviePlayerController alloc] initWithContentURL:fileURL];
moviePlayerController.view.frame = self.view.bounds;
moviePlayerController.movieSourceType = MPMovieSourceTypeFile;
moviePlayerController.fullscreen = YES;
moviePlayerController.shouldAutoplay=NO;
[self.view addSubview:moviePlayerController.view];
[moviePlayerController prepareToPlay];
but I am unable to write/save this video file to camera roll,this is my code for writing code to the camera roll.
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
NSURL *filePathURL = [NSURL fileURLWithPath:appFile isDirectory:NO];
if ([library videoAtPathIsCompatibleWithSavedPhotosAlbum:filePathURL]) {
[library writeVideoAtPathToSavedPhotosAlbum:filePathURL completionBlock:^(NSURL *assetURL, NSError *error){
if (error) {
NSLog(#"Not success");
} else {
NSLog(#"success");
}
}];
}
this code is work fine when I set mimeType/file_format as .mov & .3Gp but I have problem related to save video to the camera roll when mimeType/file_format as .mp4 file.
You can convert your .mp4 to .mov if you change your appFile this way:
Your code:
appFile = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"MyFile.%#",FileExtension]];
New code:
appFile = [documentsDirectory stringByAppendingPathComponent:#"MyFile.mov"];
The SO automatically converts .mp4 to .mov

NOt able to convert from MPMediaItem(mp3 song) to NSData

I have tried following code :
These is my delegate method of MPMediPickerController :
- (void) mediaPicker: (MPMediaPickerController *) mediaPicker didPickMediaItems: (MPMediaItemCollection *) mediaItemCollection {
// Dismiss the media item picker.
[self dismissModalViewControllerAnimated: YES];
NSLog(#"%# %d",mediaItemCollection,mediaItemCollection.count);
NSArray *newMediaItem= [mediaItemCollection items];
MPMediaItem *item=[[newMediaItem objectAtIndex:0] retain];
[self uploadMusicFile:item];
}
This is my custom method MPMediaItem to NSData:
- (void) uploadMusicFile:(MPMediaItem *)song
{
NSURL *url = [song valueForProperty: MPMediaItemPropertyAssetURL];
AVURLAsset *songAsset = [AVURLAsset URLAssetWithURL: url options:nil];
AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset: songAsset
presetName: AVAssetExportPresetPassthrough];
exporter.outputFileType = #"public.mpeg-4";
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *exportFile = [documentsDirectory stringByAppendingPathComponent:
#"exported.mp4"];
NSURL *exportURL = [[NSURL fileURLWithPath:exportFile] retain];
exporter.outputURL = exportURL;
[exporter exportAsynchronouslyWithCompletionHandler:
^{
NSData *data = [NSData dataWithContentsOfFile: [documentsDirectory
stringByAppendingPathComponent: #"exported.mp4"]];
NSLog(#"%#",data);
}];
}
I am getting "null" in NSlog.
I have also check this post :
how to convert nsdata to MPMediaitem song iOS Sdk
but not getting solution.
I am using xcode 4.6 and ios 6.1.
Can any one tell me what is wrong here?

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

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