🧊

mp3などの音源をxhrしてきて再生するには

過去に何回も書いてるはずやのに、どういうわけか毎度ハマる。
今度こそメモっておく。

音源を取得する

const xhr = new XMLHttpRequest();

xhr.open('GET', '/path/to/audio', true);
xhr.responseType = 'arraybuffer';

xhr.onload = () => {
  // ここで処理
  // xhr.response;
};
xhr.send();

バイナリを取得するのでそれ用の`responseType`が重要。
`blob`か`arraybuffer`かどっちかになるはずで、あとの処理でどういうことするかによる。

2017年やけど、jQueryの`ajax()`は、このへんの設定が上手くできないっぽいので注意。

ここで取得できない場合は、音源が見つけられてない。
パスにスペースがある時はちゃんとエスケープしないとダメとか。

// 要エスケープ!
const params = { path: 'risette/risette/risette\ -\ baby\ pink.mp3' }

HTMLAudioで再生する

// xhr.onload
const blob = new Blob([xhr.response], { type: 'audio/mpeg' });
// xhr.responseType = 'blob'; の場合は、そのまま使える
// const blob = xhr.response;
const objectUrl = URL.createObjectURL(blob);

const audio = new Audio();
audio.autoplay = true;
audio.onload = () => {
  URL.revokeObjectURL(objectUrl);
};

audio.src = objectUrl;

わかりやすい。
ちなみにこのBlobなURLで`window.open()`とかすると、そのままダウンロードできるはず。

WebAudioで再生する

// xhr.onload
const ctx = new AudioContext();
const source = ctx.createBufferSource();
ctx.decodeAudioData(xhr.response).then(buffer => {
  source.buffer = buffer;

  source.connect(ctx.destination);
  source.start(ctx.currentTime);
});

後は煮るなり焼くなり。