【发布时间】:2019-06-05 19:39:58
【问题描述】:
我的 SpriteKit 游戏中有一个问题,在应用被电话打断后,使用 playSoundFileNamed(_ soundFile:, waitForCompletion:) 的音频将无法播放。 (我还在我的应用程序中使用了 SKAudioNodes,它们不受影响,但我真的真的很想也能够使用 SKAction playSoundFileNamed。)
这里是一个简化的 SpriteKit 游戏模板中的 gameScene.swift 文件,它重现了该问题。你只需要在项目中添加一个音频文件并称之为“note”
我已将应驻留在 appDelegate 中的代码附加到切换开/关按钮以模拟电话中断。该代码 1)停止 AudioEngine 然后停用 AVAudioSession -(通常在 applicationWillResignActive 中)......和 2)激活 AVAudioSession 然后启动 AudioEngine -(通常在 applicationDidBecomeActive 中)
错误:
AVAudioSession.mm:1079:-[AVAudioSession setActive:withOptions:error:]:停用正在运行 I/O 的音频会话。在停用音频会话之前,应停止或暂停所有 I/O。
当尝试停用音频会话但仅在至少播放一次声音后才会出现这种情况。 复制:
1) 运行应用程序 2) 关闭和打开引擎几次。不会发生错误。 3) 点击 playSoundFileNamed 按钮 1 次或多次以播放声音。 4)等待声音停止 5) 再等一段时间再确定
6) 点击切换音频引擎按钮以停止音频引擎并停用会话 - 发生错误。
7) 切换引擎几次以查看会话激活、会话停用、会话激活打印在调试区域 - 即没有报告错误。 8) 现在会话处于活动状态并且引擎正在运行,playSoundFileNamed 按钮将不再播放声音。
我做错了什么?
import SpriteKit
import AVFoundation
class GameScene: SKScene {
var toggleAudioButton: SKLabelNode?
var playSoundFileButton: SKLabelNode?
var engineIsRunning = true
override func didMove(to view: SKView) {
toggleAudioButton = SKLabelNode(text: "toggle Audio Engine")
toggleAudioButton?.position = CGPoint(x:20, y:100)
toggleAudioButton?.name = "toggleAudioEngine"
toggleAudioButton?.fontSize = 80
addChild(toggleAudioButton!)
playSoundFileButton = SKLabelNode(text: "playSoundFileNamed")
playSoundFileButton?.position = CGPoint(x: (toggleAudioButton?.frame.midX)!, y: (toggleAudioButton?.frame.midY)!-240)
playSoundFileButton?.name = "playSoundFileNamed"
playSoundFileButton?.fontSize = 80
addChild(playSoundFileButton!)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if let touch = touches.first {
let location = touch.location(in: self)
let nodes = self.nodes(at: location)
for spriteNode in nodes {
if spriteNode.name == "toggleAudioEngine" {
if engineIsRunning { // 1 stop engine, 2 deactivate session
scene?.audioEngine.stop() // 1
toggleAudioButton!.text = "engine is paused"
engineIsRunning = !engineIsRunning
do{
// this is the line that fails when hit anytime after the playSoundFileButton has played a sound
try AVAudioSession.sharedInstance().setActive(false) // 2
print("session deactivated")
}
catch{
print("DEACTIVATE SESSION FAILED")
}
}
else { // 1 activate session/ 2 start engine
do{
try AVAudioSession.sharedInstance().setActive(true) // 1
print("session activated")
}
catch{
print("couldn't setActive = true")
}
do {
try scene?.audioEngine.start() // 2
toggleAudioButton!.text = "engine is running"
engineIsRunning = !engineIsRunning
}
catch {
//
}
}
}
if spriteNode.name == "playSoundFileNamed" {
self.run(SKAction.playSoundFileNamed("note", waitForCompletion: false))
}
}
}
}
}
【问题讨论】:
标签: ios swift audio avaudiosession avaudioengine