You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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)
    }
}

关键要点说明

  1. 提前锁定同步时间:在启动Sequencer前就获取节拍0的主机时间,避免Sequencer启动后时间滞后。
  2. 统一启动触发:Sequencer和音频播放器使用完全相同的时间基准启动,消除时序差。
  3. 完善错误处理:替换try!为安全的guard let,避免运行时崩溃并提供错误提示。

额外注意事项

  • 确保AudioEngine的节点连接(如采样器、播放器到混音节点)在启动前就配置完成,启动时再连接会引入额外延迟。
  • 如果需要循环播放,同步Sequencer的loopEnabled属性和音频播放器的isLooping状态,避免循环周期不一致。

内容的提问来源于stack exchange,提问作者Deji Toki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 13:22:44