多个 audioCtx addModule() 在检查器打开时调用冻结 Chrome

multiple audioCtx addModule() calls freeze Chrome when loaded with inspector open

我正在努力从 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,只是为了确保 separate 音频上下文对象不会被要求添加一个同时模块。我的意思是,这个小代码看起来不错,但要确保只有一个音频上下文在应用程序中添加模块要复杂得多:

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 检查器在被阻止后不会在任何地方显示任何有用的信息。

示例:

更新 (10/18/2018):此问题在最新版本中无法重现。 (72.0.3584.0) 在 issue entry.

中查看更多信息

这显然是一个错误。我通过 crbug.com 提交了 one,因此可以对其进行分类。可能需要一段时间才能找到罪魁祸首,因为该问题与 Web Audio、Worker 和 DevTools 有关。

与此同时,也许您可​​以用 async/await 替换 promise 链。至少,在这种情况下,它会给你更好的可读性。