浏览器是否限制每个会话的decodeAudioData调用数量?

问题描述 投票:0回答:1

我有一个 React Next Web 应用程序,它使用 Web 音频 api 播放歌曲。我注意到浏览大量歌曲后,有时我的应用程序将无法加载新歌曲。

在 Chrome 中我收到此错误: 无法在“BaseAudioContext”上执行“decodeAudioData”:无法解码音频数据, 并且只有刷新页面后(有时需要刷新2-3次),我才能再次加载歌曲。 在 Chrome 开发工具的“内存”选项卡中查看“JS 堆总大小”并不表明存在内存泄漏。

在 Safari 中,它只是自动刷新页面。

为了确保它不在我的代码中,我用一个最小的示例创建了一个新的网络应用程序,并且我可以重现该问题。我在大约 250 次后收到解码错误。

export const test = async () => {
  const audioContext = new AudioContext();
  const blob = (
    await axios.get("./url-to-some-song.wav", {
      responseType: "blob",
    })
  ).data;

  for (let i = 0; i < 300; i++) {
    const arrayBuffer = await blob.arrayBuffer();
    const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);
  }
};

我尝试在每次迭代后添加延迟 - 但这没有帮助。 看起来浏览器可能有一些限制,但我找不到任何相关文档。 可能是什么?

web-audio-api
1个回答
0
投票

我可以在 Chrome v122 中重现该问题。使用

structuredClone()
时似乎已修复。但我没有很好的解释为什么会这样。我猜这是 Chrome 中的一个错误。

export const test = async () => {
  const audioContext = new AudioContext();
  const blob = (
    await axios.get("./url-to-some-song.wav", {
      responseType: "blob",
    })
  ).data;

  for (let i = 0; i < 300; i++) {
    const arrayBuffer = await blob.arrayBuffer();
    const audioBuffer = await audioContext.decodeAudioData(
      structuredClone(arrayBuffer)
    );
  }
};

您还可以通过直接获取数据作为

'arrayBuffer'
来避免额外的步骤。

export const test = async () => {
  const audioContext = new AudioContext();
  const arrayBuffer = (
    await axios.get("./url-to-some-song.wav", {
      responseType: "arrayBuffer",
    })
  ).data;

  for (let i = 0; i < 300; i++) {
    const audioBuffer = await audioContext.decodeAudioData(
      structuredClone(arrayBuffer)
    );
  }
};
© www.soinside.com 2019 - 2024. All rights reserved.