アプリの宣伝動画を Python で量産する: Playwright で画面録画 → VOICEVOX で読み上げ → Pillow と ffmpeg で合成

2026-10-03 ・ @apkderete

個人開発のアプリの宣伝用に、縦長(1080×1920)のショート動画を 19 本作りました。動画編集ソフトは使わず、全部 Python のスクリプトです。1本直すたびに手で編集し直さなくて済むのが一番の利点でした。

構成はこうです。

アプリ(開発サーバー) ─ Playwright + CDP screencast ─→ 画面のコマ(jpg) + 各コマの時刻
                                                         │
VOICEVOX エンジン(ローカル) ─ 文ごとに wav ─────────────┤
                                                         ▼
                         Pillow で 1 コマずつ描く(背景・スマホ枠・字幕・クレジット)
                                                         │ rawvideo を標準入力へ
                                                         ▼
                         ffmpeg(libx264) → 効果音と声を adelay + amix → loudnorm

1. 画面を録る: CDP の screencast を使う

Playwright の動画録画は画質が粗いので、Chrome DevTools Protocol の Page.startScreencast でコマを直接受け取りました。各コマの受け取り時刻も一緒に保存しておくと、後で「何秒目の画面」を正確に取り出せます。

ハマりどころが2つありました。

2. 声を作る: VOICEVOX のエンジンを HTTP で叩く

VOICEVOX はエンジンをローカルで起動すると 127.0.0.1:50021 で HTTP API が使えます。/audio_query で読み上げ用のパラメータを作り、話速や音量を書き換えて /synthesis に渡すと wav が返ってきます。同じ文はハッシュをキーにキャッシュしておくと、作り直しが速くなります。

声の長さが場面より長いときは、場面のほうを伸ばして録画をゆっくり再生しています。字幕と声がずれないので、これが一番手間が少なかったです。

VOICEVOX のキャラクターを動画に使うときは、利用規約どおりクレジット(例:「VOICEVOX:ずんだもん」)を画面に入れます。

3. 1コマずつ描いて ffmpeg に流し込む

Pillow で 1 コマずつ画像を作り、tobytes() を ffmpeg の標準入力に -f rawvideo -pix_fmt rgb24 で流しています。中間ファイルを作らないので速いです。

音は、効果音と声それぞれに adelay で開始時刻を付けて amix で混ぜ、最後に loudnorm で音量をそろえました。

ハマりどころ:

4. 「掛け合い」動画にする

途中から、2人のキャラクターが掛け合う形式に変えました。せりふを (話者, 文) の並びで書いておけば、話している人の名札と字幕、声が自動でつながります。

ここでの失敗は、せりふで「設定6の確率は17%」と言っているのに、画面がまだその数字に届いていなかったことです。録画を時間どおりに流すと、言い終わってから数字が映ります。せりふが画面の数字を指すときは、その数字が映っている瞬間で画面を止めるようにしました。

結果と反省


作っているアプリ