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的更多细节。