FFmpegで動画にAIナレーションを追加する
FFmpegはどんな音声でもどんな動画にも重ねられますが、自然な音声はつくれません。オプションのflite フィルターはロボットのような声で、ほとんどのビルドには入っていません。実用的なのは2段階の方法です。音声合成エンジンで台本を音声にし、その音声をFFmpegで動画に載せます。
このガイドでは最初の段階を無料のSuperClonicaエンジンでオフラインのまま行い、次の段階のFFmpegコマンドを紹介します。どのコマンドもテスト動画で実行済みで、-c:v copyで映像を再エンコードしないため、長いクリップでも数秒で終わります。
台本を音声にする
python -m pip install superclonica-cpuで一度だけエンジンをインストールします。初回にモデルをダウンロードし、その後はオフラインで動きます。ナレーションをテキストファイルに保存して読み上げます:
superclonica --text-file script.txt --voice M3 --lang ja --normalize --output voice.wav
声はまずカタログのページで選びましょう。30〜100文字の文を無料・登録なしで読み上げられます。どの声も31言語を話すので、--langを変えれば同じ台本を英語、スペイン語、ドイツ語でも読み上げられます。中国語にはまだ対応していません。
音声トラックを差し替える
画面録画や無音のクリップなら、映像は動画から、音はナレーションから取ります:
ffmpeg -i video.mp4 -i voice.wav -map 0:v -map 1:a -c:v copy -c:a aac voiced.mp4
動画は元の長さのままで、声のほうが短ければ残りは無音になります。ここでは-shortestを付けないでください。ストリームコピーと組み合わせると止まったり、映像が声の長さで切れたりすることがあります。
声を音楽に重ねる
元の音やBGMをナレーションの下に残すには、音量を下げて両方をミックスします:
ffmpeg -i video.mp4 -i voice.wav -filter_complex "[0:a]volume=0.25[music];[music][1:a]amix=inputs=2:duration=first:normalize=0[a]" -map 0:v -map "[a]" -c:v copy -c:a aac voiced.mp4
volume=0.25で音楽を4分の1に、duration=firstで動画の長さを保ち、normalize=0でamixが声を半分にするのを防ぎます。
声が出ている間だけ音楽を下げる
サイドチェーンコンプレッサーは、編集者がするように、声が大きいときに音楽を下げ、間で戻します:
ffmpeg -i video.mp4 -i voice.wav -filter_complex "[1:a]asplit=2[v][key];[0:a][key]sidechaincompress=threshold=0.02:ratio=10:attack=20:release=400[music];[music][v]amix=inputs=2:duration=first:normalize=0[a]" -map 0:v -map "[a]" -c:v copy -c:a aac voiced.mp4
下げ幅を大きくするならratioを上げ、音楽の戻りが速すぎるならreleaseを長くします。
複数のセリフを正確な時間に置く
セリフごとに別ファイルにし、それぞれをミリ秒単位でその時点まで遅らせて、すべてをミックスします:
ffmpeg -i video.mp4 -i line1.wav -i line2.wav -filter_complex "[1:a]adelay=500:all=1[l1];[2:a]adelay=4000:all=1[l2];[0:a]volume=0.25[music];[music][l1][l2]amix=inputs=3:duration=first:normalize=0[a]" -map 0:v -map "[a]" -c:v copy -c:a aac voiced.mp4
この例では1つ目のセリフが0.5秒、2つ目が4秒から始まります。セリフごとにファイルが分かれているので、台本を直しても読み直すのは1行だけで済みます。字幕がすでにあるなら、SRTを音声にするガイドがタイミング付きのトラックを自動でつくります。