Why won't this background music stop when I tell it to? - ios

Coding a game for iOS 7, and I set it up so the music plays continuously. I've also set it up so that when the player is dead, to stop the music, but it continues to run the music until the clip of music is done. (To clarify, the clip is 7 seconds long, and for example, if the music is done at 0:03, it will continue into the next scene, until it hits 7)
Here's the code:
[self runAction:[SKAction repeatActionForever:[SKAction playSoundFileNamed:#"bgmusic.m4a" waitForCompletion:YES]]];
if (_dead == YES)
[self removeAllActions];
}
I want the music to stop the second the player dies, as opposed to finishing the action. How can I code it so it does so? I had assumed that [self removeAllActions]; would have done that? Is there a specific thing I can call to stop it instantaneously?
Thanks.

Try using this code (AVAudioPlayer)...
NSURL * backgroundMusicURL = [[NSBundle mainBundle] URLForResource:#"warmovie" withExtension:#"caf"];
self.backgroundMusicPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:backgroundMusicURL error:&error];
self.backgroundMusicPlayer.numberOfLoops = -1;
[self.backgroundMusicPlayer prepareToPlay];
[self.backgroundMusicPlayer play];
To stop...
[self.backgroundMusicPlayer stop]

Related

Sprite Kit stop playing music file and start from the beginning

Whenever I present my scene, I want to start playing a music file and stop the music playing from the last time my scene was presented. I'm trying to do it like this.
[self removeActionForKey:#"Music"];
[self runAction:[SKAction repeatActionForever:[SKAction playSoundFileNamed:#"Music.wav" waitForCompletion:YES]] withKey:#"Music"];
Should I use AVAudioPlayer or [SKAction playSoundFileNamed:]?
Also I would like to know if there is a way to play music file forever in all scenes without starting from the beginning.
To play background music in all scenes I will recommend AVAudioPlayer. You can write the code somewhere in your AppDelegate to access from all the scenes. Here is a sample code to achieve this using AVAudioPlayer
// AVAudioPlayer *bgMusicLoop;
- (void)playBackroundMusic:(NSString *)fileName withExtenstion:(NSString *)fileExtension
{
NSString *filePath = [[NSBundle mainBundle] pathForResource:fileName ofType:fileExtension];
NSError *error;
if(bgMusicLoop)
[bgMusicLoop stop];
bgMusicLoop = nil;
bgMusicLoop = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:filePath] error:&error];
if (error) {
NSLog(#"Error in audioPlayer: %#", [error localizedDescription]);
} else {
bgMusicLoop.numberOfLoops = -1;
[bgMusicLoop prepareToPlay];
[bgMusicLoop play];
}
}
- (void)stopBackgroundMusic
{
if(bgMusicLoop)
[bgMusicLoop stop];
bgMusicLoop = nil;
}
- (void)pauseBackgroundMusic
{
if(bgMusicLoop && bgMusicLoop.isPlaying)
[bgMusicLoop pause];
}
- (void)resumeBackgroundMusic
{
if(bgMusicLoop && !bgMusicLoop.isPlaying)
[bgMusicLoop play];
}
For music you should use AVAudioPlayer as using SKAction to play music will block any other actions you might want to run on the scene and its a bit more cumbersome to handle especially if you want to play more sounds along with the music.
Use SKAction to play short sound files (like player jump/fire etc...)
With AVAudioPlayer you can easily set your file to play repeatedly until stopped

How do I loop music in Sprite Kit?

I have an 8 second mp3 file and I'm trying to loop it as main menu music. I do this by using SKAction repeatActionForever, however every time it starts over there is a small pause between the loops. This is very annoying since it doesn't sound like it is one long song this way. How can I fix this?
EDIT:
It also doesn't work with AVAudioPlayer :(
Use AVAudioPlayer and set the numberOfLoops property to -1 in order to loop the sound indefinitely.
For example:
NSError *error;
NSURL *soundURL = [[NSBundle mainBundle] URLForResource:#"SomeSound.wav" withExtension:nil];
myPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:soundURL error:&error];
myPlayer.numberOfLoops = -1;
myPlayer.volume = 0.4;
myPlayer.delegate = self;
[myPlayer prepareToPlay];
[myPlayer play];

iOS - programmatically cancel all sounds/music?

I am developing an iPhone game using Xcode's sprite kit and was wondering if there is a simple or best-practice method of canceling all sound-effects/ music programatically? The most obvious method to me is to create some boolean variable "isSoundAllowed" and set it to true/false when the user toggles sound on/off in my game, but I'd like to learn better techniques if available. Thanks!
P.S: the following is 1) the sound and 2) the music:
1)
_ActionExplodeSound = [SKAction playSoundFileNamed:#"explosion.wav" waitForCompletion:NO];
2)
-(void)playBackgroundMusic
{
NSError *error;
NSURL *backgroundMusicURL = [[NSBundle mainBundle] URLForResource:#"backgroundMusic.mp3" withExtension:nil];
_backgroundMusicPlayer=[[AVAudioPlayer alloc] initWithContentsOfURL:backgroundMusicURL error:&error];
_backgroundMusicPlayer.numberOfLoops = -1;
[_backgroundMusicPlayer play];
}
edit: actually I can use [_backgroundMusicPlayer stop]; to stop the music, but is there a simple way like this to disable all sound effects (I have more than i list in #1 but they are of the same type)?
My solution so far is this, but I'm confident there is a better/more compact of doing this:
-(void)toggleSound
{
BoolSoundEnabled=!BoolSoundEnabled;
if (BoolSoundEnabled==TRUE) {
_ActionExplodeSound = [SKAction playSoundFileNamed:#"explosion.wav" waitForCompletion:NO];
[_backgroundMusicPlayer play];
} else if (BoolSoundEnabled==FALSE) {
_ActionExplodeSound=Nil ;
[_backgroundMusicPlayer stop];
}
}

iOS how to create audio fade in/out effect in a Sprite Kit game?

I'm interested in how I can manage background music in my Sprite Kit game to achieve fade in/out.
I noticed that Sprite Kit has a built-in sound player, but it seems to be more useful for very short effects, like "on hit" sounds:
[self runAction:[SKAction playSoundFileNamed:#"music.mp3" waitForCompletion:NO]];
It does not seem like there's a way to stop this sound.
I'm using Kobold Kit, and it comes with OALSimpleAudio library that can play sounds:
[[OALSimpleAudio sharedInstance] preloadEffect:#"die.wav"];
[[OALSimpleAudio sharedInstance] playEffect:#"die.wav"];
[[OALSimpleAudio sharedInstance]preloadBg:#"battle.mp3"];
[[OALSimpleAudio sharedInstance] playBg:#"battle.mp3" loop:YES];
There's a bgVolume property in OALSimpleAudio, but no real fade.
Should try to write my own fade in/out code of if there's something out there I can use to control volume over time of a generic music player, like OALSimpleAudio.
You can also just use the build in AVAudioPlayer or of course adapt the function to your player:
//play background sound
NSError *error;
NSURL * backgroundMusicURL = [[NSBundle mainBundle] URLForResource:#"SpaceLife" withExtension:#"mp3"];
self.backgroundMusicPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:backgroundMusicURL error:&error];
self.backgroundMusicPlayer.numberOfLoops = -1;
[self.backgroundMusicPlayer prepareToPlay];
[self.backgroundMusicPlayer play];
And then you add the function from this post:
- (void)doVolumeFade
{
if (self.backgroundMusicPlayer.volume > 0.1) {
self.backgroundMusicPlayer.volume = self.player.volume - 0.1;
[self performSelector:#selector(doVolumeFade) withObject:nil afterDelay:0.1];
} else {
// Stop and get the sound ready for playing again
[self.backgroundMusicPlayer stop];
self.backgroundMusicPlayer.currentTime = 0;
[self.backgroundMusicPlayer prepareToPlay];
self.backgroundMusicPlayer.volume = 1.0;
}
}
ObjectAL has an AVAudioPlayer wrapper built in for music playback. It's called OALAudioTrack.
OALAudioTrack has a method fadeTo:duration:target:selector: that you can use to do fading. You already have an instance of OALAudioTrack available to you as the simple audio interface's backgroundTrack property:
[[OALSimpleAudio sharedInstance].backgroundTrack fadeTo:.. duration:.. ..];

iOS playback audioServices

I have a working AudioServicesPlaySystemSound code to run a 10s background music.
Is there a way for me to loop this audio every 10s ? I want it to run forever until an action is triggered to stop the audio (e.g: a button is pressed to stop the loop)
I read an article about dispatch_after and thought that it might be an appropriate way to create the loop.
Switch to AVAudioPlayer instead. Not only can you specify a number of times to play the sound, but you have more control over the sound, including volume level.
It isn't that much harder. For example, here is how you would play a sound, looped indefinitely:
NSURL *fileURL = [[NSURL alloc] initFileURLWithPath: soundFilePath];
AVAudioPlayer *player = [{AVAudioPlayer alloc] initWithContentsOfURL: fileURL error: nil];
player.numberofLoops = -1;
[player play];
and this is how you would stop it:
[player stop];

Resources