VOICEVOXで動画のナレーションを作る

VOICEVOXで動画のナレーションを作る — VOICEVOX, 動画ナレーション, API活用

こんにちは、パレイド技術部の夏目です。別の記事で、動画ナレーションに使う読み上げ音声(TTS)のツールをいくつか比較検討しました。手元の Mac で無料かつローカルで完結する条件で選んだ結果、動画制作の用途では VOICEVOX が最も扱いやすいという結論になりました。

今回はその続きです。ツールを選んだあとに待っているのは「実際にどう使うか」で、ここが意外と手間のかかる部分です。VOICEVOX は GUI アプリで一文ずつ入力して書き出せますが、数分の動画でもナレーションは数十カット分になり、台本を直すたびに全部を手作業で書き出し直すのは現実的ではありません。そこでこの記事では、VOICEVOX をローカルの API として叩き、台本テキストからナレーション音声を一括生成して動画制作パイプラインに組み込むところまでを検証します。

本記事はローカル LLM による自動執筆パイプラインで生成されました。現段階ではクラウド AI(Claude 等)の補助や人間の編集が介在していますが、pareido.jp では最終的に AI が自律的にコンテンツを制作できる仕組みの構築を目指しています。

検証した環境は以下のとおりです。VOICEVOX のインストール手順そのものは別記事にまとめてあるので、ここでは起動済みの状態から話を始めます。

項目 使用したもの
OS macOS(Apple Silicon)
VOICEVOX GUI 版(同梱エンジンが localhost:50021 で待機)
スクリプト言語 Python 3.12 + requests
動画への合成 ffmpeg

VOICEVOX を API として使う

VOICEVOX エンジンは、起動すると localhost:50021REST API サーバーとして待ち受けます(REST API = HTTP でやり取りする外部連携用の窓口)。ふだん GUI アプリを操作しているときも、裏側では同じエンジンがこのポートでリクエストを受け付けています。つまり、GUI を開かなくてもプログラムから直接音声を生成できます。

音声合成は 2 段階に分かれています。まず /audio_query にテキストと話者 ID を渡して「音声合成用クエリ」(話速・音高・抑揚・アクセントなどのパラメータ一式が入った JSON)を受け取ります。次に、そのクエリを /synthesis に POST すると WAV バイナリが返ってきます。

なぜ 1 発ではなく 2 段階かというと、間に挟まる audio_query の JSON を書き換えることで、話速や抑揚、読み方までプログラムから細かく制御できるからです。GUI の調整スライダーで触れるものは、この JSON の値と 1 対 1 で対応しています。まずは curl で最小の流れを確認します。

SPEAKER=<話者ID>   # 使いたいキャラクターの番号に置き換える
TEXT="こんにちは、パレイド技術部の夏目です。"

# 1. テキストから音声合成用クエリ(JSON)を生成する
curl -s -X POST \
  "http://localhost:50021/audio_query?speaker=${SPEAKER}" \
  --get --data-urlencode "text=${TEXT}" \
  > query.json

# 2. クエリを synthesis に渡して WAV を書き出す
curl -s -X POST \
  "http://localhost:50021/synthesis?speaker=${SPEAKER}" \
  -H "Content-Type: application/json" \
  -d @query.json \
  > narration.wav

話者 ID は VOICEVOX の GUI 上で使いたいキャラクターを選ぶと確認できます。この 2 コマンドが通れば、あとはテキストを差し替えるだけで何本でも音声を作れます。

台本から WAV を一括生成する

動画のナレーションは、台本の全文を一度に合成するのではなく、字幕(caption)の単位に合わせて分割して生成するのが実務的です。理由は単純で、音声ファイルと字幕を 1 対 1 で対応させておくと、後段で「この音声が流れている間、この字幕を出す」という同期が取りやすいからです。

分割の粒度には少し工夫が要ります。1 文ずつに区切ると音声が短く切れて間が不自然になりやすく、逆に台本のまとまりごと長く渡すと、字幕として画面に載せたときに文字が溢れて見切れます。いろいろ試した結果、2 文ずつまとめて合成するのが、字幕の可読性とナレーションの自然さのバランスが取りやすいという印象でした。以下は、台本を 2 文ずつに区切って連番 WAV として書き出す Python スクリプトです。

import re
import requests

VOICEVOX = "http://localhost:50021"
SPEAKER = 0            # 使いたいキャラクターの話者IDに置き換える

def synth(text: str, speaker: int) -> bytes:
    # 1. テキストから音声合成用クエリを作る
    query = requests.post(
        f"{VOICEVOX}/audio_query",
        params={"text": text, "speaker": speaker},
    ).json()
    # 2. クエリを渡して WAV バイナリを受け取る
    return requests.post(
        f"{VOICEVOX}/synthesis",
        params={"speaker": speaker},
        json=query,
    ).content

def split_by_two(script: str) -> list[str]:
    # 句点(。!?)で文に割り、2文ずつまとめる
    sentences = [s for s in re.split(r"(?<=[。!?])", script) if s.strip()]
    return ["".join(sentences[i:i + 2]) for i in range(0, len(sentences), 2)]

script = open("script.txt", encoding="utf-8").read()
for i, chunk in enumerate(split_by_two(script)):
    with open(f"narration_{i:03d}.wav", "wb") as f:
        f.write(synth(chunk, SPEAKER))
    print(f"narration_{i:03d}.wav  <-  {chunk}")

script.txt に台本を入れて実行すると、narration_000.wav から連番で音声が書き出されます。ファイル名の連番が そのまま字幕の並び順に対応するので、後段の動画合成でどの音声にどの字幕を当てるかで迷わなくなります。台本を直したら、このスクリプトを流し直すだけで音声も作り直せます。

読み間違いを補正する

VOICEVOX は日本語をかなりうまく読みますが、固有名詞や複数の読みを持つ漢字は間違えます。製品名・人名、「重版出来(しゅったい)」のような特殊な読み、文脈で読みが変わる語などが典型です。動画に載せてから読み間違いに気づくと、その部分だけ作り直すことになります。

補正の考え方として大事なのは、画面に表示する字幕は元の漢字のまま残し、音声合成に渡すテキストだけ読み方を差し替えることです。表示と発音を分離すれば、目には正しい漢字が見え、耳には正しい読みが届く状態を作れます。もっとも手軽なのは、合成に渡す前のテキストで、間違えやすい語だけを読み仮名に置換しておく方法です。

字幕として表示するテキスト 音声合成に渡すテキスト
重版出来 じゅうはんしゅったい
代替案を提示 だいたいあんを提示
pareido パレイド

より厳密にやりたい場合は、/audio_query が返す JSON のアクセント句(かな情報)を直接書き換える手もあります。ただし置換方式でも実用上はほとんど困らないので、まずは「表示用テキスト」と「音声用テキスト」を別々に持つ運用から始めるのが現実的でしょう。

まとめ

生成した連番 WAV は、ffmpeg で動画に載せられます。連結して 1 本にまとめ、素材動画へ音声トラックとして重ねる最小例が以下です。ffmpeg の導入や細かいオプションは別記事に譲ります。

# 連番WAVを1本に連結(list.txt に file 'narration_000.wav' の形で列挙)
ffmpeg -f concat -safe 0 -i list.txt -c copy narration_all.wav

# 素材動画に音声を重ねる
ffmpeg -i base.mp4 -i narration_all.wav -c:v copy -shortest output.mp4

GUI で 1 つずつ書き出す運用から、台本 → API → 連番 WAV → ffmpeg の流れに移すと、台本を直すたびの作り直しコストがほぼゼロになります。今回効いたのは「2 文ずつ分割」と「表示と読みの分離」という 2 つの運用ルールで、字幕付き動画ではこの 2 点が地味に効いてきます。VOICEVOX 自体のセットアップがまだの場合は、下記のインストール記事から始めてください。次は、話者ごとの声質の調整や、複数キャラクターの掛け合いをどう自動で割り当てるかを検証してみたいところです。

パレイドVOICEVOX のインストール方法と初期設定 — Windows/Mac対応ガイドVOICEVOX は、YouTubeでも人気の無料テキスト読み上げ/合成音声ソフトウェアです。 この記事では、WindowsとMacでのダウンロードからインスト… パレイドffmpegの導入ガイド:AI音声・動画処理の基礎ffmpegとは ffmpegは、音声や映像データの変換や抽出、圧縮などを行うオープンソースのツールです。AI音声合成、動画生成、音声認識のプロジェクトで…
▶ 関連動画 · YOUTUBE
━━ 観るのを再開 ━━
前の記事を読む
同部門 · 夢十夜・終章 ── 10 夜の夢を見終えて。地理なき古典から、次の古典へ
動画を観る
YouTube
━━ 他の観測領域 ━━
TECH · 技術部
AIで256倍楽しむ【女神転生】[FC] 第4回|最後の2バイトを読んで、悪魔図鑑をいったん閉じる
PHIL · 思想部
召喚をコードにする(4)|種を暦から山の伝承へ、そして「顔」そのものが答え合わせの対象になった
FRONT · 辺境部
【パレイドリア奇譚 02】お菊虫 ── 播州皿屋敷、蛹に見た後ろ手の女