Я написал базовый скрипт в Chrome, который использует новый Web Audio Api для загрузки 3 звуковых файлов (через XMLHTTPRequest) и воспроизведения каждого из них по отдельности. Я предоставил отдельную кнопку для каждого звука, которая позволяет пользователю запускать и останавливать каждый звук.
Сценарий немедленно загружает все три звуковых файла и, когда все готово, отменяет приглушение кнопок воспроизведения, чтобы пользователь мог нажать кнопку воспроизведения, только когда звук будет готов. Кроме того, звуки зацикливаются, поэтому при нажатии кнопки метка на каждой кнопке меняется с «Play» на «Stop».
Все это прекрасно работает ... Когда вы нажимаете кнопку Play, вы слышите зацикленный звук, а когда вы нажимаете кнопку Stop, звук останавливается. Однако, если вы попытаетесь повторно воспроизвести один и тот же звук во второй раз, звук не начнет воспроизводиться снова. Каждый раз, когда вы нажимаете кнопку Play / Stop, вызывается соответствующая функция 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>
Кроме того, кто-нибудь знает о каком-либо событии, которое может произойти, когда закончится воспроизведение нецикличного звука? Было бы здорово, если бы я мог установить эти звуки нецикличными, и как только звук закончится, используйте такое событие, чтобы переключить его метку. Я ничего не вижу в спецификации, но, может быть, есть лучший способ?
Спасибо,
Бред.