基本コマンド

ffmpeg -i input.mp4 \
  -vf "scdet=t=10,metadata=mode=print:key=lavfi.scd.score" \
  -f null /dev/null

scdet は、1 つ前のフレームとどれだけ違うかをスコアにして、場面の切り替わり(シーンチェンジ)を探すフィルタです。t=10 は「スコアが 10 以上なら切り替わりとみなす」という指定です。-f null /dev/null はファイルを書き出さない指定です。metadata=print は、すべてのフレームのスコアを画面(標準エラー出力)に表示します。切り替わりと判定したフレームでは、scdet 自身も lavfi.scd.score と lavfi.scd.time を 1 行で表示します。

出力の読み方

[Parsed_metadata_1 @ 0x...] frame:149  pts:76288   pts_time:4.966667
[Parsed_metadata_1 @ 0x...] lavfi.scd.score=0.131
[Parsed_scdet_0 @ 0x...] lavfi.scd.score: 25.146, lavfi.scd.time: 5
[Parsed_metadata_1 @ 0x...] frame:150  pts:76800   pts_time:5
[Parsed_metadata_1 @ 0x...] lavfi.scd.score=25.146
フィールド 説明
lavfi.scd.score シーンチェンジスコア(高いほど変化が大きい)
lavfi.scd.time 検出時刻(秒)

threshold(感度)の調整

パラメータ デフォルト 説明
t / threshold 10 この値以上のスコアをシーンチェンジとして報告
ffmpeg -i input.mp4 -vf "scdet=t=20" -f null /dev/null

metadata を付けずに scdet だけで実行すると、切り替わりを見つけたときだけ lavfi.scd.score と lavfi.scd.time がログに出ます。

  • 低い値(例: 5):小さな変化まで拾います。誤検出が増えます。
  • 高い値(例: 40):はっきりしたカットだけを拾います。見逃しが増えます。
  • ドキュメンタリーや映画なら 8〜14 が目安です。

シーンチェンジ点のフレームを画像として保存

select フィルタを使うと、場面が切り替わった瞬間のフレームを画像として保存できます。

ffmpeg -i input.mp4 -vf "select='gt(scene,0.35)'" -fps_mode vfr scene_%04d.png

gt(scene,0.35) は「シーンスコアが 0.35 より大きいフレームだけを通す」という意味です。-fps_mode vfr を付けないと、間を埋めるために同じ画像が何枚も書き出されます。

注意: select の scene は select フィルタが計算するスコアで、scdet の lavfi.scd.score とは別の値です。しきい値も別に決めてください。

metadata フィルタでタイムスタンプを確認

ffmpeg -i input.mp4 -vf "scdet=t=10,metadata=print" -f null /dev/null

key を指定しないと、フレームごとにすべてのメタデータが表示されます。切り替わりと判定されたフレームには、lavfi.scd.time(その時刻)も出ます。

用途別のthreshold設定例

FFmpeg の公式ドキュメントでは、8〜14 がよい値とされています。まずデフォルトの 10 で試し、動きの多い映像で誤検出が出るなら上げ、カットを見逃すなら下げます。

よくある注意点

フェードやディゾルブは検出精度が低い

ハードカット(一瞬で切り替わる場面転換)は正確に検出できます。フェードやディゾルブ(少しずつ切り替わる場面転換)は、1 フレームごとの変化が小さいので、scdet では見逃しやすくなります。

長い動画では処理時間がかかる

シーン検出はすべてのフレームをデコード(展開)するので、長い動画ほど時間がかかります。-ss と -to で範囲を絞れば、一部だけを調べられます。

実測: 処理時間とサイズ

計測したのは次のコマンドです。

ffmpeg -i input.mp4 -vf "scdet=t=12,metadata=mode=print:key=lavfi.scd.time" -f null -
項目 実測値
処理時間 7.09 秒(実時間の 16.92 倍速)
出力ファイル なし(解析のみ)

計測環境: Core i9-14900KF(32 スレッド)/ FFmpeg 8.1 (gyan.dev) / 素材は 1920x1080・30fps・120 秒・351.4 MB の H.264(Big Buck Bunny をループ、CC BY 3.0)。2026-09-05 に、ほかの処理と並行させずに 1 本ずつ実行しました。生データはデータセットで公開しています。

なぜ 7.09 秒なのか

-f null - は、全フレームをデコードして scdet に通したあと、エンコードもディスクへの書き込みもせずに捨てます。同じ素材・同じマシンで、フィルタなしで H.264 に再エンコード(-c:v libx264 -crf 23 -preset medium)すると 27.97 秒かかりました。この差は、シーン検出が軽いからではありません。エンコードをしていないからです。

逆に、映像のフレームをデコードしない操作(映像を -c copy や -c:v copy でそのまま使う操作)は、もっと速く終わります。ストリームの選択が 0.41 秒、moov atom(MP4 の管理情報)の移動が 0.49 秒、音声フェードが 1.03 秒で、どれも 1 秒前後です。映像はファイルへ詰め直す(多重化する)だけだからです。音声フェードで再エンコードしているのは、音声だけです。scdet はその中間です。全フレームをデコードしますが、エンコードはしません。時間の大半は、このデコードにかかっています。

16.92 倍速という速さは、32 スレッドの i9 で、1080p・8bit の H.264 をローカルディスクから読んだ場合の数字です。4K や 10bit の HEVC ではデコード自体が重くなります。この計測では、7.09 秒で 351.4 MB(毎秒約 50 MB)を読んでいます。ネットワーク越しに読む場合、回線がこれより遅いと、CPU より先に読み込みの速さ(I/O)が限界になります。

また、7.09 秒は画像を 1 枚も書き出していないときの数字です。検出した場面を PNG で保存する場合は、画像のエンコードとディスクへの書き込みの時間が加わります。

検出した時刻を編集点に使うときは、ログの時刻をそのまま -ss に渡さず、前後に0.2〜0.5秒の余白を取ると失敗が減ります。シーン検出が拾うのは映像の変化だけで、音声の切れ目や字幕のタイミングは見ていません。自動で分割すると、とても短いクリップが大量にできることがあります。スクリプト側で、短すぎるクリップを除く処理を入れておくと扱いやすくなります。

カメラのフラッシュ、画面全体が白くなるフェード、ゲーム画面の暗転は、カットでなくても高いスコアになることがあります。結果を完全に自動で使う前に、代表的な部分を数分ぶん目で確認して、しきい値を決めてください。

関連記事

よくある質問

シーン検出の閾値は?

select なら、select='gt(scene,0.35)' で大きなカットを拾うところから始めます。カットの速い動画なら 0.25〜0.3 まで下げ、ハードカットだけを拾うなら 0.45〜0.5 に上げます。scdet の t とは尺度が違うので、同じ数値は使えません。

タイムスタンプをファイルにエクスポート

ffmpeg -i in.mp4 -filter:v "select='gt(scene,0.4)',showinfo" -f null - 2> scenes.log を実行すると、ログが scenes.log に保存されます。そこから pts_time(各フレームの時刻)を grep で抜き出します。

明らかなカットを見逃す

クロスフェードやフラッシュカットは、スコアが閾値に届かないことがあります。blackdetect(真っ黒な画面を見つけるフィルタ)と組み合わせると、フェードアウトも拾えます。

検出シーンで自動分割するには?

検出した時刻をスクリプトに渡し、区間ごとに ffmpeg -ss A -to B -i input.mp4 -c copy partN.mp4 を実行します。-c copy は再エンコードしない分、切れ目が A の直前のキーフレーム(単独で表示できるフレーム)の位置にずれることがあります。フレーム単位でぴったり切りたいときは、-c copy を外して再エンコードしてください。

アニメでも動く?

動きます。ただし閾値の調整が必要です。アニメは色の分布が均一なので、select なら scene のしきい値を 0.25〜0.3 まで下げると実際のカットを拾えます。scdet の t は尺度が違うので、まずデフォルトの 10 で試し、結果を見て調整してください。