我正在使用javascript在浏览器中创建钢琴。为了让我同时多次播放相同的键,而不是只播放Audio对象,我克隆它并播放克隆,否则我必须等待音频完成或重新启动它,我不知道我想要。
我做过这样的事情:
var audioSrc = new Audio('path/');
window.onkeypress = function(event) {
var currentAudioSrc = audioSrc.cloneNode();
currentAudioSrc.play();
}
问题是,我正在检查chrome的检查员,我注意到每次克隆对象时,浏览器都会再次下载
我检查了一些想要实现类似功能的人,并注意到他们中的大多数都遇到了与我相同的问题,他们重新下载了文件。我发现可以同时多次播放相同音频源的唯一示例是SoundJs http://www.createjs.com/SoundJS
我尝试检查源可能但无法弄清楚它是如何完成的。有什么想法吗?
答案 0 :(得分:3)
使用webAudioAPI你可以做类似的事情:
window.AudioContext = window.AudioContext||window.webkitAudioContext;
if(!window.AudioContext)
yourFirstImplementation();
else{
var buffer,
ctx = new AudioContext(),
gainNode = ctx.createGain();
gainNode.connect(ctx.destination);
var vol = document.querySelector('input');
vol.value = gainNode.gain.value;
vol.addEventListener('change', function(){
gainNode.gain.value = this.value;
}, false);
function createBuffer(){
ctx.decodeAudioData(this.response, function(b) {
buffer = b;
}, function(e){console.warn(e)});
var button = document.querySelector('button');
button.addEventListener('click', function(){playSound(buffer)});
button.className = 'ready';
}
var file = 'https://dl.dropboxusercontent.com/s/agepbh2agnduknz/camera.mp3',
xhr = new XMLHttpRequest();
xhr.onload = createBuffer;
xhr.open('GET', file, true);
xhr.responseType = 'arraybuffer';
xhr.send();
function playSound(buf){
var source = ctx.createBufferSource();
source.buffer = buf;
source.connect(gainNode);
source.onended = function(){if(this.stop)this.stop(); if(this.disconnect)this.disconnect();}
source.start(0);
}
}
function yourFirstImplementation(){
alert('webAudioAPI is not supported by your browser');
}

button{opacity: .2;}
button.ready{opacity: 1};

<button>play</button>
<input type="range" max="5" step=".01" title="volume"/>
&#13;
答案 1 :(得分:0)
cloneNode
有一个布尔参数:
var dupNode = node.cloneNode(deep);
/*
node
The node to be cloned.
dupNode
The new node that will be a clone of node
deep(Optional)
true if the children of the node should also be cloned, or false to clone only the specified node.
*/
另请注意MDN:
Deep是一个可选参数。如果省略,则该方法就像是一样 深度的价值是真实的,默认使用深度克隆作为 默认行为。要创建浅层克隆,必须将deep设置为 假的。
此行为已在最新规范中更改,如果省略,则 方法将表现为deep的值为false。虽然它还在 可选的,你应该总是提供深度参数 向后兼容性
因此,请尝试使用deep = false
来阻止下载资源:
var audioSrc = new Audio('path/');
window.onkeypress = function(event) {
var currentAudioSrc = audioSrc.cloneNode(false);
currentAudioSrc.play();
}
答案 2 :(得分:0)
手动加载它,并将Blob URL个二进制数据分配给src
:
<audio id="audioEl" data-src="audio.mp3"></audio>
var xhr = new XMLHttpRequest();
xhr.open('GET', audioEl.dataset.src);
xhr.responseType = 'blob';
xhr.onload = () => {
audioEl.src = URL.createObjectURL(xhr.response);
};
xhr.send();
这样,当您克隆它时,只会克隆对内存中二进制数据的引用。