Augmented Usamimi

it { is_expected.to be_blog.written_by(izumin5210) }

Web Audio APIとaxiosで音を鳴らすスニペット

Web Audio APIとaxios

Web Audio APIとFetch APIで音を鳴らすスニペット』で紹介したコードだと,対象のオーディオファイルがローカルにある(=== URIfile:// protocol)であるときにエラーを吐く.

For now, unfortunate as it is, file and ftp URLs are left as an exercise for the reader.

When in doubt, return a network error.

4.2 Basic fetch - Fetch Standard

これだとたとえば「Electronでパッケージに同梱したmp3を鳴らす」みたいなシチュエーションで困る.そこでFetch APIの代替としてPromiseベースのHTTPクライアントライブラリであるaxiosを利用する.前提知識・注意点・使い方等は元記事に同じ.

import axios from "axios";

export default class SoundPlayer {
  static AudioContext = window.AudioContext || window.webkitAudioContext;

  uri: string;
  context: AudioContext;
  buffer: AudioBuffer;

  constructor(uri: string) {
    this.uri = uri;
    this.context = new SoundPlayer.AudioContext();
  }

  fetch(): Promise<AudioBuffer> {
    return axios(this.uri, { responseType: "arraybuffer" })
      .then(({ data }) => this.context.decodeAudioData(data))
      .then(buf => (this.buffer = buf));
  }

  play() {
    const source = this.context.createBufferSource();
    source.buffer = this.buffer;
    source.connect(this.context.destination);
    source.start(0);
  }
}

diffは先頭importと以下のメソッドのみ.{ resoponseType: "arraybuffer" }を渡しとけばOK.

   fetch(): Promise<AudioBuffer> {
-    return fetch(this.uri)
-      .then(res => res.arrayBuffer())
-      .then(data => this.context.decodeAudioData(data))
+    return axios(this.uri, { responseType: "arraybuffer" })
+      .then(({ data }) => this.context.decodeAudioData(data))
       .then(buf => (this.buffer = buf));
   }

やっぱりI/FがPromiseに統一しやすいのは最高.

References