我们正在开发一个SpriteKit游戏。为了更好地控制音效,我们从使用SKAudioNodes切换到使用一些AVAudioPlayers。虽然在游戏玩法、帧率和音效方面一切似乎都运行良好,但在物理设备上测试时,有时会在控制台输出中看到偶尔的错误(?)消息:
... [general] __CFRunLoopModeFindSourceForMachPort returned NULL for mode 'kCFRunLoopDefaultMode' livePort: #####
当它发生时,似乎并没有真正造成任何损害(没有声音故障或帧速率问题等),但不理解这个消息的确切含义以及为什么会发生,让我们感到紧张。
细节如下:
游戏全部采用标准的SpriteKit,所有事件均由SKActions驱动,没有任何异常。
使用AVFoundation的内容如下。应用程序音效的初始化:
创建各种声音效果播放器:
播放声音效果:
AVAudioPlayers都是用于没有循环的短声音效果,它们被重复使用。我们总共创建了大约25个播放器,包括某些效果的多个播放器,当它们可以快速重复时。对于特定的效果,我们在固定序列中轮流使用该效果的播放器。我们已经验证,每当触发播放器时,它的isPlaying为false,因此我们不会尝试在已经播放的内容上调用play。
这个消息并不经常出现。在可能有数千个声音效果的5-10分钟的游戏过程中,我们可能会看到这个消息5-10次。
这个消息似乎最常出现在一堆声音效果被快速连续播放时,但感觉它并不完全与此相关。
不使用dispatch队列(即让sounds.execute直接调用soundActions())无法解决问题(尽管这会导致游戏明显卡顿)。将dispatch队列更改为其他优先级,如.utility,也不会影响问题。
使sounds.execute立即返回(即根本不调用闭包,因此没有play())确实消除了消息。
我们在此链接中找到了产生消息的源代码。 但我们只在抽象层面上理解它,不确定如何运行循环与AVFoundation相关。大量搜索没有找到任何有用的信息。正如我所说,这似乎并没有造成明显的问题。知道为什么会发生这种情况,要么知道如何修复它,要么确信它永远不会成为问题,这将是很好的。
... [general] __CFRunLoopModeFindSourceForMachPort returned NULL for mode 'kCFRunLoopDefaultMode' livePort: #####
当它发生时,似乎并没有真正造成任何损害(没有声音故障或帧速率问题等),但不理解这个消息的确切含义以及为什么会发生,让我们感到紧张。
细节如下:
游戏全部采用标准的SpriteKit,所有事件均由SKActions驱动,没有任何异常。
使用AVFoundation的内容如下。应用程序音效的初始化:
class Sounds {
let soundQueue: DispatchQueue
init() {
do {
try AVAudioSession.sharedInstance().setActive(true)
} catch {
print(error.localizedDescription)
}
soundQueue = DispatchQueue.global(qos: .background)
}
func execute(_ soundActions: @escaping () -> Void) {
soundQueue.async(execute: soundActions)
}
}
创建各种声音效果播放器:
guard let player = try? AVAudioPlayer(contentsOf: url) else {
fatalError("Unable to instantiate AVAudioPlayer")
}
player.prepareToPlay()
播放声音效果:
let pan = stereoBalance(...)
sounds.execute {
if player.pan != pan {
player.pan = pan
}
player.play()
}
AVAudioPlayers都是用于没有循环的短声音效果,它们被重复使用。我们总共创建了大约25个播放器,包括某些效果的多个播放器,当它们可以快速重复时。对于特定的效果,我们在固定序列中轮流使用该效果的播放器。我们已经验证,每当触发播放器时,它的isPlaying为false,因此我们不会尝试在已经播放的内容上调用play。
这个消息并不经常出现。在可能有数千个声音效果的5-10分钟的游戏过程中,我们可能会看到这个消息5-10次。
这个消息似乎最常出现在一堆声音效果被快速连续播放时,但感觉它并不完全与此相关。
不使用dispatch队列(即让sounds.execute直接调用soundActions())无法解决问题(尽管这会导致游戏明显卡顿)。将dispatch队列更改为其他优先级,如.utility,也不会影响问题。
使sounds.execute立即返回(即根本不调用闭包,因此没有play())确实消除了消息。
我们在此链接中找到了产生消息的源代码。 但我们只在抽象层面上理解它,不确定如何运行循环与AVFoundation相关。大量搜索没有找到任何有用的信息。正如我所说,这似乎并没有造成明显的问题。知道为什么会发生这种情况,要么知道如何修复它,要么确信它永远不会成为问题,这将是很好的。
AvAudioPlayer
已经内置在SKAudioNode
中,您可以从AVAudioNode
中访问所需内容。无论如何,看起来有人正在尝试从音频端口获取数据,但在抓取时该端口不可用。也许是因为您正在后台线程上执行此操作。 - Knight0fDragon