我正在从OfflineAudioContext对象加载AudioWorklet处理器。我的用例是,我试图预生成并显示有关声音的视觉数据,然后再为用户播放。
我正在尝试使用OfflineAudioContext,其想法是编写processor.js
来缓存生成的音频,但是我们有一个解决之道。
我正在使用Chrome,但还没有找到在FF或Safari中使用AudioContext的方法。
// in Sound object #1
const offlineCtx1 = new OfflineAudioContext(2, 44100, 44100);
offlineCtx1.audioWorklet.addModule("processor.js")
.then(() => log("first context loaded the processor"));
// ...
// in Sound object #2
const offlineCtx2 = new OfflineAudioContext(2, 44100, 44100);
offlineCtx2.audioWorklet.addModule("processor.js")
.then(() => log("second context loaded the processor"));
当我尝试将模块添加到两个不同的上下文中时,发生了一些有趣的事情。如果检查器已关闭,则页面加载正常。但是,如果检查器处于打开状态,则浏览器选项卡将在某种程度上冻结。您无法与页面互动或关闭标签页,但可以在检查器内部做一些有限的事情。
这似乎是一些计时问题:如果您等待1000毫秒或等待用户交互来发起第二个addModule()
调用,那么它可以正常工作。
实际上,我找到的最好的解决方法是:在对.addModule()
的调用中建立一个Promise链,并等待第一个返回,然后再触发下一个。
但是,实际上,这要求以一种看起来很傻的方式将Promises编织到对象中,只是要确保不会要求单独音频上下文对象同时添加模块。我的意思是,这种小的代码看起来不错,但是要确保只有一个音频上下文在应用程序中添加模块要复杂得多:
const offlineCtx1 = new OfflineAudioContext(2, 44100, 44100);
offlineCtx1.audioWorklet.addModule("processor.js")
.then(() => log("first context loaded the processor") )
.then(() => {
const offlineCtx2 = new OfflineAudioContext(2, 44100, 44100);
return offlineCtx2.audioWorklet.addModule("processor.js")
})
.then(() => log("second context loaded the processor") );
很显然,某种时序问题可以通过确保顺序发生来解决。我使用的是Chrome v 69.0.3497.100(正式版)(64位)
任何人都知道为什么会这样吗?或建议进一步调试? Chrome检查器出现问题后,不会在任何地方显示任何有用的信息。
示例:
答案 0 :(得分:0)
更新(2018年10月18日):在最新版本中无法重现此问题。 (72.0.3584.0)在issue entry中查看更多信息。
它显然看起来像是个错误。我通过crbug.com提交了one,因此可以对其进行分类。追查罪魁祸首可能需要一段时间,因为该问题与Web Audio,Worker和DevTools有关。
同时,也许您可以用async / await替换promise链。至少,在这种情况下,它将为您提供更好的可读性。