我想要做的就是(现在)使用AVAudioEngine
和AVAudioPlayerNode
播放声音文件。这是我的代码:
//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.
这里有什么不能访问的?我还没有加载文件...感谢任何提示。
环境
修改
这是一些更多的上下文信息。上面的代码是使用SpriteKit
和GameplayKit
构建的iOS游戏的一部分。它位于GKStateMachine
的子类中,位于名为playSound
的方法中。在源自我的子SKScene
GameScene
touchesBegan
的触摸事件过程中调用此方法。在TouchComponent
后,呼叫将委派给touchesBegan
具有相同签名方法(touchDown
)的所有实体。这些组件将向其委托发起GKStateMachine
事件,而该委托又是GameStateMachine
的子类score
。如果触摸事件正确 w.r.t.在游戏规则中,GameStateMachine
的{{1}}属性会增加。在score
setter中,如果分数增加,则调用最终方法playSound
。这是我刚才描述的序列图:
答案 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)
显然,抛出的异常是正常。它发生在我测试的任何条件和任何环境中,但不会干扰正常功能。
没有播放声音的原因是AVAudioEngine
和AVAudioPlayerNode
对象在函数返回后立即释放,因为它们没有强大的指针使它们保持活动状态。我已通过将这两个对象保持为properties
来修复此问题。