Cloning audio source without having to download it again

前端 未结 3 384
野趣味
野趣味 2020-12-06 19:02

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

3条回答
  •  粉色の甜心
    2020-12-06 19:40

    With 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.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};
    
    

提交回复
热议问题