如何用js audio播放多个音频api

how to play multiple audio with js audio api

我正在从服务器读取音频文件。我有一个原始音频文件数组。

const allAudio = [];

然后依次播放

var volumeSeq=1;

    function playAudio(){
     if(volumeSeq==allAudio.length){ volumeSeq=1;}
      var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
      source = audioCtx.createBufferSource();
      audioCtx.decodeAudioData(allAudio[volumeSeq], function(buffer) {
      source.buffer = buffer;
      console.log(source.buffer);
      source.connect(audioCtx.destination);
      source.loop = false;});

      source.start(0);
      source.onended = function () {
        volumeSeq++;
        playAudio();
}

我发现了问题。但我不知道为什么。问题是,在数组解码 i.element 之后,其中的元素被删除了。我的意思是当我解码 allAudio[1] 然后 allAudio[1] 是空的。 所以我无法为这些音轨创建循环。

我该怎么办?

为什么不在开头解码所有音频文件,然后循环遍历它们?像这样:

var allAudio = [];
var audioCtx = new AudioContext();
var volumeSeq = 0;
var decodedAudio = [];

function decodeAudio() {
    allAudio.forEach(function (file, index) {
        audioCtx.decodeAudioData(file, function(buffer) {
            decodedAudio[index] = buffer;
            if (decodedAudio.length >= allAudio.length) {
                play();
            }
        })
     })
}
function play() {
    if (volumeSeq >= allAudio.length){ volumeSeq=0;}
    var source = audioCtx.createBufferSource();
    source.buffer = decodedAudio[volumeSeq];
    source.connect(audioCtx.destination);
    source.start(0);
    source.onended = function () {
        volumeSeq++;
        play();
    }
}
decodeAudio();

还有几件事:

  • 您不需要每次都创建 AudioContext
  • AudioBufferSourceNode.loop 默认为 false。您可以跳过 source.loop = false;
  • 每个新变量都应以 constletvar 开头。你错过了 source。顺便说一句,现在最好使用 constlet,而不是 var。我将在下一个“现代”示例中展示它。
  • 我不知道你为什么要从索引 1 开始迭代 allAudio。数组中的第一个索引是 0。

如果您不喜欢 IE 等旧浏览器,可以使用 Promisesasync/await:

使代码更简洁
const audioCtx = new AudioContext();
async function start() {
   const decodedAudio = await Promise.all(allAudio.map((file) => audioCtx.decodeAudioData(file)));
   let volumeSeq = 0;
   function play() {
        if(volumeSeq >= allAudio.length) volumeSeq = 0;
        const source = audioCtx.createBufferSource();
        source.buffer = decodedAudio[volumeSeq];
        source.connect(audioCtx.destination);
        source.start(0);
        source.addEventListener('ended', () => {
           volumeSeq++;
           play();
        }, { once: true })
   }
   play();
}
start()