【发布时间】:2013-09-13 01:53:48
【问题描述】:
我在 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>
另外,是否有人知道在播放完非循环声音后可能触发的任何类型的事件?如果我可以将这些声音设置为非循环播放,并且一旦播放完声音,使用这样的事件来切换它的标签,那就太酷了。我在规范中看不到任何内容,但也许有更好的方法?
谢谢, 布拉德。
【问题讨论】:
-
你解决过这个问题吗?我也有类似的问题。
-
我在这里遇到了完全相同的问题! :S 有什么想法吗?
标签: javascript google-chrome html5-audio