AudioKit中AppleSequencer与音频播放器同步问题求助
解决Apple Sequencer与AVAudioPlayer的同步播放问题
你的核心问题在于启动时机错位:当前代码先启动Sequencer,再去获取节拍0的主机时间,此时Sequencer已经开始播放,导致获取到的时间并非真正的起始点;同时音频播放器使用.now()启动,自然无法和Sequencer同步。
修正方案:统一同步时间基准
先获取Sequencer节拍0对应的准确主机时间,再让Sequencer和所有音频播放器基于同一个时间点启动,确保时序完全对齐。
修改后的代码
func startPlayback(_ loopPlayback: Bool, startTime: AVAudioTime = .now()) { sequencerTwo.rewind() sequencerTwo.preroll() // 提前获取节拍0对应的主机时间,作为全局同步基准 guard let syncHostTime = try? sequencerTwo.hostTime(forBeats: 0) else { print("无法获取序列同步时间") return } let syncTime = AVAudioTime(hostTime: syncHostTime) // 让Sequencer在同步时间点启动 sequencerTwo.play(at: syncHostTime) // 让所有音频播放器复用同一个同步时间 startAudioPlayers(loopPlayback, startTime: syncTime) } func startAudioPlayers(_ loopPlayback: Bool, startTime: AVAudioTime) { isPlaying = true do { try startAudioEngine() } catch { print("音频引擎启动失败:\(error)") return } self.playbackChannels.forEach { channel in let player = channel.getAudioPlayer() player.isLooping = loopPlayback // 用统一的同步时间启动播放器 player.play(at: startTime, completionCallbackType: .dataPlayedBack) } }
关键要点说明
- 提前锁定同步时间:在启动Sequencer前就获取节拍0的主机时间,避免Sequencer启动后时间滞后。
- 统一启动触发:Sequencer和音频播放器使用完全相同的时间基准启动,消除时序差。
- 完善错误处理:替换
try!为安全的guard let,避免运行时崩溃并提供错误提示。
额外注意事项
- 确保
AudioEngine的节点连接(如采样器、播放器到混音节点)在启动前就配置完成,启动时再连接会引入额外延迟。 - 如果需要循环播放,同步Sequencer的
loopEnabled属性和音频播放器的isLooping状态,避免循环周期不一致。
内容的提问来源于stack exchange,提问作者Deji Toki
相关产品推荐
相关产品推荐

