tkhrsskの日記

技術ネタなど

node.jsで音声再生

駄文です

node.jsで音声再生する方法を模索

Mac環境だと play-sound 使って、おそらくaplayerが実行できていたソースコードWindowsで実行したら再生できなくなっていた。

エラー情報も 1 とだけ吐き出していて意味不明でしたが、 play-sound は音声プレイヤーをコマンドラインを読み出していだけのようで、 Windowsだと明示的にインストールが必要そうでした。

ChatGPTに相談しながら解決を模索していました。

まず試したのはmplayerのインストール。 PATHを通して、コマンドラインでも再生できることを確認し、一応明示的にplay-soundにもプレイヤーを指定。

const playSound = require('play-sound');
const opts = {
  players: ['mplayer']
};
const play = playSound(opts);

うまく再生できるときもあるが、呼び出し方によって無限ループで再生するようになった。 キュー使った処理で呼び出しているところが影響しているのか?とかよくわからず。 playerOptions を指定するも反映がされていなさそう。

child_process の execSync で直接コマンド実行するようにしても、現象を解消されず。 違う方法を模索。

次にmpg123をインストールしてみたが、こちらは音がでない現象発生し、断念。

次に試したのは、ライブラリを変えて、audioplayerライブラリを使用する方法。 ところが、実行時にエラー。どうもブラウザ上での実行限定っぽい内容。断念。

次は、ライブラリでspeakerとnode-wavを使用する方法。 するとspeakerのインストール時にエラーが発生。 Visual StudioC++のワークロードが必要ということで、わざわざこのために10G超えの環境をインストール。 再生できるようになったが、ノイズが入ることがあり断念。

const fs = require('fs');
const wav = require('wav');
const Speaker = require('speaker');

const file = fs.createReadStream('file.wav');
const reader = new wav.Reader();

// WAVファイルのフォーマットが解析されたら、そのフォーマットでスピーカーを設定
reader.on('format', function (format) {
  this.pipe(new Speaker(format));
});

file.pipe(reader);

また play-soundで経由で実行できるプレイヤーを調査。Windows Media Playerも使えるっぽい情報あったが、コマンドラインでうまく動かず。

次にVLCを利用。再生できるが、GUIが起動してしまう。オプション指定が必要。 下記のように設定してみるが、前回の時と同じように反映されず。

const playSound = require('play-sound');
const opts = {
  players: ['vlc'],
  playerOptions: {
    vlc: ['-I', 'dummy', '--verbose', '2', '--play-and-exit'] // VLCに渡すオプション(必要に応じて変更)
  }
};
const play = playSound(opts);

結局、execSync利用にする。

const { exec } = require('child_process');

execSync('vlc.exe -I dummy --play-and-exit ' + filename, (error, stdout, stderr) => {
  if (error) {
    console.error(`exec error: ${error}`);
    return;
  }
  console.log(`stdout: ${stdout}`);
  console.error(`stderr: ${stderr}`);
});

一旦、この方法で落ち着いた。 Macと環境差分でてしまっているので、ラッパー化しておきたいと思った。