admin管理员组文章数量:1435859
I'm creating a piano in the browser using 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
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
I tried checking the source could but couldn't figure out how it was done. Any idea?
I'm creating a piano in the browser using 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
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./SoundJS
I tried checking the source could but couldn't figure out how it was done. Any idea?
Share Improve this question edited May 25, 2015 at 8:09 Alex 11.3k13 gold badges52 silver badges64 bronze badges asked May 25, 2015 at 7:59 Daniel OrtizDaniel Ortiz 9212 gold badges7 silver badges14 bronze badges 1
- 1 Yeah I can see how that would be difficult to track down if you are unfamiliar with the SoundJS architecture. WebAudioLoader._sendComplete decodes the loaded file into an AudioBuffer that is then passed as the _result, which is handled in AbstractPlugin._handlePreloadComplete by storing it in the _audioSources hash (WebAudioPlugin extends AbstractPlugin). This stored AudioBuffer is then passed to each new WebAudioSoundInstance and used for creating audio nodes. Its the same idea as the accepted answer, store off the audio buffer and use it to create new audio nodes. – OJay Commented May 26, 2015 at 16:13
3 Answers
Reset to default 4With the webAudioAPI you could do something like that :
- Download once the file via XMLHttpRequest.
- Append the response to a buffer
- Create a new bufferSource and play it on each call
- Fallback to your first implementation if webAudioAPI is not supported (IE)
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./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:
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.
*/
Also note from MDN:
Deep is an optional argument. If omitted, the method acts as if the value of deep was true, defaulting to using deep cloning as the default behavior. To create a shallow clone, deep must be set to 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. Though It's still optional, you should always provide the deep argument both for backward and forward patibility
So, try to use deep = false
to prevent download resource:
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
:
<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.
本文标签: javascriptCloning audio source without having to download it againStack Overflow
版权声明:本文标题:javascript - Cloning audio source without having to download it again - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745670620a2669545.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论