Web音频API获取<audio>元素的AudioBuffer

dav*_*ler 5 javascript audio html5-audio web-audio-api

我有一个音频元素

var audioSrc = 'https://mfbx9da4.github.io/assets/audio/dope-drum-loop_C_major.wav'
var audio = document.createElement('audio')
audio.src = audioSrc
Run Code Online (Sandbox Code Playgroud)

我需要AudioBuffer 进行节拍检测,因此在加载音频时尝试访问缓冲区:

audio.oncanplaythrough = () => {
  console.info('loaded');
  var source = context.createMediaElementSource(audio);
  source.connect(context.destination);
  console.info('source.buffer', source.buffer);
  source.start()
}
Run Code Online (Sandbox Code Playgroud)

但是,以上代码片段日志

> loaded
> source.buffer undefined
Run Code Online (Sandbox Code Playgroud)

dav*_*ler 7

似乎最好的方法是避免<audio>标签并通过XHR加载音频:

var context = new (window.AudioContext || window.webkitAudioContext)();
var audioSrc = 'https://mfbx9da4.github.io/assets/audio/dope-drum-loop_C_major.wav'

fetch(audioSrc, onSuccess)

function fetch (url, resolve) {
  var request = new XMLHttpRequest();
  request.open('GET', url, true);
  request.responseType = 'arraybuffer';
  request.onload = function () { resolve(request) }
  request.send()
}

function onSuccess (request) {
  var audioData = request.response;
  context.decodeAudioData(audioData, onBuffer, onDecodeBufferError)
}

function onBuffer (buffer) {
  var source = context.createBufferSource();
  console.info('Got the buffer', buffer);
  source.buffer = buffer;
  source.connect(context.destination);
  source.loop = true;
  source.start()
}

function onDecodeBufferError (e) {
  console.log('Error decoding buffer: ' + e.message);
  console.log(e);
}
Run Code Online (Sandbox Code Playgroud)

  • 不幸的是,这在2018年仍然是正确的。WebAudio API规范试图建议为此使用`audio`元素,但是除了基本播放之外,您不能执行任何其他操作:没有预渲染的音频可视化,无法访问音频数据,什么都没有。 (3认同)