Web Audio Api 在不同浏览器中精确循环

Web Audio Api precise looping in different browsers

所以我想要的是从不同的音频源不断循环交换。出于演示目的,我制作了一个小益智游戏 - 你按 0 到 8 的顺序排列数字,并根据你如何排列它们来播放不同的循环。我设法在 Chrome 浏览器上获得了我想要的结果,但在 Safari 或 Firefox 上却没有。我尝试添加不同的音频目的地或多个音频上下文,但无论在 Safari 和其他浏览器中的一次迭代后什么循环都会停止,Chrome.

除外

这里是 link code-pen 上的演示 Demo Puzzle with music 请把你的声音关小,因为音乐可能有点太大声,我没有掌握。这是我用于网络音频 Api 操作的基本代码。 谢谢 *此外,它根本不适用于移动设备。

const AudioContext = window.AudioContext || window.webkitAudioContext;
var audioContext = new AudioContext();
const audio1 = document.getElementById("aud1");
const audio2 = document.getElementById("aud2");
const audio3 = document.getElementById("aud3");
const audio4 = document.getElementById("aud4");
var chosenTrack = audio2;
let gameStarted = false;

function startGame() {
document.getElementById("sHold").style.display = "none";
document.getElementById("container").style.display = "block";

gameStarted = true;
audioContext.resume();
audioContext = new AudioContext();
audio1.pause();
audio1.play();
audio1.currentTime = 0;

}

setInterval(function() {

if (gameStarted) {
    //console.log(audioContext.currentTime );
    if (audioContext.currentTime >= 6.4) {
        audioContext = new AudioContext();
        chosenTrack.pause();
        chosenTrack.play();
        chosenTrack.currentTime = 0;
    }
}
}, 5);

一些想法:

  • 您并没有真正以这种方式使用网络音频,您仍在使用音频元素作为源,如果您希望能够实现精确的计时,这无济于事。您应该将它们加载到 AudioBuffers 中并使用 AudioBufferSourceNode 播放它们。

  • 如果你绝对想使用音频元素(因为你使用的文件非常大并且你想流式传输它们)你可能想在上面使用循环 属性 虽然我怀疑这是否最终是精确和无缝的。

  • 永远不要使用 setInterval 来获取每一帧的回调,使用 requestAnimationFrame

  • 不要使用 setInterval 或 requestAnimationFrame 来实现精确的音频循环,javascript 线程不够精确,无法做到这一点并且当其他事情需要更多的时间,例如屏幕上有太多的敌人。您应该不时提前安排时间:https://www.html5rocks.com/en/tutorials/audio/scheduling/

  • AudioBufferSourceNodes 有一个循环布尔值 属性 将尽可能精确地循环它们

  • 请注意,不同的音频解码器(因此:不同的浏览器)对音频文件的解码可能略有不同:例如,有些可能在开始时多几毫秒。当使用多个循环的 AudioBufferSourceNode 时,这可能会成为一个问题,这些节点在 x 时间后可能 运行 不同步。我总是在需要的确切时间重新安排一些事情,而不是使用循环 属性.