I know that this is a similar question to the ARC deprecated code however, I have some old code from NIB days that I am upgrading to Storyboards and in doing so, the code revisions are causing me some issues.
In the code below:
- (void)audioSound {
NSString *path = [[NSBundle mainBundle] pathForResource:#"sound-file" ofType:#"mp3"];
if(theAudioSound)[theAudioSound release];
theAudioSound = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
theAudioSound.volume = 0.30;
[theAudioSound play];
}
I get the ARC problem; After many attempts to find a solution I can only find the following advice.
Delete the 'release'
If I do delete the release - depending on how I delete it - I get the following error messages.
from
if(theAudioSound)[theAudioSound release];
to
if(theAudioSound)[theAudioSound];
the Error is "Expected Identifier"
and from
if(theAudioSound)[theAudioSound];
to
if(theAudioSound)theAudioSound;
the Warning is "Expression Result Unused"
if I use the second of the two changes will it work?
and if not; what would I need to do to change the code so that it does work?
Well, release actually releases( decreases the retain count) here, if any object has already has been created. But in ARC, you don't have to release it manually.
I suggest clearing the AVAudioPlayer instance in stead of release, and it will work. So the code will look like:
if(theAudioSound) {
theAudioSound = nil;
}
OR
Simply delete or comment out the line if(theAudioSound)[theAudioSound release]; like:
// if(theAudioSound)[theAudioSound release];
And continue with the rest of codes. Hope this helps.
// if(theAudioSound)[theAudioSound release];
You need to totally comment out that line for this to work.
Actually this is another way of writing following
if(theAudioSound)
{
[theAudioSound release];
}
If you simply delete release, that would generate a syntax error.
"Delete the 'release'" means you don't need to release it. So, you just remove the line or comment in. That's just all I think.
- (void)audioSound {
NSString *path = [[NSBundle mainBundle] pathForResource:#"sound-file" ofType:#"mp3"];
//if(theAudioSound)[theAudioSound release];
theAudioSound = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
theAudioSound.volume = 0.30;
[theAudioSound play];
}
Related
I have an appcelerator module written in Xcode. Everything works, except it throws an error when I try to play a sound file. The code works in Xcode in a standalone app, but not as a module in appcelerator. I am not sure if the sound file is simply not building into the module, or if I have to change the path to something else. Where is the best place to store the sound files? Do I need to adjust the path? Please assist. Below is the playSound method that causes the error.
-(void)playSound:(NSString*)fileName
{
NSString *path = [[NSBundle mainBundle] pathForResource:fileName ofType:#"wav"];
NSURL *soundFileURL = [NSURL fileURLWithPath:path];
_audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:&error];
[_audioPlayer play];
}
I think the module you have used in xcode doesnt work in appcelerator. Rather you can get sound file from below code. Hope it helps.
var player = Ti.Media.createSound({url:"sound.wav"});
player.play();
I am using an AVAudioPlayer to play audio in my app, and it worked for a while. Suddenly, it just stopped working and I cannot figure out why. I created the AVAudioPlayer at the class level in the .h file. This is the code I use to init the player
-(void)initAudio
{
NSURL *song = [[NSBundle mainBundle] URLForResource:#"Prelude" withExtension:#"m4a"];
NSError *error = nil;
_audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:song error:&error];
[_audioPlayer prepareToPlay];
}
I call this method in the initWithSize function. error is nil, and I have verified that the player object contains the actual audio file. The audio file plays back fine in my OS environment and I have tried adding it to the build phase compile sources just to be safe, even though beforehand it worked fine without it explicitly there. When I trigger the play event, it will play the first snippet of the audio and then nothing. I log the current time of the player and it is 0. Everything else about the app is continuing on and functions without issue. I do not interfere with the avaudioplayer object in any way except to play/pause/preparetoplay.
I am completely stumped as it worked fine and then suddenly no longer works. I have tried to clean the project, I have even dumped the derivedData.
Any ideas?
I think your player has an error when you try to play the song.
You need to check the error first.
In my opinion, it seems like OSStatus error -43.
When you update an app, file path can be changed.
For example,
old path : /var/mobile/Applications/F28E0C2C-4AE2-4C9D-906F-414AE1669D90/Documents/AAA.mp3
new path: var/mobile/Applications/6086783B-A410-42C3-9BAE-7BA755D0E528/Documents/AAA.mp3
Try this code instead:
NSError *error;
NSURL *song = [[NSBundle mainBundle] URLForResource:#"Prelude" withExtension:#"m4a"];
_audioPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:song error:&error];
if(error){
NSLog(#"[error localizedDescription] %#", [error localizedDescription]);
NSString *fileName = [[song absoluteString] lastPathComponent]; //this code is just example. get your fileName like "AAA.m4a"
NSString *docDirPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *filePath = [NSString stringWithFormat:#"%#/%#", docDirPath , fileName];
_audioPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL URLWithString:filePath] error:&error];
}
_audioPlayer.delegate = self;
[_audioPlayer prepareToPlay];
[_audioPlayer play];
}
I hope this will help you.
Cheers
I am attempting to load an M4A file but I can't get the path to the file using NSBundle.
NSString *fileURLString = [[NSBundle mainBundle] pathForResource:fileName ofType:fileExtension];
NSURL *fileToBePlayed = [[NSURL alloc] initWithString:fileURLString];
tourAudioPlayer = [tourAudioPlayer initWithContentsOfURL:fileToBePlayed error:nil];
When I run the code the debugger shows that fileURLString is nil and, thus, so are the subsequent two objects.
I've added the file to the Supporting Files directory and confirmed that the file is included under Copy Bundle Resources under Target > Build Phases.
Unfortunately the magic of Clean and Build has failed me in this case. Is there some stage in loading the file in that I'm missing?
Just try this....
- (void)viewDidLoad
{
[super viewDidLoad];
NSURL *vedioURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:FileName ofType:FileType]];
MPMoviePlayerViewController *videoPlayerView = [[MPMoviePlayerViewController alloc] initWithContentURL:vedioURL];
[self presentMoviePlayerViewControllerAnimated:videoPlayerView];
[videoPlayerView.moviePlayer play];
}
I've solved the problem, which turns out to have been two silly problems.
The first problem was that I was using initWithString: rather than fileURLWithPath:. Lazy reading of the documentation on my part.
The second problem was a mere embarrassing oversight. The code snippet provided represents the initial creation of the AVAudioPlayer and thus I was following to allocate space for it on the heap.
Making the changes above has remedied the problem. Thank you to everyone that offered advice and support.
This has driven me nuts for a long time now. I am using Xcode 4.6 but this has been happening for several versions. When I turn on breakpoints and add the Exception Breakpoint, it always pauses on a line of code where I'm setting up an audio player. I set some up before and after the same way, but it only pauses on that one.
Here is the code I'm using:
[[AVAudioSession sharedInstance] setDelegate: self];
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryAmbient error: nil];
NSError *activationError = nil;
[[AVAudioSession sharedInstance] setActive: YES error: &activationError];
self.playedSongs = [NSMutableSet setWithCapacity:9];
[self loadSettingsFromFile];
NSURL *sfxPath = [NSURL fileURLWithPath:[[NSBundle mainBundle]pathForResource:#"Snap.aiff" ofType:nil]];
self.snapSfx = [[[AVAudioPlayer alloc]initWithContentsOfURL:sfxPath error:nil]autorelease];
self.snapSfx.volume = 1.f;
NSURL *fireworksPath;
if ([OriginalIPadChecker isNotiPadOriginal]) {
fireworksPath = [NSURL fileURLWithPath:[[NSBundle mainBundle]pathForResource:#"FireworksSFX.mp3" ofType:nil]];
}
else{
fireworksPath = [NSURL fileURLWithPath:[[NSBundle mainBundle]pathForResource:#"NoFireworksSFX.mp3" ofType:nil]];
}
self.fireWorksSfx = [[[AVAudioPlayer alloc]initWithContentsOfURL:fireworksPath error:nil]autorelease];
self.fireWorksSfx.volume = 1.f;
NSURL *poofPath = [NSURL fileURLWithPath:[[NSBundle mainBundle]pathForResource:#"Remove Poof.mp3" ofType:nil]];
//The line below is the one that it pauses on
self.removePoof = [[[AVAudioPlayer alloc]initWithContentsOfURL:poofPath error:nil]autorelease];
self.removePoof.volume = 1.f;
NSURL *newHighScorePath = [NSURL fileURLWithPath:[[NSBundle mainBundle]pathForResource:#"New High Score.mp3" ofType:nil]];
self.theNewHighScore = [[[AVAudioPlayer alloc]initWithContentsOfURL:newHighScorePath error:nil]autorelease];
self.theNewHighScore.volume = 1.f;
NSURL *badgeInTrophyPath = [NSURL fileURLWithPath:[[NSBundle mainBundle]pathForResource:#"Badge In Trophy.aiff" ofType:nil]];
self.badgeInTrophy = [[[AVAudioPlayer alloc]initWithContentsOfURL:badgeInTrophyPath error:nil]autorelease];
self.badgeInTrophy.volume = 1.f;
NSURL *dingPath = [NSURL fileURLWithPath:[[NSBundle mainBundle]pathForResource:#"Ding.aif" ofType:nil]];
self.ding = [[[AVAudioPlayer alloc]initWithContentsOfURL:dingPath error:nil]autorelease];
self.ding.volume = 1.f;
The app doesn't crash and the sound plays fine, but the debugger always pauses on that one lineāeven if I move it somewhere else, it still pauses. I can continue the execution and it works just fine, but this really bugs me.
I don't get why it pauses. Any ideas?
As explained in the comment of Xcode stops on prepareToPlay, the reason for the breakpoint is that you were setting a generic breakpoint of type 'exception on All' which responds to a signal which is fired by the c++ library. It is better to use an "Objective-c" exception breakpoint, which will protect for such cases.
Try this and update the question on where it stops (if it stops):
AVAudioPlayer *foo;
NSError *error = nil;
assert(poofPath);
foo = [AVAudioPlayer alloc];
foo = [foo initWithContentsOfURL:poofPath error:&error];
assert(foo);
[self setRemovePoof:foo];
[foo release];
If the assert kicks in, that's probably an Apple issue. Unfortunately there are cases of Apple internal frameworks using try/catch, and they will trigger the breakpoint. Its not common but does happen.
If in the end that foo is not nil and the error is also nil, the best you can do is enter a bug report at bugreporter.apple.com (which would be great). Also, did you look at poofPath - is there any chance that the URL returns anything other than pristine audio?
My guess is that Apple tries to open and process the file, its gets an internal exception because there is something "odd" or abnormal about the file. Then the framework does additional work, and manages to read the file. So you get your sound but the exception too. Take some common type of mp3 and put that in your app bundle, and try to open it. See if it (and maybe a few other files) gives the same error. Or create a demo project with the sound and upload it (in the end you may need to submit the demo project to Apple in a bug report). These kinds of things should be bug reported.
EDIT: Unfortunately there are cases of Apple internal frameworks using try/catch, and they will trigger the breakpoint. Then, as mentioned earlier, some later code finally figures out how to decode the file and does.
The original poster has responded in a comment that this particular file was created with Audacity, and has heard that such files often have decode issues.
I have a function that is almost working. A different audio file is played depending on what page you're on. The problem is, some of the audio files end abruptly. For example, while the audio file plays to the end on "case 1", on "case 2" it stops about 90% in.
- (void)playAudio
{
NSURL *audioURL;
[voiceAudio release];
switch (pageNumber)
{
case 1:
audioURL = [[NSURL alloc] initFileURLWithPath:[[NSBundle mainBundle] pathForResource:#"file1" ofType:#"aac"]];
voiceAudio = [[AVAudioPlayer alloc]
initWithContentsOfURL:audioURL error:nil];
[audioURL release];
voiceAudio.delegate = self;
[voiceAudio play];
break;
case 2:
audioURL = [[NSURL alloc] initFileURLWithPath:[[NSBundle mainBundle] pathForResource:#"file2" ofType:#"aac"]];
voiceAudio = [[AVAudioPlayer alloc]
initWithContentsOfURL:audioURL error:nil];
[audioURL release];
voiceAudio.delegate = self;
[voiceAudio play];
break;
// And so on...
}
}
The AACs are a few minutes long. Maybe there's a better way to go about this? AVAudioPlayer can be a bit funky. Thanks!
Edit: AVAudioPlayer is a bit unpredictable with the 64kb mono AACs I made in Adobe Soundbooth, but seems to run fine after remuxing the files to M4A. I used MP4Box to convert them using the syntax: "mp4box -add source.aac:mpeg4 -sbr -ipod target.m4a" (credit)
Reencoding to a higher bitrate (128kb) seemed to fix some, but not all, of the files as well. I didn't thoroughly test this before I discovered remuxing.