HTML5JS在同一时间多次播放相同的声音
HTML5 JS play same sound multiple times at the same time
我正在创建一个非常基本的HTML5游戏,我遇到了一堵小墙,基本上我有一个数组,这个数组由一个声音文件填充(这是一个数组所以如果需要,我可以分配更多的声音)
this.Sounds["L_Explosion1"] = new Audio("Assets/Sounds/Explosion_1.wav");
this.Sounds["L_Explosion1"].volume = 1;
this.Sounds["L_Explosion1"].load();
当玩家按下空格键时,我想播放声音,所以我运行这个代码
this.Sounds["L_Explosion1"].play();
然而,如果我在播放声音之前再次按下空格键,它将不会播放,我试图做的是多次播放相同的声音,如果相同的声音尚未完成,我将如何实现这一点?
为了同时播放多个声音实例,您需要创建该Audio
元素的新副本。一种方法是使用.cloneNode()
方法,每次按下空格键时播放克隆的音频。
this.Sounds["L_Explosion1"].cloneNode(true).play();
HTML5音频元素有很多局限性,它不太适合像您描述的那样复杂的音频用例,这似乎是一个游戏。
相反,请考虑使用WebAudio API。你必须:
-
使用
XMLHttpRequest
将音频文件加载到缓冲区中 -
将该缓冲区分配给
AudioBufferSourceNode
实例。 -
将该节点连接到适当的目的地或中间节点(例如
GainNode
)。 -
如果您还需要停止声音,则需要跟踪已创建但尚未完成播放的每个源节点,这可以通过收听源节点的
onended
来完成。
这里有一个类,它封装了从URL加载声音并根据需要多次播放/停止声音的逻辑,跟踪所有当前播放的源并根据需要进行清理:
window.AudioContext = window.AudioContext || window.webkitAudioContext;
const context = new AudioContext();
export class Sound {
url = '';
buffer = null;
sources = [];
constructor(url) {
this.url = url;
}
load() {
if (!this.url) return Promise.reject(new Error('Missing or invalid URL: ', this.url));
if (this.buffer) return Promise.resolve(this.buffer);
return new Promise((resolve, reject) => {
const request = new XMLHttpRequest();
request.open('GET', this.url, true);
request.responseType = 'arraybuffer';
// Decode asynchronously:
request.onload = () => {
context.decodeAudioData(request.response, (buffer) => {
if (!buffer) {
console.log(`Sound decoding error: ${ this.url }`);
reject(new Error(`Sound decoding error: ${ this.url }`));
return;
}
this.buffer = buffer;
resolve(buffer);
});
};
request.onerror = (err) => {
console.log('Sound XMLHttpRequest error:', err);
reject(err);
};
request.send();
});
}
play(volume = 1, time = 0) {
if (!this.buffer) return;
// Create a new sound source and assign it the loaded sound's buffer:
const source = context.createBufferSource();
source.buffer = this.buffer;
// Keep track of all sources created, and stop tracking them once they finish playing:
const insertedAt = this.sources.push(source) - 1;
source.onended = () => {
source.stop(0);
this.sources.splice(insertedAt, 1);
};
// Create a gain node with the desired volume:
const gainNode = context.createGain();
gainNode.gain.value = volume;
// Connect nodes:
source.connect(gainNode).connect(context.destination);
// Start playing at the desired time:
source.start(time);
}
stop() {
// Stop any sources still playing:
this.sources.forEach((source) => {
source.stop(0);
});
this.sources = [];
}
}
然后你可以做这样的事情:
const soundOne = new Sound('./sounds/sound-one.mp3')
const soundTwo = new Sound('./sounds/sound-two.mp3')
Promises.all([
soundOne.load(),
soundTwo.load(),
]).then(() => {
buttonOne.onclick = () => soundOne.play();
buttonTwo.onclick = () => soundOne.play();
})
相关文章:
- 如何减少在移动网络应用程序上播放声音的延迟
- 使用JS和JQuery播放和停止声音
- 你能用sound.js在播放声音文件后5秒执行一个动作吗
- 可以'无法播放声音
- 声音不会在一页上播放,但在另一页上会播放
- 如何在javascript中一个声音文件接一个声音地播放
- 在Wordpress网站的图像点击上播放随机声音
- 使用javascript播放声音
- 点击播放声音
- 如何检测网页中的更改并使用Javascript播放声音
- 在网站上播放多个循环声音
- 在悬停图像上播放声音,悬停在图像上时停止
- 无法使用JavaScript在iPhone上播放声音,但可以在Android上播放
- 如何停止YouTube声音播放
- 单击按钮时播放音频,并在声音播放完成后重定向
- 现场网站上没有声音播放
- 将“结束”事件绑定到没有 ID 或类的声音播放
- 如何播放/暂停声音和声音播放从声音的开始
- JQuery声音播放和停止
- 暂停网络音频 API 声音播放