He escrito un script básico en Chrome que usa el nuevo API de audio web para cargar 3 archivos de sonido (a través de XMLHTTPRequest) y reproducir cada uno de ellos de forma individual. He proporcionado un botón por separado para cada sonido que permite al usuario iniciar y detener cada sonido.Web Audio API: ¿cómo puedo reiniciar la reproducción de un sonido?
La secuencia de comandos carga inmediatamente los tres archivos de sonido y, cuando termine, desactiva los botones de reproducción para que el usuario solo pueda tocar cuando los sonidos estén listos. Además, los sonidos son en bucle, por lo que la etiqueta de cada botón cambia entre "Reproducir" y "Detener" cuando se hace clic en el botón.
Todo esto funciona muy bien ... Cuando hace clic en el botón Reproducir, escucha el sonido de bucle y cuando pulsa Detener, el sonido se detiene. Sin embargo, cuando intente volver a reproducir el mismo sonido por segunda vez, el sonido no comenzará a reproducirse nuevamente. Cada vez que hace clic en el botón Reproducir/Detener, se llama a la función playSound() o stopSound() correspondiente y se pasan los parámetros apropiados, pero por alguna razón no puedo hacer que los sonidos suenen una segunda vez. ¿Estoy haciendo algo mal?
Aquí está mi código:
<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>
Además, es alguien al tanto de cualquier tipo de evento que podría disparar una vez un sonido no se realiza un bucle de jugar? Sería fantástico si pudiera configurar estos sonidos para que no se repitiesen y, tan pronto como se reproduzca un sonido, usa un evento así para alternar la etiqueta. No veo nada en la especificación, pero tal vez hay una mejor manera?
Gracias, Brad.
¿Alguna vez solucionó esto? Estoy teniendo un problema similar. – mdm
¡Estoy teniendo exactamente el mismo problema aquí! : S alguna idea? – asheinfeld