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

时间:2017-07-16 10:48:05

标签: javascript html5-audio

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

“Uncaught(in promise)DOMException:play()请求被新的加载请求中断。”

我遗失了一些东西,或许这是不可能做到的。任何帮助表示赞赏。

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>

1 个答案:

答案 0 :(得分:2)

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

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

编辑:

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

为减少音符之间的加载时间,您有两种可能:

将声音文件分别加载到多个audio s

对于每个音符,创建一个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();

使用AudioContext API

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