克隆音频源而无需再次下载

Dan*_*tiz 5 javascript audio html5

我正在使用javascript在浏览器中创建钢琴.为了让我同时多次播放相同的键,而不是只播放Audio对象,我克隆它并播放克隆,否则我必须等待音频完成或重新启动它,我不知道我想要.

我做过这样的事情:

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

问题是,我正在检查chrome的检查器,我注意到每次克隆对象时,浏览器都会再次下载它

在此输入图像描述

我检查了一些想要实现类似功能的人,并注意到他们中的大多数都遇到了同样的问题,他们重新下载了文件.我发现可以同时多次播放相同音频源的唯一示例是SoundJs http://www.createjs.com/SoundJS

我尝试检查源可能但无法弄清楚它是如何完成的.任何的想法?


Kai*_*ido 4

使用 webAudioAPI 你可以做类似的事情:

  • 通过 XMLHttpRequest 下载一次文件。
  • 将响应附加到缓冲区
  • 创建一个新的 bufferSource 并在每次调用时播放它
  • 如果不支持 webAudioAPI (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');
  }
Run Code Online (Sandbox Code Playgroud)
button{opacity: .2;}
button.ready{opacity: 1};
Run Code Online (Sandbox Code Playgroud)
<button>play</button>
<input type="range" max="5" step=".01" title="volume"/>
Run Code Online (Sandbox Code Playgroud)

  • 我无法停止播放 :D (3认同)