
GeoPrismJP 説明動画の作り方 — TSV + Python + ffmpeg で音声テロップ付き動画を自動生成(内部情報)
GeoPrismJP のデモ動画・操作説明動画は、スクリーンショット画像と台本テキストを TSV ファイルに書くだけで、ナレーション音声+テロップ付きの mp4 が自動生成されるしくみで作っています。この記事ではそのワークフローを紹介します。
説明ビデオ作成はAIに任せるのが近頃のトレンドでしょうが、古い人間は昔ながらの方法をとってます。ただし、初期のTSVファイル作成は、Claude Coworkを使って、スクリーンショット画像から自動で作成しています。初期のTSVを修正して使うので便利ではあります。
全体の流れ
スクリーンショット撮影
↓
TSV ファイルに台本を書く(frame_no / 秒数 / 読み上げ文 / テロップ文 / 画像パス)
↓
preview_subtitles.py でテロップ位置・改行を目視確認
↓
preview_tts.sh で読み上げ音声を確認・秒数調整
↓
make_voiced_video.sh で最終 mp4 を生成
必要なツール
| ツール | 用途 | インストール |
|---|---|---|
| Python 3 + Pillow | テロップ焼き込み | pip3 install pillow --break-system-packages |
macOS say コマンド |
TTS 音声生成 | macOS 標準(Kyoko 音声が必要) |
| ffmpeg | 動画・音声合成 | brew install ffmpeg |
Kyoko 音声が未インストールの場合は、システム設定 → アクセシビリティ → 読み上げコンテンツ からダウンロードしてください。
TSV ファイルの書き方
スライド1枚につき1行、タブ区切りで記述します。
# frame_no dur tts display img_file
1 6 じおプリズムのホーム画面です。 GeoPrismJPのホーム画面です。 images/zuremap/Simulator Screenshot - iPhone 17 Pro - 2026-06-09 at 20.35.39.png
2 8 ズレマップをタップして開きます。東京測地系から… ズレマップをタップして開きます。東京測地系から… images/zuremap/Simulator Screenshot - ...
| 列 | 内容 | 注意点 |
|---|---|---|
frame_no |
フレーム番号(1始まり) | 連番でなくてもよい |
dur |
表示秒数(整数) | 読み上げ時間+余白を目安に設定 |
tts |
読み上げ文(TTS 用) | JGD2000 → 「じぇいじーでぃーにせん」のように仮名で書く |
display |
テロップ表示文 | 正式表記(JGD2000、GeoPrismJP など)で書く |
img_file |
使用画像のパス | スクリプトからの相対パス |
# で始まる行はコメントとして無視されます。display 内で改行したい場合は \n を使います。
動画ごとに TSV ファイルを用意します(例:slides_default.tsv、zuremap.tsv)。複数動画に対応しており、スクリプトにファイル名を渡すだけで切り替わります。
Step 1:テロップをプレビューする
python3 preview_subtitles.py zuremap.tsv
images/zuremap/tmp/ に各フレームのプレビュー画像が生成されます。テロップの位置・改行・折り返しを目視で確認し、display テキストを調整します。
データファイルを省略すると slides_default.tsv が使われます。
Step 2:読み上げ音声を確認する
# 全スライドを通しで読み上げ
bash preview_tts.sh --data zuremap.tsv
# frame 5〜10 だけ確認
bash preview_tts.sh --data zuremap.tsv 5 10
# 2倍速で通し確認
bash preview_tts.sh --data zuremap.tsv --x2
# 読み上げ時間が dur を超えたフレームの dur を自動更新
bash preview_tts.sh --data zuremap.tsv --update
読み上げが dur 秒を超えるとコンソールに赤字で警告が出ます。--update オプションを付けると、超過したフレームの dur を実測値+1秒に自動書き換えてくれます。
TTS は macOS の say コマンドを使い、Kyoko 音声(女性)で読み上げます。tts 列には JGD2000 を「じぇいじーでぃーにせん」のように仮名表記しておくと自然に発音されます。
Step 3:最終 mp4 を生成する
bash make_voiced_video.sh zuremap.tsv
zuremap-voiced.mp4 が出力されます(データファイルのステム名 + -voiced.mp4)。slides_default.tsv を使うと geoprism-demo-voiced.mp4 になります。
内部的には4ステップで処理されます。
- テロップ焼き込み:Pillow でスクリーンショットにテロップ画像を生成
- 無音動画生成:ffconcat + ffmpeg でスライドショー動画を作成
- 音声生成:
sayで各フレームのナレーション音声ファイルを生成し連結 - 動画合成:無音動画+ナレーション音声を ffmpeg でマージ
ファイル構成
41-post/
├── slides_default.tsv # メインデモ動画の台本
├── zuremap.tsv # ズレマップ説明動画の台本
├── slides_data.py # TSV ローダー(各スクリプトから import)
├── preview_subtitles.py # テロップ確認用プレビュー生成
├── preview_tts.sh # TTS 読み上げ確認スクリプト
├── preview_tts_runner.py # preview_tts.sh から呼び出される Python 本体
├── make_voiced_video.sh # 最終 mp4 生成スクリプト
├── images/
│ ├── flow/ # メインデモ動画用スクリーンショット
│ │ └── tmp/ # preview_subtitles.py の出力先
│ └── zuremap/ # ズレマップ動画用スクリーンショット
│ └── tmp/ # preview_subtitles.py の出力先
├── geoprism-demo-voiced.mp4 # 生成済みデモ動画
└── zuremap-voiced.mp4 # 生成済みズレマップ説明動画
新しい動画を追加する手順
- スクリーンショットを
images/<テーマ名>/に保存する <テーマ名>.tsvをslides_default.tsvを参考に作成するpython3 preview_subtitles.py <テーマ名>.tsvでテロップを確認・調整するbash preview_tts.sh --data <テーマ名>.tsv --updateで秒数を調整するbash make_voiced_video.sh <テーマ名>.tsvで mp4 を生成する
スクリプト類は TSV を差し替えるだけで動くため、機能ごとに動画を追加していくのが容易です。
関連記事・動画
お願い
本記事の情報は参考目的で掲載しており、正確性・完全性を保証するものではありません。誤記・不正確な情報がございましたら、コメント欄よりご指摘いただければ、確認のうえ修正いたします。
コメントを残す