AVAudioPlayer声音没有播放

时间:2015-09-24 18:24:10

标签: ios sprite-kit swift2 ios9 xcode7

在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

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

有什么问题? :'(

3 个答案:

答案 0 :(得分:8)

MP3文件可能存在问题

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

使用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下,在子线程中播放音频不再安全。