フィルタグラフとは
フィルタグラフは、フィルタ(映像や音声を加工する部品)をつないだ処理の流れです。映像や音声のフレームがフィルタからフィルタへ順に流れ、それぞれのフィルタで加工されます。
入力 → [scale] → [overlay] → 出力
↑
[logo入力]
入力も出力も1つだけの単純な処理は、-vf(映像)か -af(音声)で指定します。入力や出力が複数あるときや、別々の処理を並べるときは、-filter_complex を使います。
シンプルフィルタ:-vf と -af
映像フィルタ(-vf)
ffmpeg -i input.mp4 -vf "scale=1280:720" output.mp4
ffmpeg -i input.mp4 -vf "scale=1280:720,fps=30" output.mp4
複数のフィルタを , でつなぐと、左から順に処理されます。これをフィルタチェーンと呼びます。
音声フィルタ(-af)
ffmpeg -i input.mp4 -af "volume=2.0" output.mp4
フィルタチェーンの区切り文字
| 記号 | 意味 |
|---|---|
, |
同一チェーン内で次のフィルタへ(前フィルタの出力が次の入力) |
; |
別のフィルタチェーンを開始(並列チェーン) |
-filter_complex の基本
-filter_complex では、[name] の形の名前(ラベル)でストリームを区別します。
スケールして特定の出力ラベルにバインド
ffmpeg -i input.mp4 -filter_complex "[0:v]scale=640:360[v]" -map "[v]" -map 0:a output.mp4
[0:v]:入力0(1つ目のファイル)の映像ストリームscale=640:360:大きさを 640x360 に変えるフィルタ[v]:出力に付けるラベル(名前は自由)-map "[v]":ラベル[v]の映像を出力ファイルに入れる
複数フィルタのチェーン
ffmpeg -i input.mp4 -filter_complex "[0:v]scale=1280:720,fps=30[v]" -map "[v]" -map 0:a -c:a copy output.mp4
ウォーターマーク(画像オーバーレイ)
入力を2つ使う overlay フィルタの例です。
ffmpeg -i input.mp4 -i logo.png \
-filter_complex "[0:v][1:v]overlay=10:10[v]" \
-map "[v]" -map 0:a -c:a copy output.mp4
[0:v]:背景になる映像[1:v]:ロゴの画像overlay=10:10:左上から (10,10) の位置に重ねる
複数出力の作成(サムネイルと本編を同時生成)
ffmpeg -i input.mp4 \
-filter_complex "[0:v]scale=1280:720[main];[0:v]scale=320:180[thumb]" \
-map "[main]" -c:v libx264 -crf 23 main.mp4 \
-map "[thumb]" -c:v libx264 -crf 28 thumb.mp4
1つの入力から、2つのファイルを同時に書き出します。
音声と映像を同時に処理する
映像の大きさの変更と、音量の調整を同時に行う例です。
ffmpeg -i input.mp4 \
-filter_complex "[0:v]scale=1280:720[v];[0:a]volume=1.5[a]" \
-map "[v]" -map "[a]" -c:v libx264 -crf 23 output.mp4
amix で複数音声を合成する
BGM と元の音声を混ぜる例です。
ffmpeg -i main.mp4 -i bgm.mp3 \
-filter_complex "[0:a][1:a]amix=inputs=2:duration=first:dropout_transition=2[a]" \
-map 0:v -map "[a]" -c:v copy output.mp4
split でストリームを分岐させる
1つの映像を2つに分けて、それぞれ別に処理する例です。
ffmpeg -i input.mp4 \
-filter_complex "[0:v]split[v1][v2];[v1]scale=1280:720[main];[v2]scale=320:180[preview]" \
-map "[main]" -c:v libx264 -crf 23 main.mp4 \
-map "[preview]" -c:v libx264 -crf 30 preview.mp4
よくあるエラーと対処法
Filter 'split' has output 1 (b) unconnected
-filter_complex で名前を付けた出力(この例では [b])を、どの -map でも指定していないときに出ます。名前を付けた出力は、-map "[b]" のように必ずどれかの出力ファイルに割り当ててください。
Simple and complex filtering cannot be used together for the same stream
-filter_complex から出てきた映像や音声に、さらに -vf や -af をかけることはできません。フィルタはすべて -filter_complex の中にまとめてください。
実測: 処理時間とサイズ
1080p の動画1本から、本編用の 720p とプレビュー用の 360p を同時に書き出して計測しました。計測したコマンドは次のとおりです。
ffmpeg -i input.mp4 -filter_complex "[0:v]split=2[v1][v2];[v1]scale=1280:720[main];[v2]scale=640:360[preview]" -map "[main]" -c:v libx264 -crf 23 -an main.mp4 -map "[preview]" -c:v libx264 -crf 28 -an preview.mp4
| 項目 | 実測値 |
|---|---|
| 処理時間 | 17.52 秒(6.85倍速) |
| 出力サイズ | 41.14 MB |
出力サイズの 41.14 MB は、720p の main.mp4 の大きさです。360p のプレビューも同じ処理の中で書き出していますが、この数字には含めていません。
計測環境: 1920x1080 / 30fps / 120秒 / 351.4 MB の素材(Big Buck Bunny をループ、CC BY 3.0)、Core i9-14900KF(32スレッド)、FFmpeg 8.1(gyan.dev)、2026-09-05、各コマンドを1つずつ順に実行。元データはデータセットで公開しています。
この数字になる理由
出力を2本にしても、処理時間は 720p を1本だけ出すときとほぼ同じでした。同じ素材を 720p に縮小するだけのコマンドは 18.43 秒、split で 720p と 360p を同時に出したこのコマンドは 17.52 秒です。
これは、この処理にかかる時間の大部分が、デコードではなく、エンコードする画素の数で決まるからです。split を使うと入力のデコードは1回で済み、増えるのは 640x360 の小さな映像をもう1本エンコードする分だけです。一方、1080p のままフィルタなしで再エンコードすると 27.97 秒かかりました。解像度を下げてから再エンコードするほうが、下げずに再エンコードするより速く終わります。
ただし、フィルタを使うと必ず再エンコードになります。同じ計測環境で映像を再エンコードしない操作は、ストリームの入れ替えが 0.41 秒、moov atom の移動が 0.49 秒、映像はコピーのまま音声だけを再エンコードする音声フェードが 1.03 秒でした。フィルタを1つでも使うと、今回の例では 17.52 秒かかります。分割や縮小が本当に必要か、コンテナの操作だけで済まないかを、先に確かめてください。
つまずきやすいポイント
-
,と;を取り違えて、フィルタがつながらない。,は同じチェーンの中で次のフィルタにつなぐ記号で、;は別のチェーンを始める記号です。1本のストリームを順に処理するなら,、ラベルで分けたりまとめたりするなら;を使います。例:scale=...,fps=...は順につながった処理、[0:v]...[v];[0:a]...[a]は別々に並んだ処理です。 -
Output with label 'x' does not existというエラーが出る。-map "[x]"で指定したラベルが-filter_complexの中にないか、名前が合っていないか、同じラベルをすでに別の-mapで使っています。ラベル名は、大文字と小文字まで同じにします。 -
グラフの中で付けたラベルを2回使うと、片方の出力が加工されないままになる。
[v1]のようにグラフの中で付けたラベルは、一度しか使えません。FFmpeg 8.1 では、2回目に使ってもエラーは出ず、そこには1つ目の入力ファイルの映像や音声が加工なしで入ります。[v1]のようなラベルの場合、FFmpeg 6.1 ではmatches no streamsのエラーで止まります。同じ映像を何度も使うときは、split(映像)やasplit(音声)で複製し、別のラベルに分けます。上のsplitの例を見てください。[0:v]のような入力ファイルの指定は、何度使ってもかまいません。 -
同じストリームに
-filter_complexと-vfの両方を使ってエラーになる。 1つのストリームに両方はかけられません(別々のストリームなら、一緒に使えます)。そのストリームのフィルタは、すべて-filter_complexの中にまとめます。
よくある質問
Q. -vf と -filter_complex はいつ使い分けますか。
A. 入力も出力も1つの単純な処理なら、-vf(音声は -af)で足ります。入力が複数あるとき(重ねる、混ぜる)、出力が複数あるとき、途中で分けたりまとめたりするときは、-filter_complex を使います。
Q. ラベル名に決まりはありますか。
A. [v] や [main] など、英数字で自由に付けられます。[thumb] のように役割がわかる名前にすると、読みやすくなります。入力ファイルのストリームは、[0:v] や [1:a] のように「入力番号:種類」で指定します。
Q. 1回のデコードで複数出力を作れますか。
A. できます。split でストリームを複製し、それぞれを別の -map で別のファイルに出力します。入力のデコードは1回で済み、同じファイルを何度も読まずに済みます。
Q. 音声と映像を同時に処理できますか。
A. できます。[0:v]...[v];[0:a]...[a] のように別々のチェーンで処理し、-map "[v]" -map "[a]" で両方を出力に入れます。
Q. フィルタの順序は結果に影響しますか。
A. します。たとえば crop を scale の前に入れるか後に入れるかで、結果が変わります。, でつないだフィルタは左から順にかかるので、やりたい順に並べてください。