【问题标题】:Can't play sound: application crashes无法播放声音:应用程序崩溃
【发布时间】:2015-09-21 13:23:57
【问题描述】:

我正在尝试以各种方式播放声音:首先我尝试使用 SpriteKit 的操作:

sprite.runAction(SKAction.playSoundFileNamed("explosion.mp3", waitForCompletion: false))

我还尝试将这段代码分成两部分:在 init 方法中我初始化动作,稍后执行。但即使我只是初始化 SKAction,应用程序也会崩溃:

self.soundAction = SKAction.playSoundFileNamed("explosion.mp3", waitForCompletion: true)

我也尝试过使用 AVFoundation。这段代码在 init 方法中:

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)
}

我不得不使用 NSData 对象,因为它使用 URL 失败。这样它也失败了,但至少它给了我一个更有意义的错误描述:

Optional("操作无法完成。(OSStatus error -39.)")

【问题讨论】:

  • 确保您已将声音文件添加到捆绑包中。还要在设备中验证它。希望你打电话给[explosionSoundPlayer play];
  • @abyt07 是的,它在包内,我在设备/模拟器上遇到同样的错误。

标签: ios swift sprite-kit avfoundation


【解决方案1】:

我刚刚测试了 AVAudioPlayer,它在两种情况下都适用于我(使用 NSData 或 NSUrl)。检查下面的代码:

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()
       */
    }
}

你可以像这样播放声音(例如在 touchesBegan 方法中):

//audioPlayer?.play()

 self.runAction(self.soundAction)

尝试复制并粘贴此代码(只需更改声音名称和扩展名),看看您是否仍然遇到错误。 NSData 部分与您的示例相同。

我想你已经知道了,但不要说你应该如何将声音文件添加到你的项目中:

  • 将声音拖到您的项目中
  • 在目标部分,选择“如果需要,复制”
  • 在添加的文件夹部分,选择“创建组”
  • 在添加到目标中,选择您的目标。

如果仍然不起作用,我会在“构建阶段”->“复制捆绑资源”下检查是否存在“explosion.mp3”。如果不是,请使用 + 按钮(悬停时会显示添加项目)并添加它。

提示:

请注意,不建议使用 mp3 文件来播放短音,因为 mp3 是经过压缩的,并且需要硬件解码。解码需要 CPU 时间。此外,使用硬件解码器只能播放一个 mp3 文件。如果您一次播放多个 mp3,则将使用软件对其进行解码,这很慢。来自文档:

使用硬件辅助解码时,设备只能播放 一次支持的格式之一的单个实例。为了 例如,如果您使用硬件播放立体声 MP3 声音 编解码器,第二个同步 MP3 声音将使用软件解码。 同样,您不能同时播放 AAC 和 ALAC 声音 使用硬件。如果 iPod 应用程序正在播放 AAC 或 MP3 声音 在后台,它声称拥有硬件编解码器;你的申请 然后使用软件解码播放 AAC、ALAC 和 MP3 音频。

播放短音的更好选择是 .wav 和 .caf 格式。

【讨论】:

  • 还是不行。也许这是一个库错误,我会尝试调查它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-26
  • 1970-01-01
  • 2015-11-01
  • 2013-01-18
  • 1970-01-01
相关资源
最近更新 更多