[英]Cloning audio source without having to download it again
I'm creating a piano in the browser using javascript.我正在使用 javascript 在浏览器中创建钢琴。 In order for me to play the same key multiple times simultaneously, instead of just playing the Audio object, I clone it and play the clone, otherwise I'd have to wait for the audio to finish or to restart it, which I don't want.
为了让我同时多次播放相同的键,而不是仅仅播放音频对象,我克隆它并播放克隆,否则我必须等待音频完成或重新启动它,我不这样做'不想。
I've done something like this:我做过这样的事情:
var audioSrc = new Audio('path/');
window.onkeypress = function(event) {
var currentAudioSrc = audioSrc.cloneNode();
currentAudioSrc.play();
}
The problem is, I was checking chrome's inspector, and I noticed that every time I clone the object, the browser download it again问题是,我正在检查 chrome 的检查器,我注意到每次克隆对象时,浏览器都会再次下载它
I checked some people who wanted to achieve similar things, and noticed that most of them have the same problem that I do, they redownload the file.我查了一些想实现类似事情的人,发现他们中的大多数人都有和我一样的问题,他们重新下载了文件。 The only example I found that can play the same audio source multiple times simultaneously is SoundJs http://www.createjs.com/SoundJS
我发现可以同时多次播放相同音频源的唯一示例是 SoundJs http://www.createjs.com/SoundJS
I tried checking the source could but couldn't figure out how it was done.我尝试检查源可以但无法弄清楚它是如何完成的。 Any idea?
任何的想法?
With the webAudioAPI you could do something like that :使用 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"/>
cloneNode
have one boolean argument: 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.
*/
Deep is an optional argument.
Deep 是一个可选参数。 If omitted, the method acts as if the value of deep was true, defaulting to using deep cloning as the default behavior.
如果省略,该方法就好像 deep 的值为 true,默认使用深度克隆作为默认行为。 To create a shallow clone, deep must be set to false.
要创建浅克隆,必须将 deep 设置为 false。
This behavior has been changed in the latest spec, and if omitted, the method will act as if the value of deep was false.
此行为已在最新规范中更改,如果省略,该方法将表现为 deep 的值为 false。 Though It's still optional, you should always provide the deep argument both for backward and forward compatibility
尽管它仍然是可选的,但您应该始终为向后和向前兼容性提供深层参数
So, try to use deep = false
to prevent download resource:所以,尝试使用
deep = false
来防止下载资源:
var audioSrc = new Audio('path/');
window.onkeypress = function(event) {
var currentAudioSrc = audioSrc.cloneNode(false);
currentAudioSrc.play();
}
Load it manually and assign a Blob URL of the binary data to src
:手动加载它并将二进制数据的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();
This way when you clone it, only the reference to the in-memory binary data is cloned.这样,当您克隆它时,只会克隆对内存中二进制数据的引用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.