Cannot play audio in Xcode project - ios

This code works in a test app, but not in the app in which I want the audio to play.
-(void) playTutorialAudio
{
_theAudioFile = [[NSBundle mainBundle] pathForResource:#"Welcome" ofType:#"mp3"];
NSLog(#"playTutorialAudio _theAudioFile %#",_theAudioFile);
NSURL *playTutorialURL = [NSURL fileURLWithPath:_theAudioFile ];
_audioPlayAlert = [[AVAudioPlayer alloc] initWithContentsOfURL:playTutorialURL error:NULL];
[_audioPlayAlert setDelegate:self];
[_audioPlayAlert prepareToPlay];
_audioPlayAlert.volume = 1.0;
[_audioPlayAlert play];
}
The code works with other audio files.

It will work, You need to change your implementation like this. Please notice your init method.
#property (nonatomic, retain) AVAudioPlayer *cellTapSound;
may be in viewDidLoad
cellTapSound = [[AVAudioPlayer alloc] initWithContentsOfURL:[[NSBundle mainBundle] URLForResource:#"ting" withExtension:#"wav"] error:nil];
[cellTapSound prepareToPlay];
Now may be on click of some button, you can give a shot like this :
if (cellTapSound.isPlaying) [cellTapSound setCurrentTime:0.0];
[cellTapSound play];
hope that helps.

Related

Playing a sound in background

I have read some threads about this topic, and currently have this:
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *soundFilePath = [NSString stringWithFormat:#"%#/testsoundsr.aiff",
[[NSBundle mainBundle] resourcePath]];
NSURL *soundFileURL = [NSURL fileURLWithPath: soundFilePath];
AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL
error:nil];
player.numberOfLoops = -1; //Infinite
[player play];
}
The sound is not played though, and I can only imagine that the problem is with the NSString definition which is used to reference the file
The file I'm trying to play is named 'testsoundsr.aiff' and I have dragged that into the project. Also I have added several frameworks to the project, including AudioToolBox.framework
---UPDATE---
I have now tried using an .mp3 file instead, but still getting no sound through.
Try player.delegate = self before [player play]

stop first sound when second is playing

I am an absolute beginner in both objective-c and other environments so please be patient. Here is my problem: I need to play sound files so that each of them stops when the other is started, right now they overlap; here is a snippet of my code.
Thank you in advance and let me know if you need other details.
- (IBAction)soundfirst {
NSString *path =
[[NSBundle mainBundle] pathForResource:#"hi2" ofType:#"mp3"];
player1 = [[AVAudioPlayer alloc]
initWithContentsOfURL:[NSURL fileURLWithPath:path]
error:NULL];
player1.delegate = self;
[player1 play];
}
- (IBAction)soundsecond {
[player1 stop];
NSString *path =
[[NSBundle mainBundle] pathForResource:#"hi2" ofType:#"mp3"];
player2 = [[AVAudioPlayer alloc]
initWithContentsOfURL:[NSURL fileURLWithPath:path]
error:NULL];
player2.delegate = self;
[player2 play];
}
The best way to do something when you're stuck, is to look into the documentation.
In your code, you're creating an object of type AVAudioPlayer, and naming it player1.
AVAudioPlayer Documentation:
http://developer.apple.com/library/ios/#DOCUMENTATION/AVFoundation/Reference/AVAudioPlayerClassReference/Reference/Reference.html
look under the instance methods, and there's a method there called stop.
So in the first method, you can do something like
if(player2.playing){
[player2 stop];
}
[player1 play];
#import <AudioToolbox/AudioServices.h>
SystemSoundID buttonClickSoundID;
+ (void)playButtonClickSound {
if (buttonClickSoundID == 0) {
NSString *soundPath = [[NSBundle mainBundle] pathForResource:#"button_click" ofType:#"wav"];
CFURLRef soundURL = (CFURLRef)[NSURL fileURLWithPath:soundPath];
AudioServicesCreateSystemSoundID(soundURL, &buttonClickSoundID);
}
AudioServicesPlaySystemSound(buttonClickSoundID);
}

AVAudioPlayer: Simple sound not playing

I'm trying to figure out why sounds aren't playing in my app, so I created what I think is as simple an implementation as possible:
NSError *error;
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:#"canary-trills" ofType:#"wav"];
NSLog(#"string=%#", soundFilePath);
NSURL *url = [[NSURL alloc] initFileURLWithPath:soundFilePath];
NSLog(#"URL=%#", url);
AVAudioPlayer *avPlayer = [[AVAudioPlayer alloc]
initWithContentsOfURL:url error:&error];
[avPlayer prepareToPlay];
BOOL success = [avPlayer play];
NSLog(#"The sound %# play", success ? #"did" : #"didn't");
Per the console, it looks like it finds the resource, creates the URL correctly. Even the play call indicates success. However, no sound play in the simulator nor the device.
AVAudioPlayer wasn't being retained & was going out of scope.
Adding:
#property (strong, nonatomic) AVAudioPlayer *audioPlayer;
to the class & using that member solved the issue.

Stop Audio on ViewDidDissapear

I finally have my audio playing in a loop with ViewDidLoad but I'm really struggling to get it to stop with ViewDidDissapear. I've read this and this plus many answers and questions on this forum. If I use [theAudio stop] I get an error and most of the other tutorials end up with errors. What am I doing wrong?
I have imported the AVFoundation/AVFoundation.h Framework and added AVAudioPlayerDelegate
- (void)viewDidLoad
{
NSString *path = [[NSBundle mainBundle] pathForResource:#"safariSFX" ofType:#"mp3"];
AVAudioPlayer* theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
[theAudio play];
theAudio.numberOfLoops = -1;
[super viewDidLoad];
}
You need to store the AVAudioPlayer instance as a #property. That way when theViewWillDisappear event occurs, you can call [theAudio stop]; In your code above you create a local var and so don't have any way to reference it later on.
your code is out of scope.
You need to make theAudio an ivar if you want to be able to call it from viewWIllDisappear.
// In viewDidLoad -- you will need to setup theAudio in viewWillAppear if you are going to come back to this viewcontroller
if(theAudio == nil){
//initialize theAudio if it is nil
theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
}
//begin playing
[theAudio play];
.
.
.
-(void)viewWillDisappear{
//cleaning up if theAudio isn't nil, stop playing and set to nil;
if(theAudio != nil){
[theAudio stop];
theAudio = nil;
}
}

Pick songs from plist(NSArray) and play using AVAudioPlayer?

I'm student working on a coding exercise and I am stumped!
I have two instances of AVAudioPlayer in my app - I can load the songs into each player using a direct path no problem.
What I'd like to be able to do is play multiple songs held within an array on each player.
Is this possible? and if so how would I go about doing this?
In my plist I have the key set to "One.mp3" as a string and the value as the path to the file... (was guessing at that part).
Thanks for any insight.
- (void)viewDidLoad {
[super viewDidLoad];
//multiple song array
NSString *soundsPath = [[NSBundle mainBundle] pathForResource:#"soundslist"
ofType:#"plist"];
soundsList = [[NSArray alloc] initWithContentsOfFile:soundsPath];
NSString* filename = [soundsList objectAtIndex:0];
NSString *path = [[NSBundle mainBundle] pathForResource:filename
ofType:#"mp3"];
AVAudioPlayer * newAudio=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path]
error:NULL];
self.audioPlayer = newAudio; // automatically retain audio and dealloc old file if new file is loaded
[newAudio release]; // release the audio safely
audioPlayer.delegate = self;
[audioPlayer prepareToPlay];
[audioPlayer setNumberOfLoops:0];
[audioPlayer play];
}
It sounds like you want to try to play multiple songs on a single player. This isn't possible as stated in the AVAudioPlayer Overview (4th bullet). It is possible to play multiple songs with multiple AVAudioPlayers. Something like this:
NSMutableArray *audioPlayers = [NSMutableArray arrayWithCapacity:[soundsList count]];
for (NSString *soundPath in soundsList) {
NSError *error = nil;
AVAudioPlayer *audioPlayer = [AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:&error];
[audioPlayers addObject:audioPlayer];
audioPlayer.delegate = self;
[audioPlayer prepareToPlay];
[audioPlayer setNumberOfLoops:0];
[audioPlayer play];
}
I would suggest that you hardcode the file path instead of reading it in with a plist. Once you get that working, then you can try reading it in with the plist. Something like this would work:
NSURL *soundURL = [[NSBundle mainBundle] URLForResource:#"One" withExtension:#"mp3"];
AVAudioPlayer *soundPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:soundURL error:&error]
This way, you remove one level of indirection and one point of failure.

Resources