Cloning a sound source without having to reload it

I am creating a piano in a browser using javascript. In order for me to play the same key several times at the same time, instead of just playing the Audio object, I cloned it and played the clone, otherwise I would have to wait for the sound to finish or restart it, you want.

I did something like this:

var audioSrc = new Audio('path/'); window.onkeypress = function(event) { var currentAudioSrc = audioSrc.cloneNode(); currentAudioSrc.play(); } 

The problem is that I checked the chrome inspector, and I noticed that every time I clone an object, the browser loads it again

enter image description here

I checked some people who wanted to achieve such things, and noticed that most of them have the same problems as me, they reload the file. The only example I found that can play the same sound source several times at the same time is SoundJs http://www.createjs.com/SoundJS

I tried to check the source, but could not understand how it was done. Any idea?


+5
source share
2 answers

Using webAudioAPI you can do something like this:

  • Upload the file once through XMLHttpRequest.
  • Add buffer response
  • Create a new buffer source and play it every time you call
  • Return 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.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"/> 
+3
source

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 pay attention to MDN :

Depth is an optional argument. If this parameter is omitted, the method acts as if the depth value were true without using deep cloning, since by default. To create a shallow clone, you must set the depth to false.

This behavior has been changed in the latest specification, and if omitted, the method will act as if the depth value were false. Although it is still optional, you should always provide a deep argument for both backward and forward compatibility.

So try using deep = false to prevent the resource from loading:

 var audioSrc = new Audio('path/'); window.onkeypress = function(event) { var currentAudioSrc = audioSrc.cloneNode(false); currentAudioSrc.play(); } 
0
source

All Articles