2019/03/14

rubyでサウンドファイル(mp3)を再生する

こんばんは、宇賀神です。
先日gemを作って記事にしたのですが、その時に詰まった事をせっかくなのでまた記事のネタにしようと思います。

何で詰まったんですか

pomodorokun という、25分と5分を延々とカウントダウンするgemを作ったのですが、ラスト5秒くらいで「パ、パ、パ、パーン」て感じの時報っぽい音を流したくて。

調べてみてもrubyでサウンド流す系の事例があまり見かけず、まあそりゃ確かにJavaScriptでやるような内容だし 頑張ってやってみた次第です。

やった事

「rubyで鳴らせないなら、shellで鳴らせばいいじゃない」ということで、 afplay コマンドを使うことにしました。コンソールで試したところ、以下のコマンドでmp3ファイル(countdown.mp3)を再生することが出来ました。この時点でOSX以外への対応が不可能になってますが一旦気にしない。

$ afplay countdown.mp3

後はこれを %w なり使ってruby側から実行すればいいと思ったのですが、どうやらrubyのプロセスから単にコマンドを実行するだけではmp3ファイルは開けないらしく、解決するのに結構時間を使ってしまいました。

救世主Open3

上記の問題はOpen3を使うことで解決しました。
リファレンスによるとOpen3とは、

プログラムを実行し、そのプロセスの標準入力・標準出力・ 標準エラー出力にパイプをつなぎます。

とのことです。正直言うと完全には理解できてないです。
なんとなく感覚としては、プログラムから実行環境の標準入/出力を操作できて、その結果を受け取れる、というような感じで捉えてます。← 優しい読者の方、このあたりマサカリあればください。
最終的なコードとしては以下のようになりました。

Open3.popen3 ("afplay #{File.expand_path('../../sound/countdown.mp3', __FILE__)}")

Open3.capture3() も試してみたのですが、サウンドの再生中に肝心のカウントダウン自体が止まってしまったので、別プロセスで動かせる Open3.popen3() を使いました。

まとめ

今回の技術的な部分としてはこんな感じです。
今後仕事で使うかと言うと微妙なところですが 普段触らないところに触ったので楽しかったです。
他にもimportメソッドに渡すパスがどこから始まるとかそれなりに学びはあったので、総合的にまあ良かったかなと思います。また何かあれば更新します〜