在iOS 8 / Xcode 6中,我有一个包含声音效果的功能。在多次更改代码后,它不再适用于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
它在实际设备上根本不起作用。
有什么问题? :'(
答案 0 :(得分:8)
问题很可能与您正在使用的MP3
文件有关。该代码适用于其他声音,这表明MP3
文件可能已损坏,AVAudioPlayer
因解码而失败。您可以尝试重新编码此文件,看看问题是否仍然存在。或者,甚至更好,将其转换为WAV
。
为游戏创建简短的音效时,拇指的一般规则是使用WAV
,除非你真的觉得你需要修剪它的脂肪。
一流的游戏正在追求顶级的制作质量,因此他们会记录并制作未压缩的资产24bit
/ 48kHz
。志愿性稍差的标题可以在16
/ 44.1
中录制和制作,这是CD
质量音频的官方标准。
这至少有两个好处。一个是声音质量更好。第二个,CPU
不必解码文件来播放它。
答案 1 :(得分:4)
AVAudioPlayer
超出范围<强> 1。损坏的数据文件
这将确保您找到了文件:
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
超出范围
在backgroundMusicPlayer
完成并返回之前,保留play()
的变量不得超出范围。这通常通过使用类变量来实现:
var backgroundMusicPlayer: AVAudioPlayer? = nil
请勿执行此操作:由于outOfScopeDelay
的本地范围,以下声音最多只会播放var audioPlayer
。
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上找到此解决方案,并在Swift Recipes上找到其他详细信息。
答案 2 :(得分:3)
试试这个:
dispatch_async(dispatch_get_main_queue(), {
(self.playRocketExplosionSound("Bang.mp3")
})
在iOS 9下,在子线程中播放音频不再安全。