按顺序播放多个声音文件只播放最后一个声音

Play multiple sound files in sequence only playing last sound

此应用根据数字播放声音。我有多个非常短的 mp3 音频文件。正如问题所说,我希望它按顺序播放所有声音,一个接一个,但只播放最后一个声音(数字),我在控制台上收到错误消息:

"Uncaught (in promise) DOMException: The play() request was interrupted by a new load request."

我遗漏了什么,或者这不可能。感谢任何帮助。

function playSound(note){

    var currentPlayer;
    var player = document.getElementById("player");

    var isPlaying = player.currentTime > 0 && !player.paused && !player.ended 
&& player.readyState > 2;


     if (!isPlaying){

        player.src = "sounds/"+note+".mp3";
        player.play();

     }else{
        player.pause();
        player.currentTime = 0;
        currentPlayer = player;

     }



}


//variable with numbers where each number should load a sound and play
var numString = "0934590042529689108538569377239609480456034083552";


for(i = 0; i < numString.length; i++){


    switch (parseInt(numString[i])){
        case 1:
            playSound("C"); 
            break;
        case 2:
            playSound("D");
            break;
        case 3:
            playSound("E");
            break;
        case 4:
            playSound("F");
            break;
        case 5:
            playSound("G");
            break;

        case 6:
            playSound("A");
            break;

        case 7:
            playSound("B");
            break;

        case 8:
            playSound("C2");
            break;

        case 9:
            playSound("D2");
            break;


        case 0:
            playSound("silence");
            break;


}

Html:

<audio controls id="player" style="display: none">
    <source  src="#"></source>
</audio>

您必须等待第一个音符完成才能加载下一个音符:

var index = 0;
var numString = "0934590042529689108538569377239609480456034083552";
var notes = ['silence', 'C', 'D', 'E', 'F', 'G', 'A', 'B', 'C2', 'D2'];
var player = document.getElementById('player');

function playNote() {
  if (index >= numString.length) {
    stop();
    return;
  }
  var note = notes[Number(numString[index])]; // transform the number to the corresponding note ('1' => 'C')
  if (!note) {
    stop();
    return;
  }
  index++; // when 'playNote' is called the next time, the next note will be played
  player.src = `sounds/${note}.mp3`;
  player.play(); // when this ends, the 'ended' event will be fired and 'playNote' will be called
}

function stop () {
  player.removeEventListener('ended', playNote); // the last note has been played, remove the event listener
}

player.addEventListener('ended', playNote); // whenever the sound ends, call 'playNote'
playNote(); // start to play the first note

编辑:

我在 playNote 函数中将 this 更改为 player。第一次调用此函数时 (playNote()),没有 this 对象引用 player。应该是playNote.call(player)。但就像现在一样,它也应该如此。

要减少笔记之间的加载时间,您有两种可能性:

在多个 audios

中单独加载声音文件

为每个音符创建一个 new Audio() 并加载声音文件:

var numString = "0934590042529689108538569377239609480456034083552";
var notes = ['silence', 'C', 'D', 'E', 'F', 'G', 'A', 'B', 'C2', 'D2'];
var audios = {};
notes.forEach(note => {
  var audio = new Audio();
  audio.src = `sounds/${note}.mp3`; // load the sound file
  audios[note] = audio;
});

var currentAudio = null; // the audio that is currently playing

function playNote () {
  if (currentAudio) {
    currentAudio.removeEventListener('ended', playNote); // remove the event listener from the audio that has just stopped playing
  }
  if (index >= numString.length) {
    return;
  }
  var note = notes[Number(numString[index])]; // transform the number to the corresponding note ('1' => 'C')
  if (!note) {
    return;
  }
  currentAudio = audios[note];
  index++; // when 'playNote' is called the next time, the next note will be played
  currentAudio.play(); // when this ends, the 'ended' event will be fired and 'playNote' will be called
  currentAudio.addEventListener('ended', playNote);
}

playNote();

使用AudioContextAPI

新的 Web Audio API 比简单的 new Audio() 复杂得多,但功能更强大。您不需要在您的服务器上拥有所有可能的声音文件 - 您可以使用客户端的声音芯片来创建您想要的任何声音。