将AVAudioPlayerNode连接到输出时,AVAudioEngine会抛出异常

时间:2017-06-26 10:46:01

标签: ios swift avfoundation avaudioplayer avaudioengine

我想要做的就是(现在)使用AVAudioEngineAVAudioPlayerNode播放声音文件。这是我的代码:

//Init engine and player
let audioEngine = AVAudioEngine()
let audioPlayerNode = AVAudioPlayerNode()

//Hook them up
audioEngine.attach(audioPlayerNode)
audioEngine.connect(audioPlayerNode, to: audioEngine.outputNode, format: nil) // < error

执行最后一行时,抛出异常。没有任何内容打印到控制台并继续执行,但是当我设置一个特殊断点时,我得到以下LLDB

(lldb) po [$arg1 reason]
error: Execution was interrupted, reason: EXC_BAD_ACCESS (code=1, address=0xffffd593).
The process has been returned to the state before expression evaluation.

这里有什么不能访问的?我还没有加载文件...感谢任何提示。

环境

  • Xcode 8.2.1
  • 在iOS 10.3.2(14F89)上运行的iPhone 5

修改

这是一些更多的上下文信息。上面的代码是使用SpriteKitGameplayKit构建的iOS游戏的一部分。它位于GKStateMachine的子类中,位于名为playSound的方法中。在源自我的子SKScene GameScene touchesBegan的触摸事件过程中调用此方法。在TouchComponent后,呼叫将委派给touchesBegan具有相同签名方法(touchDown)的所有实体。这些组件将向其委托发起GKStateMachine事件,而该委托又是GameStateMachine的子类score。如果触摸事件正确 w.r.t.在游戏规则中,GameStateMachine的{​​{1}}属性会增加。在score setter中,如果分数增加,则调用最终方法playSound。这是我刚才描述的序列图:

Sequence Diagram showing how "playSound" is invoked

2 个答案:

答案 0 :(得分:2)

这是在游乐场中播放本地文件资源的一个工作示例:

import AVFoundation
import PlaygroundSupport

// prevent program from exiting immediately
PlaygroundPage.current.needsIndefiniteExecution = true

let fileURL = Bundle.main.url(forResource: "song", withExtension: "mp3")!
let file = try! AVAudioFile(forReading: fileURL)

let audioEngine = AVAudioEngine()
let audioPlayerNode = AVAudioPlayerNode()

audioEngine.attach(audioPlayerNode)
audioEngine.connect(audioPlayerNode, to: audioEngine.outputNode, format: nil)

audioPlayerNode.scheduleFile(file, at: nil, completionHandler: nil)

// need to start the engine before we play
try! audioEngine.start()

audioPlayerNode.play()

这假设在playground资源目录中存在song.mp3

答案 1 :(得分:0)

显然,抛出的异常是正常。它发生在我测试的任何条件和任何环境中,但不会干扰正常功能。

没有播放声音的原因是AVAudioEngineAVAudioPlayerNode对象在函数返回后立即释放,因为它们没有强大的指针使它们保持活动状态。我已通过将这两个对象保持为properties来修复此问题。