Web Audio APIとaxiosで音を鳴らすスニペット
Web Audio APIとaxios
『Web Audio APIとFetch APIで音を鳴らすスニペット』で紹介したコードだと,対象のオーディオファイルがローカルにある(=== URIがfile://
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.
これだとたとえば「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に統一しやすいのは最高.