【问题标题】:Play multiple sound files in sequence only playing last sound按顺序播放多个声音文件只播放最后一个声音
【发布时间】:2017-12-21 00:18:45
【问题描述】:

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

“未捕获(承诺中)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>

【问题讨论】:

  • 该循环在几毫秒内完成。在设置下一个src 之前,它不会等待每个声音完成。你需要一个递归函数,使用一个声音的结尾来设置下一个

标签: javascript html5-audio


【解决方案1】:

在加载下一个之前,您必须等待第一个注释完成:

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()),没有引用playerthis 对象。应该是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();

使用AudioContext API

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

【讨论】:

  • 感谢您的快速回复,我尝试了您的代码,但收到错误“Uncaught TypeError: this.play is not a function”
  • 好吧,我将“this”更改为“player”,它可以工作。非常感谢;)
  • 是否可以使其加载更快?还是玩得更快?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多