ffmpegとPythonで音楽動画を自動生成する構成と落とし穴

ffmpegとPythonで音楽動画を自動生成する構成と落とし穴

静止画1枚と音声ファイルから、ffmpegで数時間の長尺動画を自動生成しています。その構成と、実際に運用して分かった「サーバーが巻き添えで遅くなる」「ディスクが埋まる」という2つの落とし穴、そして43万通りの組み合わせをどう管理しているかをまとめます。

やっていることはシンプルです

やっている中身は驚くほど単純で、静止画1枚と音声ファイルをffmpegに渡して、数時間ぶんの動画ファイルを書き出すだけです。映像は動きません。音楽が流れているあいだ、同じ画像がずっと表示されているタイプの動画です。

単純だからこそ自動化しやすく、Python側でやることは「どの曲に、どのタイトルで、どの画像を組み合わせるか」を決めて、ffmpegを呼び、後片付けをする、という流れになります。難しいのは動画を作ることではなく、作り続けたときに周りを壊さないことでした。

組み合わせは434,700通りある

素材は3種類あります。タイトルのパターン、曲、背景画像です。

素材の種類ごとの数
素材の種類ごとの数
実測

434,700通り
タイトル25種 × 曲378本 × 画像46枚の総組み合わせ数

数字だけ見ると無尽蔵に思えますが、放っておくと同じ組み合わせを何度も引きます。ランダムに選ぶ実装のままだと、体感でぶつかります。そこで使用済みの組み合わせを記録して、次回以降はそれを避けるようにしました。生成のたびに「この曲・このタイトル・この画像」の組を記録し、選定時に既出を除外します。

ポイント

組み合わせ総数が多いことと、重複しないことは別問題です。「使った組み合わせを覚えておく」という一手間を入れるかどうかで、出てくるものの見え方が変わります。

落とし穴1:書き出し中にWebサイトが遅くなる

これが最初にぶつかった問題です。動画生成はCPUを大きく使います。同じサーバーでWebサイトを動かしていると、書き出し中にサイトのレスポンスが目に見えて遅くなりました。

対策として、ffmpegの実行を次の2つでくるんでいます。

  • taskset で使用するCPUコアを2つに限定する
  • nice でプロセスの優先度を下げる
うまくいったこと

コアを絞って優先度を下げたことで、書き出し中でもWebサイト側が巻き添えになる状況は避けられるようになりました。動画生成はバックグラウンドの仕事だと割り切って、CPUを全部使わせないという判断です。

書き出し自体は当然その分ゆっくりになりますが、長尺動画の生成は急ぐ必要がありません。急ぐ必要がない処理にCPUを全部渡してしまうのが、そもそも設計ミスでした。

落とし穴2:ディスクが埋まる

数時間の動画ファイルは大きいです。生成して、アップロードして、そのまま置いておくとディスクが埋まります。実際に埋まってから気づく類の問題です。

いまは生成後に動画ファイルとサムネイルを削除する処理を、パイプラインの最後に必ず入れています。

注意

削除を「あとでまとめてやる」にすると、まとめてやる前に容量が尽きます。生成→アップロード→削除、までを1本の流れとして完結させるのが安全です。

タイトルは2つ持てる

運用してみて便利だったのが、動画に焼き込む(burned-in)タイトルと、YouTube側に設定するタイトルを別々に持てるという点です。

種類 用途
burned-inタイトル 動画の映像そのものに入るタイトル
YouTube側のタイトル プラットフォーム上に表示されるタイトル

この2つが独立しているので、日本語タイトルを別途付けることができます。映像に焼き込んだ文字列を変えずに、プラットフォーム側の見せ方だけ変えられるのは、あとから調整する余地が残るという意味で助かっています。

まだ分かっていないこと

  • タイトルの付け方の違いが、実際にどれくらい結果に効いているのかは検証できていません
  • コアを2つに絞るのが最適なのかも、他の値と比較したわけではありません。Webサイトが遅くならない、という条件を満たす設定を1つ見つけただけです
失敗したこと

最初は「動画を作る」ことだけを考えて自動化しました。結果、CPUを食い尽くしてWebサイトを遅くし、生成物を消し忘れてディスクを埋めました。自動化で壊れるのは、自動化した対象ではなく、その周りです。

まとめ

  • 静止画1枚+音声で数時間の動画をffmpegで生成。処理自体は単純
  • タイトル25種×曲378本×画像46枚=434,700通り。使用済みの組み合わせを記録して重複を避ける
  • CPUを食うのでtasksetで2コアに限定しniceで優先度を下げる。しないと同居のWebサイトが遅くなる
  • 生成後に動画とサムネイルを削除する。しないとディスクが埋まる
  • burned-inタイトルとYouTube側タイトルは別管理でき、日本語タイトルを別途付けられる
広告