PR
AIで記事作成を効率化したいなら → 高品質SEO記事生成AIツール【Value AI Writer byGMO】
※本記事は2026年9月に実際に行った作業の記録です。コマンドはmacOS(ffmpeg 8系)で動作確認しています。
こんにちは!Conomacです。
SeaArtなどの生成AIで作った動画に、あとから別で作った音声(VOICEVOXなど)を載せたい——よくある要望ですが、動画編集ソフトを開かずにコマンドだけで完結できます。しかも映像は再エンコードせず、画質を一切落とさずに音声だけ差し替えられます。
実際にこの方法で作ったショート動画がこちらです。
この記事でわかること
- 生成AIの動画(mp4/mov)に、別のWAV音声を載せる手順
- 音声を置き換える場合と、元の環境音を残して重ねる(ミックス)場合の使い分け
- 映像を劣化させずに処理できたかを数値で確認する方法
- 「音量が測れない」「音声が途中で切れる」など、ハマりどころ
前提:まず2つの素材の仕様を確認する
いきなり結合する前に、ffprobeで中身を確認します。ここで映像の解像度・フレームレート・音声のサンプルレート・長さを見ておくと、後段のトラブルが激減します。
ffprobe -v error -show_entries stream=index,codec_name,codec_type,width,height,r_frame_rate,channels,sample_rate,duration -show_entries format=duration -of default=noprint_wrappers=1 video.mov
ffprobe -v error -show_entries stream=codec_name,channels,sample_rate,duration -of default=noprint_wrappers=1 voice.wav
今回の実例では、動画が「720×1244 / 30fps / h264 + aac / 10.07秒」、音声が「モノラル 24kHz / 7.37秒」。動画のほうが長い点がポイントです(後述)。
手順1:音声を「置き換える」(いちばんシンプル)
元動画の音を消して、用意した音声だけにしたい場合はこれだけです。
ffmpeg -i video.mov -i voice.wav \
-map 0:v:0 -map 1:a:0 \
-c:v copy -c:a aac -b:a 192k -ar 44100 -ac 2 -movflags +faststart out.mp4
-c:v copyが最重要。映像をコピーするので再エンコードなし=画質劣化ゼロ・処理も数秒-map 0:v:0 -map 1:a:0で「1つ目のファイルの映像」+「2つ目のファイルの音声」を選ぶ- 音声は
aac 192k / 44.1kHz / ステレオに整えると、各種プラットフォームで再生トラブルが起きにくい -movflags +faststartを付けると、Web再生時の読み込みがスムーズになる
手順2:元の環境音を残して「重ねる」(ミックス)
生成AIの動画には、環境音やBGMが入っていることがあります。それを薄く残したまま、声を上に載せたい場合はこちら。
ffmpeg -i video.mov -i voice.wav -filter_complex \
"[0:a]volume=0.6[bg];[1:a]volume=1.6,aresample=44100[vo];[bg][vo]amix=inputs=2:duration=first[out]" \
-map 0:v:0 -map "[out]" -c:v copy -c:a aac -b:a 192k out.mp4
volume=0.6で元の環境音を控えめに、volume=1.6で声を持ち上げています(数字は聞きながら調整)amixは入力を合成するので、声が埋もれる場合はここでバランスを取るduration=firstは「1つ目の入力の長さに合わせる」の意味。動画側の長さを維持したいときに便利です
検証1:映像が本当に無劣化か確かめる
「-c:v copy したから大丈夫」で終わらせず、元動画と出力のフレームを数値で比較します。Python(MoviePy)で同じ秒のフレームを取り出して差を見るだけです。
from moviepy import VideoFileClip
import numpy as np
A = VideoFileClip("video.mov"); B = VideoFileClip("out.mp4")
for t in [1.0, 5.0, 9.0]:
d = np.abs(A.get_frame(t).astype(int) - B.get_frame(t).astype(int)).max()
print(t, "差分:", int(d))
すべて差分: 0なら、映像はビット単位で同一=完全に無劣化です。「なんとなくキレイ」ではなく0で確認するのがおすすめ。
検証2:音量を測る(ハマりどころ付き)
ffmpeg -hide_banner -i out.mp4 -af volumedetect -f null - 2>&1 | grep -E 'mean_volume|max_volume'
注意:-v error を付けると volumedetect の結果が出ません(volumedetectはinfoレベルで出力するため)。最初これで「測れない」とハマりました。-hide_bannerだけにして、2>&1で標準エラーも拾うのが正解です。
今回の実例では、元動画の環境音が mean -37.5dB・声が mean -24.2dB / max -5.7dB でした。数字を見ておくと「声が小さすぎないか」「割れていないか」を客観的に判断できます。
つまずきポイント
- 音声が動画より短いとき:無音区間ができます(今回は声7.37秒/動画10.07秒)。長さを合わせたいなら
-shortestを付けて動画を切るか、後ろに無音を足します。どちらが自然かは用途次第です。 - サンプルレートが違う:VOICEVOXのWAVは24kHzモノラル。そのまま入れると環境によっては再生が不安定なので、
-ar 44100 -ac 2で整えるのが無難です。 - 動画編集ソフト不要:カット・テロップ・BGM合成までffmpegで完結します。手作業より再現性が高く、スクリプト化すれば量産できます。
- YouTubeは投稿後にタイトル・カテゴリを変更できない:APIのアップロード用スコープでは
videos.updateが使えないためです。投稿前に決め切りましょう。
まとめ
- 生成AI動画への音声の後載せは、ffmpegの2行で完結する
-c:v copyで映像は無劣化。フレーム差分0で検証できる- 「置き換え」と「ミックス」は
-filter_complexの有無で使い分け - 音量計測は
-v errorを付けない(volumedetectが消える)
動画の素材づくりから音声の合成、結合、投稿まで、コマンドでつながると「1本作る」のハードルがぐっと下がります。ぜひ試してみてください。
PR・広告
動画の音声を整えるなら
ナレーションや音声の収録に、1本あると音が変わります。
関連記事
AIショート動画に喋らせてみた|VOICEVOX導入でkokoro版と聴き比べ+実測コスト全公開
ブログ画像3枚からYouTubeショート動画を全自動で作る方法|BGM生成×テロップ×YouTube API連携の全手順
今回の動画の元記事(メインサイト): 【完全保存版】AI画像生成の始め方 完全ガイド