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

如何在AKSequencer播放时获取Timebase?需用于功能与应用同步

解决AKSequencer播放时Timebase持续递减的问题

我来帮你分析下这个问题的根源,以及对应的解决方案:

问题出在哪?

你当前计算timeBase的方式mach_absolute_time() - AVAudioTime.hostTime(forSeconds: posSeconds)之所以会持续递减,核心原因是AKSequencer的播放时钟和系统主机时钟存在微小的频率偏差:

  • sequencer.currentPosition.seconds是由音频硬件时钟驱动的(专门为音频播放优化,精度高);
  • mach_absolute_time()则是系统主机时钟的计时,和音频时钟的增速不可能完全一致。

随着播放持续,两者的时间差会不断累积,导致你计算出的timeBase出现持续变化(你看到的是递减,说明音频时钟走得比主机时钟慢一丢丢)。

正确的解决方案

方案1:播放开始时一次性记录基准偏移

不要每次播放过程中重新计算timeBase,而是在播放启动的瞬间记录好固定的基准值,后续直接复用:

  1. 先在你的类里加两个属性存基准值:
private var playbackStartHostOffset: UInt64 = 0
private var playbackStartPosition: Double = 0
  1. 监听AKSequencer的播放启动事件,记录初始基准:
// 注册播放启动通知
NotificationCenter.default.addObserver(
    forName: .AKSequencerPlaybackStarted,
    object: sequencer,
    queue: .main
) { [weak self] _ in
    guard let self = self else { return }
    self.playbackStartPosition = self.sequencer.currentPosition.seconds
    // 计算并保存初始的时间基准偏移
    self.playbackStartHostOffset = mach_absolute_time() - AVAudioTime.hostTime(forSeconds: self.playbackStartPosition)
}
  1. 修改你的getTimebase函数,直接返回预存的基准:
func getTimebase() -> UInt64 {
    return sequencer.isPlaying ? playbackStartHostOffset : 0
}

用这个基准转换时间的示例:

// 从主机时间转换为对应的播放位置秒数
let currentHostTime = mach_absolute_time()
let elapsedHostTime = currentHostTime - getTimebase()
let currentPlaybackSeconds = AVAudioTime.seconds(forHostTime: elapsedHostTime)

方案2:直接使用音频时钟(更可靠)

AKSequencer基于AVAudioEngine运行,你可以直接用它关联的音频时钟来获取完全同步的时间基准,彻底避免时钟偏差问题:

func getAudioAlignedTimebase() -> UInt64 {
    guard sequencer.isPlaying, 
          let audioClock = sequencer.engine?.mainMixerNode.outputAudioClock else {
        return 0
    }
    // 用音频时钟的当前时间和主机时间计算基准
    let currentAudioTime = audioClock.currentTime().seconds
    return audioClock.hostTime() - AVAudioTime.hostTime(forSeconds: currentAudioTime)
}

这个方式的精度更高,因为它直接绑定了音频播放的硬件时钟,和AKSequencer的播放进度完全同步。

额外建议

如果你的核心需求是让其他功能和AKSequencer严格同步,其实更推荐直接使用sequencer.currentPosition或者AVAudioClock的时间,而不是绕到mach_absolute_time——毕竟音频时钟是专门为音频播放设计的,同步性和精度都更有保障。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:16:29