This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
iOS SDK : playing music on the background and switching views
Hi guys im currently using this code to play background music in my app when its launched .But when i switch views to my SecondView and return back to my Firstview the music starts over and overlaps the music that is currently playing and it keeps overlapping music when i return back to my Firstview, how can i have the music start over when i switch back to my Firstview from my SecondView.
FirstViewController.m
- (void)viewDidLoad {
NSString *path = [[NSBundle mainBundle] pathForResource:#"drums" ofType:#"mp3"];
theAudio=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPathath] error:NULL];
theAudio.delegate = self;
theAudio.numberOfLoops = -1;
[theAudio play];
You can use NSUserDefaults to save the music playing status, so when the view is loaded, the music will only be played if it hasn't already.
if ([[NSUserDefaults standardUserDefaults] stringForKey:#"music"] == nil) {
NSString *path = [[NSBundle mainBundle] pathForResource:#"drums" ofType:#"mp3"];
theAudio=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPathath] error:NULL];
theAudio.delegate = self;
theAudio.numberOfLoops = -1;
[theAudio play];
[[NSUserDefaults standardUserDefaults] setObject:#"-" forKey:#"music"]; }
You need to reset this key back to nil when quitting the app. Otherwise, if the player quit the app, and next time when the app is restarted the #"music" string wouldn't be nil.
Go to the projectAppDelegate.m file:
- (void)applicationDidEnterBackground:(UIApplication *)application {
[[NSUserDefaults standardUserDefaults] setObject:nil forKey:#"music"]; }
If the music is being played throughout the app, then put the music playing codes as shown below to be safe. Don't forget to declare the AVAudioPlayer *theAudio in projectAppDelegate.h file.
- (void)applicationDidBecomeActive:(UIApplication *)application {
NSString *path = [[NSBundle mainBundle] pathForResource:#"drums" ofType:#"mp3"];
theAudio=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPathath] error:NULL];
theAudio.delegate = self;
theAudio.numberOfLoops = -1;
[theAudio play];
[[NSUserDefaults standardUserDefaults] setObject:#"-" forKey:#"music"]; }
I might have missed a few bits here. Just run a few tests to make it the way you like to work. I just tried on my app and it worked for me.
Two option,
1- stop the player while first view is disappear.
[theAudio stop] in `viewWillDisappear`
2- if you don't want to play again on come back.
declare theAudio in appDelegate class. and before allocating check whether it is allocated or not.
if(!appDelegate.theAudio)
{
NSString *path = [[NSBundle mainBundle] pathForResource:#"drums" ofType:#"mp3"];
appDelegate.theAudio=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPathath] error:NULL];
theAudio.delegate = self;
theAudio.numberOfLoops = -1;
[theAudio play];
}
else
{
[theAudiostop];
[theAudio play];
}
You are reallocating and recreating the AVAudioPlayer each time you display the view. You should avoid this if possible. As a solution to your problem, depending on your code, call [theAudio stop] in viewDidDisappear or viewDidUnload events. This will stop your audio player when its view enters background.
Related
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.
I have a ViewController : GLKViewController
with this code:
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *path = [[NSBundle mainBundle] pathForResource:#"background-music-aac" ofType:#"caf"];
NSURL *url = [NSURL URLWithString:path];
NSData *data = [NSData dataWithContentsOfURL:url];
AVAudioPlayer *audio = [[AVAudioPlayer alloc] initWithData:data error:nil];
audio.delegate = self;
audio.volume = 1.0;
audio.numberOfLoops = -1;
[audio prepareToPlay];
[audio play];
[self setupContext];
[self setupDisplay];
}
However... my graphical things working fine but the iOS simulator plays no music.
did I something wrong?
Assuming you are using ARC, the player is getting deallocated as soon your method returns to its caller. To quote from this answer:
ARC inserts a release call to the audio player, so it's deallocated right after leaving the method where it is created.
Try implementing the AVAudioPlayer as a property.
If your data is nil, the file was not properly added to the project. To add your file to the project, just drag and drop it and add it to your targets.
Also, AVAudioPlayer has a method, initWithContentsOfURL:, which you might want to use.
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;
}
}
hi does anyone know how to add audio to buttons i have added the framework creatd an action that place the sounds but when i press the button no sound plays?
heres what i have done so far
-(void)buttonSound{
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/ButtonSound.mp3", [[NSBundle mainBundle] resourcePath]]];
NSError *error;
audioPlayer2 = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
audioPlayer2.numberOfLoops = -1;
[audioPlayer2 play];
}
- (IBAction)backToMenu:(id)sender {
[self buttonSound];
[self.navigationController popViewControllerAnimated:YES];
}
For short system sounds, you should use something like:
SystemSoundID sound;
CFURLRef alertURL = CFBundleCopyResourceURL(CFBundleGetMainBundle(), (CFStringRef)#"ButtonSound", CFSTR("mp3"), NULL);
OSStatus status = AudioServicesCreateSystemSoundID(alertURL, &sound);
AudioServicesPlayAlertSound(sound);
your audioplayer is getting released by immediately popping up navigation controller.
if you remove this line:
[self.navigationController popViewControllerAnimated:YES];
you should be able to hear the audio file (if the path is correct).
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.