AVAudioPlayer声音不能播放

在iOS 8 / Xcode 6中,我有一个包含音效的function。 多次更改代码后,它不再适用于iOS 9。 这是我试过的:

原版的:

let bangSoundEffect = SKAction.playSoundFileNamed("Bang.mp3", waitForCompletion: false) runAction(bangSoundEffect) 

其他尝试:

 self.runAction(SKAction.playSoundFileNamed("Bang.mp3", waitForCompletion: false)) 

也:

 func playRocketExplosionSound(filename: String) { let url = NSBundle.mainBundle().URLForResource( filename, withExtension: nil) if (url == nil) { print("Could not find file: \(filename)") return } var error: NSError? = nil do { backgroundMusicPlayer = try AVAudioPlayer(contentsOfURL: url!) } catch let error1 as NSError { error = error1 backgroundMusicPlayer = nil } if backgroundMusicPlayer == nil { print("Could not create audio player: \(error!)") return} backgroundMusicPlayer.numberOfLoops = 1 backgroundMusicPlayer.prepareToPlay() backgroundMusicPlayer.play() } playRocketExplosionSound("Bang.mp3") 

我正在拉我的头发。 我使用相同的代码在另一个场景中的另一个声音效果,它工作正常! 怎么了? 我注意到,模拟器中的声音效果有时候会开始播放,但是它并没有完成并且抛出这个错误:

 2015-09-24 19:12:14.554 APPNAME[4982:270835] 19:12:14.553 ERROR: 177: timed out after 0.012s (735 736); mMajorChangePending=0 

它在实际设备上根本不起作用。

问题是什么? :'(

MP3文件可能的问题

问题很可能与您使用的MP3文件有关。 该代码适用于其他声音,这表明MP3文件可能已损坏, AVAudioPlayer解码失败。 你可以尝试重新编码这个文件,看看问题是否存在。 或者,甚至更好,将其转换为WAV

使用WAV

为游戏创造短暂的声音效果时,大拇指的一般规则是使用WAV除非你真的觉得你需要修剪脂肪。

顶级的游戏将获得顶级的制作质量,因此他们可以logging和生产未压缩的24bit / 48kHz资产。 稍微有点野心的标题可能会在CD音质的官方标准16 / 44.1录制和制作。

这至less有两个好处。 一个是声音质量更好。 其次, CPU不必解码文件来播放它。

尝试这个:

 dispatch_async(dispatch_get_main_queue(), { (self.playRocketExplosionSound("Bang.mp3") }) 

在iOS 9下的子线程中播放audio已经不再安全。

损坏的数据文件| AVAudioPlayer超出了范围


1.损坏的数据文件

这将确保您find该文件:

  var backgroundMusicPlayer: AVAudioPlayer? = nil if let url = Bundle.main.url( forResource: "Bang", withExtension: "mp3") { do { try backgroundMusicPlayer = AVAudioPlayer(contentsOf: url) backgroundMusicPlayer!.play() } catch {} } return nil 

2. AVAudioPlayer超出范围

play()完成并返回前,variablesretainMusicPlayer不能超出范围。 这通常通过使用类variables来实现:

 var backgroundMusicPlayer: AVAudioPlayer? = nil 

不要这样做:由于var audioPlayer的本地范围,以下声音最多只能播放outOfScopeDelay

 let outOfScopeDelay = 0.5 do { var audioPlayer:AVAudioPlayer! // Incorrectly scoped variable try audioPlayer = AVAudioPlayer(contentsOf: audioRecorder.url) audioPlayer.play() Thread.sleep(forTimeInterval: outOfScopeDelay) } catch {} 

►在GitHub上find这个解决scheme和Swift Recipes的更多细节。