ネイティブモジュール非依存のマルチプラットフォームで音を鳴らすことのできるnode-moudleを作った

github.com

背景

Electronアプリで通知音を鳴らしたいが,音にまつわるモジュールがネイティブ絡んできて辛い. かつ,DOMのaudioを使いたくないという場面があった.

ネイティブが絡むと,node-gypを使ったりしてビルドが若干めんどくさくなるし, ちょっと音を鳴らしたいだけの時には重いモジュールが多いように感じた.

そこで,できるだけミニマムかつシンプルなモジュールを作成した.

利用方法

nodeのコードでは次のように使える.

var simplayer = require('simplayer');

var musicProcess = simplayer('/path/to/sound.mp3');

var musicProcess = simplayer('path/to/song.mp3', function (error) {
  if (error) throw error;
  console.log('end of song!');
});

require('simplayer') することで得られる関数を呼び出すとchild_processインスタンスが帰ってくる. なので,再生した音楽を監視したりするのであれば,child_processと同じように扱えば良い.

注意としては,windowsはwavフォーマットのみ対応 ということである. powershell というか, .NET の System.Media.SoundPlayer でmp3を再生する手段があれば教えていただきたい.

一応,cliも提供している.グローバルインストール後に,

simplayer /path/to/sample.mp3

すれば,実行できる.

実装

イデアは,openerを参考にした. openerは,各プラットフォームごとにファイルを開くコマンドをchild_processでspawnしているだけの シンプルなモジュールだ.macでいうopenや,windowsでいうcmdそものもが便利なのもあって非常に使いやすい.

openerと同じように各プラットフォームの音楽再生をするコマンドをよべば,音楽でも似たようなことが実現できる. ...と思っていたが,windowsには音楽を再生するコマンドはない.

そこで,このモジュールでは,powershellを使うことにした. powershellを通せば,.NETが提供している様々なものが使える. 今回は,System.Media.SoundPlayer を使って音を鳴らすことにした.

powershell.exe -NoExit (New-Object System.Media.SoundPlayer path\to\sound.wav).Play()

のようにすると,即席でwavファイルを再生できる.-NoExit オプションを付与している理由は, 音楽の再生が終了する前に,powershell.exeのプロセスが終了してしまうからだ.

他のプラットフォームは,macでは,afplay, linuxではaplay(ALSA) を用いるようにした.

作ってみて

30行程度の関数をモジュール化するのかどうか迷ったが,openerがものすごい利用されているのを見て, 公開しようと思った.