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é
相关产品推荐
相关产品推荐

