草庐IT

javascript - 网络音频 API : How Can I Re-start the Playback Of a Sound?

coder 2024-07-29 原文

我在 Chrome 中编写了一个基本脚本,它使用新的 Web Audio Api 加载 3 个声音文件(通过 XMLHTTPRequest)并单独播放每个文件。我为每种声音提供了一个单独的按钮,允许用户开始和停止每种声音。

该脚本会立即加载所有三个声音文件,完成后,取消播放按钮的灰色,以便用户只能在声音准备就绪后点击播放。此外,声音是循环播放的,因此单击按钮时每个按钮上的标签会在“播放”和“停止”之间变化。

这一切都很好...当您单击“播放”按钮时,您会听到循环播放的声音,而当您单击“停止”时,声音会停止。但是,当您第二次尝试重新播放相同的声音时,该声音不会再次开始播放。每次单击“播放/停止”按钮时,都会调用相应的 playSound() 或 stopSound() 函数并传入相应的参数,但由于某种原因,我无法让声音再次播放。我做错了什么吗?

这是我的代码:

<body>

<label for="playBtn1">Moog:</label>
<input id="playBtn1" type="button" value="Play" disabled />
<label for="playBtn1">Drums:</label>
<input id="playBtn2" type="button" value="Play" disabled />
<label for="playBtn1">Choir:</label>
<input id="playBtn3" type="button" value="Play" disabled />

<script>
  var playBtn1 = document.getElementById("playBtn1");
  var playBtn2 = document.getElementById("playBtn2");
  var playBtn3 = document.getElementById("playBtn3");

  var context = new webkitAudioContext();

  var soundBuffer1 = null;
  var soundBuffer2 = null;
  var soundBuffer3 = null;

  var soundBufferSourceNode1 = context.createBufferSource();
  soundBufferSourceNode1.looping = true;
  var soundBufferSourceNode2 = context.createBufferSource();
  soundBufferSourceNode2.looping = true;
  var soundBufferSourceNode3 = context.createBufferSource();
  soundBufferSourceNode3.looping = true;

  loadSound('micromoog.wav', 1);
  loadSound('breakbeat-drum-loop.wav', 2);
  loadSound('choir.wav', 3);

  playBtn1.addEventListener("click", function(e) {
    if(this.value == "Play") {
      this.value = "Stop";
      playSound(soundBuffer1, soundBufferSourceNode1);
    } else if(this.value == "Stop") {
      this.value = "Play";
      stopSound(soundBufferSourceNode1);
    }
  }, false);
  playBtn2.addEventListener("click", function(e) {
    if(this.value == "Play") {
      this.value = "Stop";
      playSound(soundBuffer2, soundBufferSourceNode2);
    } else if(this.value == "Stop") {
      this.value = "Play";
      stopSound(soundBufferSourceNode2);
    }
  }, false);
  playBtn3.addEventListener("click", function(e) {
    if(this.value == "Play") {
      this.value = "Stop";
      playSound(soundBuffer3, soundBufferSourceNode3);
    } else if(this.value == "Stop") {
      this.value = "Play";
      stopSound(soundBufferSourceNode3);
    }
  }, false);

  function loadSound(url, bufferNum) {
    var request = new XMLHttpRequest();
    request.open('GET', url, true);
    request.responseType = 'arraybuffer';

    // Decode asynchronously
    request.onload = function() {
      var successCallback = function(buffer) {
        switch(bufferNum) {
          case 1:
            soundBuffer1 = buffer;
            playBtn1.disabled = false;
          break;
          case 2:
                soundBuffer2 = buffer;
            playBtn2.disabled = false;
          break;
          case 3:
            soundBuffer3 = buffer;
            playBtn3.disabled = false;
          break;
        }
      }
      var errorCallback = function(e) {
      console.log(e);
      }
      context.decodeAudioData(request.response, successCallback, errorCallback);
    }

    request.send();
  }

  function playSound(buffer, bufferSourceNode) {
    bufferSourceNode.buffer = buffer;
    bufferSourceNode.connect(context.destination);
    bufferSourceNode.noteOn(0);
  }

  function stopSound(bufferSourceNode) {
    bufferSourceNode.noteOff(0);
  }
</script>

</body>

此外,是否有人知道在非循环声音播放完毕后可能触发的任何类型的事件?如果我可以将这些声音设置为非循环,并且一旦声音播放完毕,就可以使用这样的事件来切换它的标签,那就太酷了。我在规范中没有看到任何内容,但也许有更好的方法?

谢谢, 布拉德。

最佳答案

我知道这已经晚了一年,但我遇到了类似的问题,进行了一些快速搜索,结果如下:

在此页面中:http://updates.html5rocks.com/2012/01/Web-Audio-FAQ

然后引用问题:

  • “如何检查 AudioSourceNode 何时播放完毕?”
  • “我有一个 AudioBufferSourceNode,我刚刚用 noteOn() 播放了它,我想再次播放它,但是 noteOn() 什么也没做!救命!”

据我了解:从 createBufferSource() 创建的源只能播放一次。一旦你停止它,你必须创建一个新的。如果您想知道特定声音何时停止播放,则没有调度它的事件;所以你必须使用超时。

希望这对您有所帮助!

关于javascript - 网络音频 API : How Can I Re-start the Playback Of a Sound?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7862304/

有关javascript - 网络音频 API : How Can I Re-start the Playback Of a Sound?的更多相关文章

随机推荐