我正在使用WebAudio API在多个源之间进行淡入淡出。淡入使用setValueCurveAtTime(曲线,时间,持续时间)排队。 WebAudio规范指示不允许对具有重叠持续时间的setValueCurveAtTime进行任何后续调用。所以我在排队新的淡入淡出之前打电话给cancelScheduledValues(time)。但是,Firefox v68和Chrome v77都会在第二个setValueCurveAtTime调用上引发错误。
附带的代码段包含在任一浏览器中触发错误的最少代码量。 单击开始触发错误。请注意,它不会播放任何音频,因为不需要抛出任何错误。选择下拉列表允许控制两个函数的time
参数。在Chrome v77中,time=0
不会触发错误。
任何有关如何在两种浏览器中都能使用它的想法,将不胜感激!
更新:正如Raymond Toy所指出的那样,cancelScheduledValues(t)似乎可以取消在t
或更高版本中started的自动化(在t
期间不仅有效)。通过使用cancelScheduledValues(Math.max(t - duration, 0))
,该代码现在似乎可以在Chrome中使用。 Firefox仍然失败,并显示Operation is not supported
错误。
<!DOCTYPE html>
<html>
<body>
<button id="start">Start</button>
<select id="time">
<option value="0">time=0</option>
<option value="1">time=currentTime</option>
</select>
<pre id="log"></pre>
<script>
const select = document.querySelector('#time')
const log = document.querySelector('#log')
function start() {
const ctx = new AudioContext()
ctx.resume()
const gain = ctx.createGain()
gain.connect(ctx.destination)
// Fade in
gain.gain.setValueCurveAtTime(new Float32Array([0, 1]), 0, 1)
setTimeout(() => {
const time = select.options[select.selectedIndex].value === '0' ? 0 : ctx.currentTime
// Replace fade in with fade out
// THIS IS THE CALL THAT DOESN'T WORK =====
// Doesn't work in Firefox nor Chrome:
// gain.gain.cancelScheduledValues(time)
// Doesn't work in Firefox:
gain.gain.cancelScheduledValues(Math.max(time - 1 /* duration of previous fade */, 0))
try {
// ERROR IS THROWN HERE =================
gain.gain.setValueCurveAtTime(new Float32Array([0, 1]), time, 1)
} catch (error) {
log.prepend(error.message + '\n')
throw error
}
log.prepend('No error!\n')
}, 100)
}
document.querySelector('#start').addEventListener('click', start)
</script>
</body>
</html>
[我对cancelScheduledValues的阅读表明,它正在按预期工作。 setValueCurveAtTime(curve, time, duration)
的事件时间为time
。 cancelScheduledValues(t2)
删除事件时间为t2
或更长的所有事件。在您的测试用例中,time
= 0,并且t2
为currentTime
,该值大于0。因此,不会从时间轴中删除任何内容。对setValueCurveAtTime
的第二次调用将插入一个新事件,该事件确实与前一个事件重叠。因此,您会得到一个错误。
话虽如此,我认为这有点出乎意料。这可能是WebAudio规范中的错误。