AVAudioPlayer -> not working - iphone

Audio Player works fine if I initiate it for 20 to 30 times but after that it shows the following error
Error Domain=NSOSStatusErrorDomain Code=-43 "The operation couldn’t be completed. (OSStatus error -43.)"
The code currently I am using is as follows
- (void)playShortSound:(NSString *)fileName type:(NSString *)type
{
if (!isSound) {
return;
}
NSString *soundFilePath =[[NSBundle mainBundle] pathForResource: fileName ofType: type];
NSURL *fileURL = [[[NSURL alloc] initFileURLWithPath: soundFilePath] autorelease];
NSError *error;
AVAudioPlayer *newPlayer =[[AVAudioPlayer alloc] initWithContentsOfURL: fileURL
error: &error];
//newPlayer.numberOfLoops = 0;
newPlayer.volume=1.0;
if (newPlayer == nil){
NSLog(#"%#",[error description]);
//[self playShortSound:fileName type:type];
//return;
}
else{
[newPlayer play];
newPlayer.delegate=self;
}
}
- (void) audioPlayerDidFinishPlaying: (AVAudioPlayer *) player
successfully: (BOOL) completed {
if (completed == YES) {
NSLog(#"Sound Playing complete");
}else {
NSLog(#"error in completion of %#",player.url);
}
}

I was having the same problem and instead of init the player from url i did it from NSData.
NSString *soundFilePath =[[NSBundle mainBundle] pathForResource: fileName ofType: type];
NSData *soundData = [[NSData alloc] initWithContentsOfFile:soundFilePath];
NSError *error;
AVAudioPlayer *newPlayer =[[AVAudioPlayer alloc] initWithData: soundData
error: &error];
It seem to solved my problem hope it does yours.

By calling the method many times you are allocating the instance of AVAudioPlayer newPlayer many times. This will certainly cause you problems because of the memory allocated. Just make sure you release the objects that you own once you are done using them.

Did you set AudioSessionCategory?
{NSError *setCategoryError = nil;
BOOL success = [[AVAudioSession sharedInstance] setCategory: avaudiosessioncategoryplayandrecorderror: &setCategoryError];
}

I was trying to play files in my app by picking them from the iPod library when I got this error code. I found that in my iPod library on the device, I had a duplicate entry for the same song. Music player that comes with iOS was able to play one and not the other. That means one entry was not valid anyway. Probably removed from the device but iTunes/iOS did not do proper housekeeping.
It seems that the reference to the non-playable entry existed within the "Recently Added" playlist which is automatically created by the system. I had picked the same file from "Recently Added" playlist to play in the app.
Side Note: I had removed the file from the manually created playlist in which it existed (removed from the iOS device itself).
In short it seems that the file that I loaded into the AVAudioPlayer instance was not available on the device anymore or its referencing URL did not give back a proper file to play. So common reason for this error would be when the player does not get the file to load based on the URL given to it.

Related

Audio file doesn't play in iPhone 5

I use a code for playing a .caf audio file, the same code works good in an iPhone 4s and an iPad 2 but doesn't play at all in a iPhone 5...
this is the code:
-(IBAction)checkSound:(id)sender
{
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/Lunatic.caf", [[NSBundle mainBundle] resourcePath]]];
NSLog(#"%#",url);
NSError *error;
self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
self.audioPlayer.numberOfLoops = 0;
self.audioPlayer.volume = 1;
NSLog(#"log audioplayer: %#",audioPlayer);
if (audioPlayer != nil)
{
[self.audioPlayer prepareToPlay];
[self.audioPlayer play];
}
if (audioPlayer.playing == NO)
{
NSLog(#"not playing, error: %#",error);
}
if([[NSFileManager defaultManager] fileExistsAtPath:#"file://localhost/var/mobile/Applications/0D3F5169-8DB1-4398-A09A-DB2FBADF57EF/myApp.app/Lunatic.caf"])
{
NSLog(#"file exist");
}
else
{
NSLog(#"file doesn't exist");
}
}
and this is the log output:
2013-08-07 20:05:52.694 myApp[7006:907] file://localhost/var/mobile/Applications/0D3F5169-8DB1-4398-A09A-DB2FBADF57EF/myApp.app/Lunatic.caf
2013-08-07 20:05:52.697 myApp[7006:907] log audioplayer: (null)
2013-08-07 20:05:52.701 myApp[7006:907] not playing, error: Error Domain=NSOSStatusErrorDomain Code=-43 "The operation couldn’t be completed. (OSStatus error -43.)"
2013-08-07 20:05:52.703 myApp[7006:907] file doesn't exist
As you can see the audioplayer log gives "null" and the error log says error -43....
but I repeat... with iphone 4s everything works good....
Any clue why is this happening? Did they change something with audio in iPhone 5? Could it be a setting in my iPhone 5 that's preventing the sound to play? Any help would be greatly appreciated
Have you called [audioPlayer prepareToPlay] prior to calling play? Also have you double checked the audioRoutes to ensure it is playing out of the proper channel?
Two good sanity checks are to:
1.) Call [audioPlayer isPlaying] and see if it returns yes or no after you call play.
2.) Set the AVAudioPlayerDelegate and wait for the callback on audioPlayerDidFinishPlaying: and see if it gets called after the length of your audio.
http://developer.apple.com/library/ios/#documentation/AVFoundation/Reference/AVAudioPlayerClassReference/Reference/Reference.html
EDIT:
Since you're file actually isn't playing, that most likely means you have something wrong with the path you're calling.
Print out your path with an NSLog and also check to see if the file actually exists using:
if([[NSFileManager defaultManager] fileExistsAtPath:yourPath])
{
}

Sound and new images fail to load in View after my app runs for about 30 minutes

I'm working on a game, that at first seem too run fine, but.......
after it runs a long time the sound first stops to work,
[[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error]; returns a null and a little while later when I try to set a view equal to a new image, by view.image=, I get a error in my console that says to many files open,
ImageIO: CGImageRead_mapData 'open' failed '/Users/deno/Library/Application Support/iPhone Simulator/5.1/Applications/5A0C777C-70D1-4AA0-8D7B-04A1F734C932/cPetCakes.app/twinkles04fin32.png'
error = 24 (Too many open files)
right now I creat a new I'm creating a new AVAudioPlayer object each time a sound is played. Should I be re-using the object or some how freeing it??? Since I was not using a alloc, I was thinking that the object would be freed automatcly???
Code for sound
-(void) PlaySound: (NSString *) name
{
NSURL *url;
if ( [name compare:#"chasdog"]==0)
url = [[NSBundle mainBundle]
URLForResource:name
withExtension:#"wav"];
else
url = [[NSBundle mainBundle]
URLForResource:name
withExtension:#"mp3"];
NSError *error;
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
audioPlayer.volume=1.0;
audioPlayer.numberOfLoops= 0;
[audioPlayer play];
audioPlayer.delegate = self;
}
code that no longer loads in new images
self.image=gPetCakeB[gGame->mPetCakeId];
In the player delegate it's needed to release the player once it's stopped playing:
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag {
[player release];
}

Whats the simplest way to play a looping sound?

What is the simplest way to play a looping sound in an iPhone app?
Probably the easiest solution would be to use an AVAudioPlayer with the numberOfLoops: set to a negative integer.
// *** In your interface... ***
#import <AVFoundation/AVFoundation.h>
...
AVAudioPlayer *testAudioPlayer;
// *** Implementation... ***
// Load the audio data
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:#"sample_name" ofType:#"wav"];
NSData *sampleData = [[NSData alloc] initWithContentsOfFile:soundFilePath];
NSError *audioError = nil;
// Set up the audio player
testAudioPlayer = [[AVAudioPlayer alloc] initWithData:sampleData error:&audioError];
[sampleData release];
if(audioError != nil) {
NSLog(#"An audio error occurred: \"%#\"", audioError);
}
else {
[testAudioPlayer setNumberOfLoops: -1];
[testAudioPlayer play];
}
// *** In your dealloc... ***
[testAudioPlayer release];
You should also remember to set the appropriate audio category. (See the AVAudioSession setCategory:error: method.)
Finally, you'll need to add the AVFoundation library to your project. To do this, alt click on your project's target in the Groups & Files column in Xcode, and select "Get Info". Then select the General tab, click the + in the bottom "Linked Libraries" pane and select "AVFoundation.framework".
The easiest way would be to use an AVAudioPlayer set to an infinite number of loops (or finite if that's what you need).
Something like:
NSString *path = [[NSBundle mainBundle] pathForResource:#"yourAudioFileName" ofType:#"mp3"];
NSURL *file = [[NSURL alloc] initFileURLWithPath:path];
AVAudioPlayer *_player = [[AVAudioPlayer alloc] initWithContentsOfURL:file error:nil];
[file release];
_player.numberOfLoops = -1;
[_player prepareToPlay];
[_player play];
This will simply loop whatever audio file you have specified indefinitely.
Set the number of loops to any positive integer if you have a finite number of times you want the audio file to loop.
Hope this helps.
Cheers.

NSOSStatusError

I am try to play a number of audios in my app and it is working fine upto 3 times.
But when i am trying to play in 4th time it shows the error . Error Domain=NSOSStatusErrorDomain Code=-43 "The operation couldn’t be completed. (OSStatus error -43.)" .the code is
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/Sun.wav", [[NSBundle mainBundle] resourcePath]]];
NSError *error;
AudioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
AudioPlayer.numberOfLoops = 0;
AudioPlayer.volume=1.0;
if (AudioPlayer == nil)
{
NSLog([error description]);
}
else
[AudioPlayer play];
Anybody figure it out before..?
You can use the macerror command line utility to find out what an OSStatus code is:
macerror -43
Output:
Mac OS error -43 (fnfErr): File not found
i.e. the file you tried to use doesn't exist.
Looks like you aren't releasing the AudioPlayer object. So the fact you can play three times is probably related to the number of open files you can have in the AVAudioPlayer object.
look into the delegate methods for AVAudioPlayer: specifically
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
- (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)error
you'll want to do something like
(in your main code)
AudioPlayer.delegate = self;
then add function like
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
[player release];
}
I'm sure you can figure out the rest.

AVAudioPlayer only initializes with some files

I'm having trouble playing some files with AVAudioPlayer. When I try to play a certain m4a, it works fine. It also works with an mp3 that I try. However it fails on one particular mp3 every time (15 Step, by Radiohead), regardless of the order in which I try to play them. The audio just does not play, though the view loading and everything that happens concurrently happens correctly. The code is below. I get the "Player loaded." log output on the other two songs, but not on 15 Step. I know the file path is correct (I have it log outputted earlier in the app, and it is correct). Any ideas?
NSData *musicData = [NSData dataWithContentsOfURL:[[NSURL alloc] initFileURLWithPath:[[NSBundle mainBundle] pathForResource:[song filename] ofType:nil]]];
NSLog([[NSBundle mainBundle] pathForResource:[song filename] ofType:nil]);
if(musicData)
{
NSLog(#"File found.");
}
self.songView.player = [[AVAudioPlayer alloc] initWithData:musicData error:nil];
if(self.songView.player)
{
NSLog(#"Player loaded.");
}
[self.songView.player play];
NSLog(#"You should be hearing something now.");
Sorry for entering the party so late. Just want to post a tip so that It will be useful for any person referring this in the future.
A small correction to shaggy frog's answer. The correct usage would be:
NSError *anError = nil;
anAVAudioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:someURL] error:&anError];
if (!anAVAudioPlayer) {
NSLog(#"localizedDescription : %#", [anError localizedDescription]);
}
NSData *musicData = [NSData dataWithContentsOfURL:[[NSURL alloc] initFileURLWithPath:[[NSBundle mainBundle] pathForResource:[song filename] ofType:nil]]];
Here, is musicData nil for the problem case?
Also:
self.songView.player = [[AVAudioPlayer alloc] initWithData:musicData error:nil];
You shouldn't pass nil for methods that take an NSError object. Likely it will shed more light on your problem if you use it correctly:
NSError* error = nil;
self.songView.player = [[AVAudioPlayer alloc] initWithData:musicData error:&error];
if (error)
{
NSLog(#"Error with initWithData: %#", [error localizedDescription]);
}