在打开检查器的情况下加载多个audioCtx addModule()会冻结Chrome

时间:2018-09-30 02:38:43

标签: javascript google-chrome web-audio web-audio-api

我正在从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检查器出现问题后,不会在任何地方显示任何有用的信息。

示例:

1 个答案:

答案 0 :(得分:0)

更新(2018年10月18日):在最新版本中无法重现此问题。 (72.0.3584.0)在issue entry中查看更多信息。

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

同时,也许您可​​以用async / await替换promise链。至少,在这种情况下,它将为您提供更好的可读性。