音声ファイルを動画ファイルに変換するだけのWebサービスとCLIツールを作りました
はじめに
TwitterやYoutubeに音声のみを投稿したいニーズがそこそこあると思うのですが、音声ファイルを静止画付きの動画ファイルに簡単に変換できるサービスがなさそうだったので作ってみました。
(後から知りましたが、MP3TUBEというサービスがありました :sweat_smile: でもこのサービス、デカデカと「MP3TUBE」と書かれた画像で動画ファイル化されてしまうっぽいので、今回作ったものはもう少し柔軟で便利なものになってると思います)
作ったもの
Webサービス
こんな感じの超シンプルなものです。音声ファイルを入力して変換ボタンを押せばとりあえず真っ黒なmp4ファイルになって降ってきます。
「詳細設定」を開くと、
- 出力動画のファイル形式
- 出力動画のフレームレート
- 出力動画に使う画像ファイル
- 既存の画像ファイルを使う
- 解像度と色を指定して画像を生成させる
を設定することもできます。
主にTwitterへの投稿を想定しているため、サーバーの負荷のことも考えてとりあえず現状は再生時間が140秒までの音声ファイルにのみ対応しています。
CLIツール
ほぼ同じソースコードを流用して、エンジニア向け(というか自分用)にCLI版も作りました。
こちらは140秒までという制限はないので、長めの音声ファイルをYoutubeとかに投稿したい場合にはこっちを使ってもらえればいいかなと思います。
使った技術
音声ファイルを動画ファイルに変換する処理自体は、定番のffmpegを使っています。
PHPerなのでPHPからffmpegを使うベストプラクティスをちょろっと調べてみたところ、どうやら今時はPHP-FFMpegというライブラリを使うのが一般的っぽいです。
が、少し触ってみた感じ、やりたいことに対してAPIが足りてなさそうだったので、今回は諦めてsymfony/processでラップして自前でシステムコールする感じの実装にしました。
画像の生成はImageMagickです。
Webサービス
docker-composeでnginx+php-fpmでサービスしてます。docker-composeもnginxも今回初めて使ったので色々ハマりました。
とりあえず現状の内容はこんな感じです。(色々間違ったやり方もあると思うので、気になる点ご指摘いただけると嬉しいです)
PHPはフレームワークにSilexを使っています。
Silex-Skeletonにいくつか自分用に味付けしたもの(最初からBootstrap+fontawesome+select2でUIが書けるようにしたり、フォームとか翻訳とかがささっと導入できるようにしたりしたもの)を使ったので、大枠は割とすぐ書けました。
Silexのルーティングに合うようにnginxのlocation設定を書くのとか最初どうすればいいのか全然分からなくて大変でした。
CLIツール
上記Web版のソースコードをほぼコピペして、symfony/consoleでコマンド化しただけです。
実はWeb版よりもこっちを先に作っていて、最初はシェルスクリプトで書いていたんですが、複雑なオプションを付けたくなったあたりで嫌気がさしてsymfony/consoleに逃げましたw
symfony/consoleマジ便利っす。
ソースコード
ソースコードは以下で公開しています。まだリファクタしてなくてテストもない悲しいコードですが、何かの参考にでもなれば幸いです。
おわりに
これを読んでる人に需要があるか謎ですが、よければ使ってやってください😃
Discussion