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

Web audio API get AudioBuffer of <audio> element

我有一个音频元素

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

我需要 AudioBuffer 要做 beat detection 所以我尝试在加载音频时访问缓冲区:

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

但是,上面的代码片段记录了

> loaded
> source.buffer undefined

似乎最好的方法是避免使用 <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);
}