gpt4 book ai didi

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

转载 作者:数据小太阳 更新时间:2023-10-29 05:06:29 29 4
gpt4 key购买 nike

我在 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/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com