由于存在太多的WebMediaPlayer,因此阻止创建WebMediaPlayer的尝试。

24
我们正在开发一种浏览器中的数字音频工作站。我们需要在选项卡中使用多个音频文件。我们使用new Audio(audioUrl)来播放自己的音频混合器中的音频。到目前为止,它一直在正常工作。 在最新版本的Chrome(92)中,我们遇到了上述代码片段引起以下错误的问题:
[Intervention] Blocked attempt to create a WebMediaPlayer as there are too many WebMediaPlayers already in existence. See crbug.com/1144736#c27

我无法访问提供的错误链接,它显示权限被拒绝。是否有建议的解决方法?

更新: 我不再使用HTMLAudioElement而是改用AudioBufferSourceNode。看起来这是唯一直接的解决方案,因为Chrome团队正在讨论对它们进行限制。 注意:我们可能需要播放超过1000个音频剪辑。这是关于chromium讨论线程的参考,在下一个发布版本中将增加到1000个webmediaplayers,即2021年8月5日之后。


2
相关源代码更改 https://chromium-review.googlesource.com/c/chromium/src/+/2816118 - digitalPBK
我通过在HTML中设置属性“preload”来解决了这个问题,以进行懒加载:preload="none"(完整示例:<audio src="…" preload="none"></audio>)。希望这可以帮到你。 - vcoppolecchia
4个回答

13

Chrome 92限制了特定标签页中可分配的音频和视频标签数量,桌面浏览器为75个,移动浏览器为40个。

目前唯一的解决办法是限制页面中创建的音频/视频标签数量。尝试重复使用已分配的音频/视频元素。

如果在启动Chrome时传递以下标志,则可以增加此限制,例如:--max-web-media-player-count=5000(当然我们不能指望最终用户这样做)

相关源代码在此处: https://chromium-review.googlesource.com/c/chromium/src/+/2816118

编辑:

在取消分配音频/视频元素之前,似乎设置以下内容可以强制清理该元素。

mediaElement.remove();
mediaElement.srcObject = null;

1
看起来这些限制可能会提高到桌面端为200,移动端为100 - Kohanz
看起来整个更改将被还原。 - digitalPBK
2
他们将在2021年8月3日的更新中将限制提高到1,000。讨论可以在此处找到:https://bugs.chromium.org/p/chromium/issues/detail?id=1232649。 - Kohanz
Chrome忽略了这个标志。有人解决了吗? - desperado06
我不知道将srcObject设置为null是否有效。 我知道mediaElement.src ='';对我有效。 您可以使用chrome:// media-internals确定确切情况。 另请参见https://bugs.chromium.org/p/chromium/issues/detail?id=1232649#c18和https://groups.google.com/a/chromium.org/g/media-dev/c/wEUYR7BvdZI/m/R-8X1EdiBAAJ?pli=1。 - David Winiecki

6
const MaxWebMediaPlayerCount = 75;

class VideoProducer {
  static #documentForVideo

  static createVideo() {
    if (!this.#documentForVideo || this.#documentForVideo.videoCount === MaxWebMediaPlayerCount) {
      const iframeForVideo = document.body.appendChild(document.createElement('iframe'));
      iframeForVideo.style.display = 'none';
      iframeForVideo.contentDocument.videoCount = 0;
      this.#documentForVideo = iframeForVideo.contentDocument;
    }
    this.#documentForVideo.videoCount++;
    const video = this.#documentForVideo.createElement('video');
    return video;
  }

  foo() {
    const video = VideoProducer.createVideo();
    // ...
  }

1
等等。所以你可以通过在iframe内创建视频,并将其作为新的视频文档根来解决这个问题?我不知道该有什么感觉... - Dominic Bou-Samra

3

我也遇到了这个问题,它导致我的游戏崩溃。以下是我找到的解决方法,希望能在此期间帮到你:

function playSound(  ) {
    var jump_sound = new Audio("./jump.mp3");
    jump_sound.play();

    jump_sound.onended = function(){
        this.currentSrc = null;
        this.src = "";
        this.srcObject = null;
        this.remove();
    };
}

注意:如果有太多并发声音,它仍然会阻塞,但是使用这段代码后,阻塞是暂时的。

1
至少 removeAttribute('src') 部分似乎并没有真正销毁媒体播放器。您可以通过 chrome://media-internals 证明这一点。相反,使用 this.src = '';。我认为必须分配空字符串很奇怪,但它确实有效。另请参见 https://bugs.chromium.org/p/chromium/issues/detail?id=1232649#c18 和 https://groups.google.com/a/chromium.org/g/media-dev/c/wEUYR7BvdZI/m/R-8X1EdiBAAJ?pli=1 - David Winiecki
我修改了这个答案,使用 src='' 而不是 removeAttribute('src'). - David Winiecki
2
注意:在我的情况下,src ='' 对我起作用。使用 chrome://media-internals 验证您使用的任何解决方案是否实际上在您的情况下销毁了音频播放器。 - David Winiecki
1
currentSrc 是 Chrome 上的一个 getter,尝试设置它会抛出异常。 - Ronen Ness

2

Chrome 版本 92.0.4515.131 似乎解决了这个问题。


1
如果我们使用的元素超过1000个,这仍然是一个问题。在Chromium源代码中提交了硬编码的1000个元素。 https://chromium.googlesource.com/chromium/src/+log/92.0.4515.107..92.0.4515.131?pretty=fuller&n=10000 https://chromium.googlesource.com/chromium/src/+/f7489718ee87fbef92c59d35d9437cf55466fa2c%5E%21/#F0 - Nasik Shafeek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接