Reputation: 21966
I'm trying to play a sound in all ways: first I tried with SpriteKit's actions:
sprite.runAction(SKAction.playSoundFileNamed("explosion.mp3", waitForCompletion: false))
I also tried to split this code in two parts: in the init method I initialize the action, to be executed later. But even if I just initialize the SKAction, the app crashes:
self.soundAction = SKAction.playSoundFileNamed("explosion.mp3", waitForCompletion: true)
I've also tried with AVFoundation. This code is inside the init method:
let explosionURL = NSBundle.mainBundle().URLForResource("explosion", withExtension: "mp3")
var error:NSError?
let data = NSData(contentsOfURL: explosionURL!)
explosionSoundPlayer = AVAudioPlayer(data: data, fileTypeHint: AVFileTypeMPEGLayer3, error: &error)
if explosionSoundPlayer != nil {
explosionSoundPlayer?.prepareToPlay()
} else {
println(error?.localizedDescription)
}
I had to use a NSData object because it was failing with an URL. This way it fails too, but at least it gives me a more meaningful error description:
Optional("The operation couldn’t be completed. (OSStatus error -39.)")
Upvotes: 0
Views: 162
Reputation: 13665
I've just tested AVAudioPlayer and it works for me in both ways (either with NSData or NSUrl). Check the code below:
class GameScene: SKScene {
var audioPlayer : AVAudioPlayer?
var soundAction = SKAction.playSoundFileNamed("sound.wav", waitForCompletion: true)
override func didMoveToView(view:SKView) {
let explosionURL = NSBundle.mainBundle().URLForResource("music", withExtension: "mp3")
var error:NSError?
let data = NSData(contentsOfURL: explosionURL!)
audioPlayer = AVAudioPlayer(data: data, fileTypeHint: AVFileTypeMPEGLayer3, error: &error)
if audioPlayer != nil {
audioPlayer?.prepareToPlay()
} else {
println(error?.localizedDescription)
}
/*
var soundUrl = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("music", ofType: "mp3")!)
println(soundUrl)
var error:NSError?
audioPlayer = AVAudioPlayer(contentsOfURL: soundUrl, error: &error)
audioPlayer?.prepareToPlay()
*/
}
}
You can play sounds like this (for example in touchesBegan method):
//audioPlayer?.play()
self.runAction(self.soundAction)
Try to copy & paste this code (just change sound names and extensions) to see if you are still getting errors. The NSData part is the same as from your example though.
I guess you are already know, but not hurt to mention how you should add sound files to your project:
If still doesn't work, I would check under "Build Phases" -> "Copy Bundle Resources" to see if "explosion.mp3" is present. If it isn't, use the + button (add items will show up when hover) and add it.
Hint:
Note that using mp3 file for short sounds is not recommended because mp3 is compressed and it requires hardware decoding. Decoding takes cpu time. Also, only one mp3 file can be played using hardware decoder. If you play more than one mp3 at a time, those will be decoded with software and that is slow. From the docs:
When using hardware-assisted decoding, the device can play only a single instance of one of the supported formats at a time. For example, if you are playing a stereo MP3 sound using the hardware codec, a second simultaneous MP3 sound will use software decoding. Similarly, you cannot simultaneously play an AAC and an ALAC sound using hardware. If the iPod application is playing an AAC or MP3 sound in the background, it has claimed the hardware codec; your application then plays AAC, ALAC, and MP3 audio using software decoding.
The better option for playing short sounds are .wav and .caf formats.
Upvotes: 1