🎵

Node.jsで音声を再生したい!

に公開

Node.jsで音声を再生したい

Node.jsで音声を再生したくてnpmやらredditやらでライブラリを探してみたんですが、
思った以上にライブラリが少なく、更にメンテナンスが5年以上前とかザラです。
音声再生って需要ないのかな?

ここでは、数時間調べて帰結した結果を残します。───長かった...

やりたいこと

  • いろんな形式の音声ファイルを再生する
  • 多重再生する
  • 任意のタイミングで音量を変えたりしたい

TL;DR

色々調べた結果、audio-decode + node-web-audio-api の組み合わせが良さそうです

しかもマルチプラットフォーム!(Windows, macOS, Linuxのx64,ARM64対応)
開発者に敬意を表しましょう

再生してみる

npm i audio-decode node-web-audio-api

audio-decodeで音声ファイルをデコードしてnode-web-audio-apiに渡します。[対応する形式]
まんまWeb Audio APIなので、ドキュメントが豊富です

import decode from 'audio-decode'
import { readFileSync } from 'fs'
import { AudioContext } from 'node-web-audio-api'
import { sleep } from 'yukari-util' //スリープできれば何でもいいです

const wav = await decode(readFileSync('./your_audio.wav'))
const ctx = new AudioContext();
const wavBuf = ctx.createBuffer(
    wav.numberOfChannels,
    wav.length,
    wav.sampleRate
);

for (let ch = 0; ch < wav.numberOfChannels; ch++) {
    wavBuf.getChannelData(ch).set(wav.getChannelData(ch));
}

const src = ctx.createBufferSource();
const gain = ctx.createGain();
src.buffer = wavBuf;
src.connect(gain).connect(ctx.destination);
src.start();
src.addEventListener("ended", ()=>{
    ctx.close(); //音声が終わったらプログラムを停止する
})

console.log("2秒後に3秒かけて音量を0.2にフェードします");
await sleep(2000);
gain.gain.setValueAtTime(gain.gain.value, ctx.currentTime); //これ入れないと変な感じになる
gain.gain.linearRampToValueAtTime(0.2, ctx.currentTime + 3);

他のライブラリ

play-sound

調べて真っ先に出てきたんですが、あまり自由なことはできなそう
完了時に音を鳴らすとかには最適かも!

@kmamal/sdl

音を鳴らすライブラリというよりは、sdlバインディングの中のオーディオ機能を使うみたいな感じです。
sdlに詳しくなくて、自分には難しすぎました(泣)

Discussion