i'm trying to design audio streaming app everything is working, but i don't know how to download audio file to the device and read it afterword.
Download audio to document directory.
play it back from document directory.
Added code:
NSArray *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentDirectory = [path firstObject];
NSString *filePath = [documentDirectory stringByAppendingPathComponent:#"evet.mp3"];
// UIImage *cellImage = [[UIImage alloc] initWithContentsOfFile:filePath];
NSLog(#"%#",filePath);
NSError *error;
NSData *_objectData = [NSData dataWithContentsOfURL:[NSURL URLWithString:filePath]];
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:_objectData error:&error];
[audioPlayer play];
Based on the code you posted try this.
Change
NSData *_objectData = [NSData dataWithContentsOfURL:[NSURL URLWithString:filePath]];
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:_objectData error:&error];
to this:
NSURL *fileURL = [NSURL fileURLWithPath:filePath isDirectory:NO];
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:&error];
AVAudioPlayer wants a URL object (which needs to be a local URL not a remote web address, hence fileURLWithPath:) not the data itself.
You were trying to give the NSData itself to the audio player.
Fetch your audio file in document directory
- (NSString *)getCacheDirectoryPathForAudio:(NSString *)filePath
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); //create an array and store result of our search for the documents directory in it
NSString *documentsDirectory = [paths objectAtIndex:0]; //create NSString object, that holds our exact path to the documents directory
NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.mp3", filePath]]; //add
return fullPath;
}
Initiate player with file path
NSString *pathToSaveAudioString = [self getCacheDirectoryPathForAudio:#“filename”];
NSURL* url = [NSURL fileURLWithPath:pathToSaveAudioString];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:pathToSaveAudioString];
if (fileExists) {
NSError* error = nil;
self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
[self.player setDelegate:self];
if(!self.player)
{
NSLog(#"Error creating player: %#", error);
}
}
else
{
NSLog(#“File Not Exist: %#");
}
and play it using
[self.player play];
Use Delegate methods to check status
#pragma mark - AVAudioPlayerDelegate
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
}
- (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)error
{
}
For more details follow
http://iosdeveloperzone.com/2012/10/01/tutorial-playing-audio-with-avaudioplayer/
I have simple code
NSData *D = [self FindDatafromDocument:#"ASDF"];
player = [[AVAudioPlayer alloc] initWithData:D error:nil];
[player setDelegate:self];
[player play];
Method
- (NSData *)FindDatafromDocument:(NSString *)Name {
NSData *IMG;
NSError *error;
NSArray *directoryContents = [[NSArray alloc] init];
directoryContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:[Utility getDocumentDirectory] error:&error];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF contains[c] %#",Name];
NSArray *ArrImages = [directoryContents filteredArrayUsingPredicate:predicate];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *Doc = [paths objectAtIndex:0];
for (NSString *imageName in ArrImages) {
if ([imageName rangeOfString:#".caf"].location != NSNotFound) {
IMG = [[NSFileManager defaultManager] contentsAtPath:[NSString stringWithFormat:#"%#/%#",Doc,imageName]];
}
}
return IMG;
}
Related
I tried to play mp3 file using AVP player. But i couldn't play it..my code is
NSString *fileurl=[FILE_URL_Array objectAtIndex:indexPath.row];
NSArray *parts = [fileurl componentsSeparatedByString:#"/"];
NSString *filename = [parts lastObject];
NSLog(#"file name is %#",filename);
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [NSString stringWithFormat:#"%#/%#", documentsDirectory,filename];
//NSString* documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString* foofile = [documentsDirectory stringByAppendingPathComponent:filename];
NSLog(#"foofile %#",foofile);
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:foofile];
NSLog(#"boolean value is %hhd",fileExists);
if (fileExists)
{
NSURL *audioURL = [NSURL fileURLWithPath:filePath];
NSLog(#"existig url is%#",audioURL);
NSData *urlData =[NSData dataWithContentsOfURL:audioURL];
// NSString *sourcePath =[audioURL path];
//UISaveVideoAtPathToSavedPhotosAlbum(sourcePath,nil,nil,nil);
NSString *filePath = [NSString stringWithFormat:#"%#/%#", documentsDirectory,filename];
[urlData writeToFile:filePath atomically:YES];
audioPlayer = [[AVAudioPlayer alloc]initWithData:urlData error:NULL];
audioPlayer.delegate = self;
[audioPlayer play];
}
but i am unable to play that audio file....Please give your valuable solution.Thanks in advance...
You're currently appending documentsDirectory twice.
NSString *filePath = [NSString stringWithFormat:#"%#/%#", documentsDirectory,filename];
//NSString* documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString* foofile = [documentsDirectory stringByAppendingPathComponent:filename];
Once in filePath, and again in foofile.
Additionally, you seem to be doing a whole bunch of extra processing that you don't need to be doing. You should be able to create the audio player from the initial file url:
NSString *fileurl=[FILE_URL_Array objectAtIndex:indexPath.row];
NSError *error;
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL urlWithString:fileUrl] error:&error];
if (error != nil) {
NSLog(#"Error creating player: %#", error);
}
audioPlayer.delegate = self;
[audioPlayer prepareToPlay];
[audioPlayer play];
I have downloaded a mp3 file but i'm not able to play it. The file is downloaded, i've checked but when i try to play the local file, nothing happens. If i directly play it without downloading it, it plays.
- (IBAction)downloadTrack:(id)sender {
NSData *soundData = [NSData dataWithContentsOfURL:self.song.ticket.url];
NSString *documents = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *filePath = [documents stringByAppendingPathComponent:self.song.slug];
[soundData writeToFile:filePath atomically:YES];
NSURL *urlFile = [NSURL URLWithString:filePath];
AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:urlFile error:nil];
player.numberOfLoops = -1; //Infinite
[player play];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Download
NSString *urlString = #"https://oi.net/songs/5-dope-ski-128k.mp3";
NSURL *url = [[NSURL alloc] initWithString:urlString];
NSData *soundData = [NSData dataWithContentsOfURL:url];
NSString *documents = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *filePath = [documents stringByAppendingPathComponent:#"5-dope-ski-128k.mp3"];
[soundData writeToFile:filePath atomically:YES];
// Play
NSString *filename = #"Ola.mp3";
NSArray *pathArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);
NSString *documentsDirectory = [pathArray objectAtIndex:0];
NSString *yourSoundPath = [documentsDirectory stringByAppendingPathComponent:filename];
NSURL *soundUrl;
if ([[NSFileManager defaultManager] fileExistsAtPath:yourSoundPath])
{
soundUrl = [NSURL fileURLWithPath:yourSoundPath isDirectory:NO];
}
// Create audio player object and initialize with URL to sound
_audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:soundUrl error:nil];
[_audioPlayer play];
}
I want to download or save youtube video in document directory and then play that video using MPMoviePlayerViewController. But I don't know why my code is not working.
I'm using this below code :
prgrma mark- download Or save
-(IBAction)onclick_download:(id)sender
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(#"Downloading Started");
NSString *urlToDownload = #"youtubeurl";
NSURL *url = [NSURL URLWithString:urlToDownload];
NSData *urlData = [NSData dataWithContentsOfURL:url];
if ( urlData )
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
filePath = [NSString stringWithFormat:#"%#/%#", documentsDirectory,#"thefile.mp4"];
//saving is done on main thread
dispatch_async(dispatch_get_main_queue(), ^{
[urlData writeToFile:filePath atomically:YES];
NSLog(#"File Saved !");
});
}
});
}
pragma mark- Play video from document directory
-(IBAction)onclick_playvideolocally:(id)sender
{
[self playvideolocally];
}
-(void)playvideolocally
{
NSURL *videoUrl;
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];
videoUrl =[NSURL fileURLWithPath:fullpath];
}
MPMoviePlayerViewController *videoPlayerView = [[MPMoviePlayerViewController alloc] initWithContentURL:videoUrl];
[self presentMoviePlayerViewControllerAnimated:videoPlayerView];
[videoPlayerView.moviePlayer play];
}
As your link you provided in url is for youtube so it is not downloaded or saved in local
Use this for youtube
Ive used classes from this project: https://github.com/larcus94/LBYouTubeView It works fine for me. I can download youtube videos.
LBYouTubeExtractor *extractor = [[[LBYouTubeExtractor alloc] initWithURL:[NSURL URLWithString:[NSString stringWithFormat:(#"http://www.youtube.com/watch?v=%#"), self.videoID ]] quality:LBYouTubeVideoQualityLarge] autorelease];
[extractor extractVideoURLWithCompletionBlock:^(NSURL *videoURL, NSError *error) {
if(!error) {
NSLog(#"Did extract video URL using completion block: %#", videoURL);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData *data = [NSData dataWithContentsOfURL: videoURL];
NSString *pathToDocs = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *filename = [NSString stringWithFormat:(#"video_%#.mp4"), self.videoID ];
[data writeToFile:[pathTODocs stringByAppendingPathComponent:filename] atomically:YES];
NSLog(#"File %# successfully saved", filename);
});
} else {
NSLog(#"Failed extracting video URL using block due to error:%#", error);
}
}];
I have audio player. I download audio in this way
- (void) song{
if (_index == 0) {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:#"1.mp3"];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:filePath isDirectory:NO];
if (!fileExists) {
NSString *stringURL = #"https://drive.google.com/uc?export=download&id=0B6zMam2kAK39VHZ1cUZsM3BhQXM";
NSURL *url = [NSURL URLWithString:stringURL];
NSData *urlData = [NSData dataWithContentsOfURL:url];
[urlData writeToFile:filePath atomically:YES];
}
self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL URLWithString:filePath] error:nil];
}
}
But when audio downloading I can’t do anything. User interface stop.
How can download audio and do anything in user interface simultaneously?
Give your method a block to execute when finished, then run the download code in the background. Lets say, for your case the output is a local file with the downloaded content:
- (void)songWithCompletion:(void (^)(NSString *))completion {
NSString *filePath = [self song];
dispatch_async(dispatch_get_main_queue(), ^{
if (completion) completion(filePath);
});
}
Change the song method to return filePath. Don't ever call it directly, only via songWithCompletion.
- (void)song {
// ... your code from the OP
// don't allocate the audio player here, just return the local file
return filePath;
}
Call it like this...
[self songWithCompletion:^(NSString *filePath) {
if (filePath) {
self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL URLWithString:filePath] error:nil];
// you should really handle audio player error here, too
} else {
// handle error
}
}];
You are downloading the file in the main thread. you need to make an asynchronous call in order to avoid stopping UI.
-(void)downloadAudio
{
NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:#"https://drive.google.com/uc?export=download&id=0B6zMam2kAK39VHZ1cUZsM3BhQXM"]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if (theConnection) {
receivedData = [NSMutableData data] ;
} else {NSLog(#"no connection!");
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
NSLog(#"Succeed! Received %d bytes of data",[receivedData length]);
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
//NSLog(#"%#", [documentPaths objectAtIndex:0]);
NSString *documentDirectoryPath = [documentPaths objectAtIndex:0];
NSString *folderPath = [documentDirectoryPath stringByAppendingPathComponent:#"audioFile.mp3"];
[receivedData writeToFile:folderPath atomically:YES];
NSURL *soundURL = [NSURL fileURLWithPath:folderPath];
NSError *error;
if ([[NSFileManager defaultManager] fileExistsAtPath:folderPath]) {
player = [[AVAudioPlayer alloc]initWithContentsOfURL:soundURL error:&error];
player.volume=0.5;
NSError *error = nil;
if (!error) {
[player play];
NSLog(#"File is playing!");
}
else{
NSLog(#"Error in creating audio player:%#",[error description]);
}
}
else{
NSLog(#"File doesn't exist");
}
}
I have a UITableView displaying a llist f files in the Documents Directory... and I want it to play the audio file in the Documents directory when pressed...
It runs with no errores but doesn't play the audio when pressed...
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *fileName = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%d.caf",indexPath.row+1]];
NSURL *audioURL = [NSURL URLWithString:fileName];
NSData *audioData = [NSData dataWithContentsOfURL:audioURL];
NSError *error;
_audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:audioURL error:&error];
_audioPlayer.delegate = self;
[_audioPlayer play];
}
Change this line:
NSURL *audioURL = [NSURL URLWithString:fileName];
to this:
NSURL *audioURL = [NSURL fileURLWithPath:fileName isDirectory:NO];
And then just do:
if(_audioPlayer == nil)
{
_audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:audioURL error:nil];
}
else
{
_audioPlayer = [self.audioAlert initWithContentsOfURL:audioURL error:nil];
}
To start out, the best way to declare a files path is this
- (NSString *)docsdir {
return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0];
}
in your header, declareNSString *Path;
then, declare the path like this when the view loads
Path = [[self docsdir]stringByAppendingPathComponent:[NSString stringWithFormat:#"%d.caf",indexPath.row+1]];
if (![[NSFileManager defaultManager]fileExistsAtPath:Path]) {
[[NSFileManager defaultManager]copyItemAtPath:[[NSBundle mainBundle]pathForResource:[NSString stringWithFormat:#"%d",indexPath.row+1] ofType:#"caf"] toPath:Path error:nil];
}
now to play it, do this
AVAudioPlayer *player = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:Path] error:&error];
player.delegate = self;
[player play];