音频在 Firefox 上无法正常播放

Audio not playing properly on Firefox

以下代码在 Chrome 88 上可以正确播放音频,但在 Firefox 85 上音频会中断,有时甚至无法播放。

window.onload = function() {
    Audio.prototype.stop = function() {
        audio.pause();
        audio.currentTime = 0;
    }

    let audio = new Audio("./audio.mp3");
    let count = 0;

    function replay() {
        audio.stop();
        audio.play();
    }

    let button = document.getElementsByTagName("button")[0];
    button.addEventListener("click", function() {
        let interval = setInterval(function() {
            if (count < 10) {
                replay();
                count += 1;
            } else {
                clearInterval(interval);
                count = 0;
            }
        }, 100);
    });
}

如何解决此问题,以便在 Firefox 中正确播放音频?可以找到重现问题所需的所有文件 here

我没有任何使用 HTMLAudioElements 的经验, 但该错误似乎并不在您的代码中。
(这是有道理的,因为它确实适用于 Chrome)

Mozilla MDN's documentation about this 也没有显示任何与 Firefox 相关的内容可能不受支持。
(除了 supporting more than one audio type,我认为这里不是这种情况)

奇怪。

您是否尝试查看这些问题以寻找可能 help/guide 您找到答案的答案?
HTML5 audio not working on Firefox
HTML5-Audio-tag not playing in Firefox

祝你找到正确的解决方法,完成后给我评论!

这是因为 HTMLMediaElement API 本质上是异步的,您不能指望它能够像那样维持每 100 毫秒导航一次。
即使 currentTime 的设置实际上是异步的,所以对于非常短的间隔,您可能需要音频在它有时间重新开始之前就停止。

对于您想做的事情,请使用 Web Audio API 及其 AudioBuffer 接口,以及 AudioBufferSourceNodes 这是播放器的真正精简表示,您可以极其精确地控制它延迟非常低:

(async () => {
  const context = new (window.AudioContext || window.webkitAudioContext)();
  const buffer = await fetch( "https://cdn.jsdelivr.net/gh/joaobzrr/firefox-audio-problem/audio.mp3" )
    .then( (resp) => resp.ok && resp.arrayBuffer() );
  const audiobuffer = await context.decodeAudioData( buffer );

  document.getElementById( "btn" ).onclick = async (evt) => {
    for ( let i = 0; i < 10; i++ ) {
      const buffersource = context.createBufferSource();
      buffersource.buffer = audiobuffer;
      buffersource.connect( context.destination );
      const starttime = context.currentTime + (i * 0.1);
      buffersource.start( starttime, 0, 0.1 );
    }
  };
})().catch( console.error );
<script src="https://cdn.jsdelivr.net/gh/mohayonao/promise-decode-audio-data@eb4b1322113b08614634559bc12e6a8163b9cf0c/build/promise-decode-audio-data.min.js"></script>
<button id="btn">click to start</button>