Sprite Kit & Playing Sound Leads to App Termination

Sprite Kit & playing sound leads to app termination

The problem is AVAudioSession can't be active while the app enters background. This isn't immediately obvious because Sprite Kit makes no mention that it uses AVAudioSession internally.

The fix is quite simple, and also applies to ObjectAL => set the AVAudioSession to inactive while the app is in background, and reactivate the audio session when the app enters foreground.

A simplified AppDelegate with this fix looks like so:

#import 
...

- (void)applicationWillResignActive:(UIApplication *)application
{
// prevent audio crash
[[AVAudioSession sharedInstance] setActive:NO error:nil];
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
// prevent audio crash
[[AVAudioSession sharedInstance] setActive:NO error:nil];
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
// resume audio
[[AVAudioSession sharedInstance] setActive:YES error:nil];
}

PS: this fix will be included in Kobold Kit v7.0.3.

SpriteKit app crashes when playing a sound after re-entering a scene

I was able to fix this issue by creating a strong property for the sound action like this

@property (strong, nonatomic) SKAction *playMySound;

and initialised it like this

self.playMySound = [SKAction playSoundFileNamed:@"mySound.mp3" waitForCompletion:NO];

After that I had no more issues with the sound crashes. In addition it gave me a path for preloading them before they were played.

Action that runs audio file in Sprite Kit stops running after applicationWillResignActive: is called

Running audio with SKAction is not reliable when it comes to interruptions which send your app into the background such as phone calls, pressing the home button, etc...

The solution is to use an AVAudioPlayer instead for anything other than short lived sound effects.

You would have to:

  1. Only use AVAudioPlayer for all your audio as it is designed and tested to handle interruptions.
  2. Use NSData as a sound container to be used with AVAudioPlayer (optional).
  3. Each sound should have its own temporary AVAudioPlayer instance for sound lifetime only.

There is a detailed explanation of how to do this on iKnowSomething.com which deals specifically with:

  1. SpriteKit app using [SKAction playSoundFileNamed:] cause crash on app exit or going into background.

  2. Deactivating AVAudioSession in AppDelegate applicationDidEnterBackground: fails with error (no deactivation in effect): Error Domain=NSOSStatusErrorDomain Code=560030580 "The operation couldn’t be completed. (OSStatus error 560030580.)

  3. SpriteKit app using [SKAction playSoundFileNamed:] on AVAudioSession interruption (e.g. call arrived) cannot be reactivated (silence).

  4. How to implement AVAudioPlayer in place of SpriteKit [SKAction playSoundFileNamed:]?

LearnCocos2D also wrote an excellent answer on the issue of preventing crashes when an app goes into the background and an AVAudioPlayer is being used.

#import 
...

- (void)applicationWillResignActive:(UIApplication *)application
{
// prevent audio crash
[[AVAudioSession sharedInstance] setActive:NO error:nil];
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
// prevent audio crash
[[AVAudioSession sharedInstance] setActive:NO error:nil];
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
// resume audio
[[AVAudioSession sharedInstance] setActive:YES error:nil];
}

His original answer is here.

Handling interruptions in Sprite Kit - can't get sound effects via [SKAction playSoundFileNamed: to work after interruption

From various discussions this seems to be a bug which can show its head on occasion. The short of it is that if you are experiencing these issues, and it appears you are, it comes down to skipping the SKAction playSoundFileName and going purely with AVAudioPlayer.

You would have to:

  1. Only use AVAudioPlayer for all your audio as it is designed and tested to handle interruptions.
  2. Use NSData as a sound container to be used with AVAudioPlayer
  3. Each sound should have its own temporary AVAudioPlayer instance for sound lifetime only.

There is a detailed explanation of how to do this on http://iknowsomething.com/ios-sdk-spritekit-sound/

Play sound in Sprite Kit

Delete the file from your project and add it again.
Remember to select

Copy items into destination group...

And select your project as a target (not test).

Playing Motor Sound Effects for iOS SpriteKit Game... AVAudioPlayer vs SKAction vs?

Based on the comment left by LearnCocos2D, I looked into ObjectAL. For those not familiar with ObjectAL, it is designed to be a simple and intuitive interface to OpenAL and AVAudioPlayer. You can download and find more information about it here...

http://kstenerud.github.io/ObjectAL-for-iPhone/index.html

For my audio clip I used 3 to 5 second long .caf audio file of a motor sound. ObjectAL allowed me to continuously loop and vary the pitch of the audio file. By varying the pitch, I could simulate the motor at different speeds.

Below is a sample of the code...

Two member variables or you can set them as properties...

ALBuffer *_buffer;
ALSource *_source;

Method to initialize the motor sound effect...

- (void)initializeSound
{
// We'll let OALSimpleAudio deal with the device and context.
// Since we're not going to use it for playing effects, don't give it any sources.
[OALSimpleAudio sharedInstance].reservedSources = 0;

_source = [ALSource source];
_buffer = [[OpenALManager sharedInstance] bufferFromFile:@"EngineSound.caf"];
_source.pitch = 0.30; // Start at low pitch for engine idle.
[_source play:_buffer loop:YES];
}

Inside my SKScene's update method I adjust the pitch according to speed.

- (void)update:(CFTimeInterval)currentTime
{
CGFloat enginePitch;

// Code to calculate desired enginePitch value based on vehicle speed.

_source.pitch = enginePitch;
}

Because of an alleged bug in SpriteKit, I did have an issue with a gpus_ReturnNotPermittedKillClient EXC_BAD_ACCESS error when closing the app. I found the fix here...

https://stackoverflow.com/a/19283721/3148272

Any ideas why I'm getting this error in sprite kit when adding sound?

Your sound file sounds/jump.caf could not be found by your app. Where and how did you add it to your Xcode project?



Related Topics



Leave a reply



Submit