Web audio API: how can I resume audio playback?

I wrote a basic script in Chrome that uses the new Web Audio Api to download 3 audio files (via XMLHTTPRequest) and play each one individually. I have provided a separate button for each sound, which allows the user to start and stop each sound.

The script immediately downloads all three sound files and, when this is done, smoothes the play buttons so that the user can only press play as soon as the sound is ready. In addition, the sounds are looped, so "Play" and "Stop" are changed on each button when the button is pressed.

All this works great ... When you press the Play button, you hear the sound of the loop and when you press Stop, the sound stops. However, when you try to play the same sound a second time, the sound will not start playing again. Each time you press the Play / Stop button, the corresponding playSound () or stopSound () functions are called and the corresponding parameters are passed, but for some reason I just can’t play the sounds a second time. Am I doing something wrong?

Here is my code:

<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> 

Also, does anyone know of any event that can fire when sound is played without looping? It would be great if I could turn off these sounds, and as soon as the sound is played, use such an event to switch it. I don’t see anything in the specification, but maybe there is a better way?

Thanks, Brad.

+6
source share
2 answers

I know this is a year later, but I had a similar problem, I did a few quick searches, and here is what I found:

On this page: http://updates.html5rocks.com/2012/01/Web-Audio-FAQ

Then refer to the questions:

  • "How can I check if an AudioSourceNode has finished playing?"
  • "I have an AudioBufferSourceNode that I just played using noteOn (), and I want to play it again, but noteOn () does nothing! Help!"

From what I understand: a source created from createBufferSource () can only be played once. Once you stop it, you must create a new one. If you want to know when a sound stops playing, there is no event that sends it; therefore you must use a timeout.

Hope this helps!

+6
source

Just learn the web audio API. At first glance, I would say this because you have to create a BufferSource every time you play a sound, and it seems that you only do it the first time. see examples here: http://www.html5rocks.com/en/tutorials/webaudio/intro/

+5
source

Source: https://habr.com/ru/post/899878/


All Articles