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

Web Audio API的oscillator如何实现onstarted启动监听事件?

Web Audio API Oscillator 启动事件实现方案

Web Audio API 没有为 OscillatorNode 提供原生的onstarted启动事件回调,你写的osc.onstarted赋值不会生效是正常表现。要实现启动时的通知逻辑,可以参考以下两种实现方案:


方案1:定时匹配方案(绝大多数场景够用)

原理:osc.start(delayTime)的入参是相对于当前AudioContext.currentTime的延迟秒数,直接按照该时间设置主线程定时器即可,实现成本极低。

const ac = new AudioContext()

const osc = ac.createOscillator()
osc.type = 'sawtooth'
osc.connect(ac.destination)

const startDelay = 5 // 和osc.start的入参保持一致
// 注册启动回调
setTimeout(() => {
  console.log('oscillator started!')
}, startDelay * 1000)

osc.onended = () => console.log('oscillator ended!')

osc.start(startDelay)
osc.stop(7)

注意:如果AudioContext处于挂起状态,需要等ac.resume()执行完成后再设置定时器,否则会出现时间偏差。


方案2:音频线程同步方案(高精度场景适用)

如果主线程存在阻塞可能、对回调触发的时间精度要求极高,可以借助辅助静音振荡器的onended事件模拟启动回调,回调完全由音频线程触发,不会受主线程调度影响。

const ac = new AudioContext()

const osc = ac.createOscillator()
osc.type = 'sawtooth'
osc.connect(ac.destination)

const startDelay = 5
// 创建静音辅助振荡器
const helperOsc = ac.createOscillator()
const helperGain = ac.createGain()
helperGain.gain.value = 0 // 完全静音不会输出可听见的声音
helperOsc.connect(helperGain)
helperGain.connect(ac.destination)
// 辅助振荡器和目标振荡器同时启动,启动后1毫秒停止,onended事件等价于启动通知
helperOsc.start(startDelay)
helperOsc.stop(startDelay + 0.001)
helperOsc.onended = () => {
  console.log('oscillator started! 和音频输出完全同步')
}

osc.onended = () => console.log('oscillator ended!')

osc.start(startDelay)
osc.stop(7)

内容的提问来源于stack exchange,提问作者Yukulélé

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 23:54:03