この記事でわかること
scdetフィルタでシーンチェンジを検出するコマンド- 検出感度
threshold(t)の調整方法 - 各シーンのタイムスタンプをメタデータから取得する方法
selectフィルタと組み合わせたシーン先頭フレームの抽出- シーンチェンジ点のサムネイル一括生成
テスト済みバージョン: FFmpeg 6.1で確認済み(検証スクリプトで実 FFmpeg 実行確認) 対象 OS: Windows / macOS / Linux
基本コマンド
ffmpeg -i input.mp4 \
-vf "scdet=t=10,metadata=mode=print:key=lavfi.scd.score" \
-f null /dev/null
-f null /dev/null で出力ファイルを生成せず、metadata=print で検出情報を標準エラー出力に表示します。
出力の読み方
[Parsed_metadata_1 @ 0x...] lavfi.scd.score=18.3
[Parsed_metadata_1 @ 0x...] lavfi.scd.time=4.96
[Parsed_metadata_1 @ 0x...] lavfi.scd.score=32.7
[Parsed_metadata_1 @ 0x...] lavfi.scd.time=23.42
| フィールド | 説明 |
|---|---|
lavfi.scd.score | シーンチェンジスコア(高いほど変化が大きい) |
lavfi.scd.time | 検出時刻(秒) |
threshold(感度)の調整
| パラメータ | デフォルト | 説明 |
|---|---|---|
t / threshold | 10 | この値以上のスコアをシーンチェンジとして報告 |
ffmpeg -i input.mp4 -vf "scdet=t=20" -f null /dev/null
- 低い値(例: 5): 細かな変化も検出(誤検出増)
- 高い値(例: 40): 明確なカットのみ検出(見逃し増)
- ドキュメンタリーや映画:
10〜20が目安
シーンチェンジ点のフレームを画像として保存
select フィルタと組み合わせて、シーンが変わった瞬間のフレームを画像として保存します:
ffmpeg -i input.mp4 -vf "select='gt(scene,0.35)'" -vsync vfr scene_%04d.png
注意:
selectのsceneはselectフィルタ側のシーンスコアです。scdetのlavfi.scd.scoreとは別の値なので、しきい値も別に調整します。
metadata フィルタでタイムスタンプを確認
ffmpeg -i input.mp4 -vf "scdet=t=10,metadata=print" -f null /dev/null
用途別のthreshold設定例
| 用途 | 推奨 threshold |
|---|---|
| 映画のカット検出 | 8〜15 |
| スポーツ映像 | 15〜25 |
| アニメーション | 10〜20 |
| 監視カメラ映像 | 5〜10 |
| スライドショー動画 | 30〜50 |
よくある注意点
フェードやディゾルブは検出精度が低い
ハードカット(瞬間的な場面転換)は高精度で検出できますが、フェードやディゾルブ(徐々に変化)は scdet では誤検出しやすいです。
長い動画では処理時間がかかる
シーン検出は全フレームをデコードするため、長尺動画では時間がかかります。-ss と -to で部分的に解析することも可能です。
実測例
1080p/30fps、2分の H.264 動画を scdet で解析する場合、出力動画を作らないため再エンコードは発生しません。
ffmpeg -i input.mp4 \
-vf "scdet=t=12,metadata=mode=print:key=lavfi.scd.time" \
-f null /dev/null
処理時間はデコード速度に近く、8コア程度のデスクトップ環境では実時間より速く終わることもあります。ただし4K素材、10bit HEVC、ネットワーク上の入力ファイルでは大きく遅くなる場合があります。
シーンフレームをPNGで保存する場合は、検出に加えて画像エンコードとディスク書き込みが発生します。大量のカットを検出する動画では、PNG出力の方がボトルネックになることがあります。環境により変動します。
検出結果を編集点として使う場合は、ログの時刻をそのまま -ss に渡す前に、前後0.2〜0.5秒の余白を取ると失敗が減ります。シーン検出は映像の変化点を拾うだけで、音声の切れ目や字幕のタイミングまでは考慮しません。自動分割では短いクリップが大量にできることもあるため、最小尺のフィルタリングをスクリプト側で入れると扱いやすくなります。
カメラのフラッシュ、画面全体の白フェード、ゲーム画面の暗転は、実際のカットでなくても高いスコアになることがあります。検出結果を完全自動で使う前に、代表的な数分だけ手動確認してしきい値を決めてください。
関連リソース
よく使うオプション・フィルタ・コーデック設定をまとめた PDF チートシートです。手元に置いておくと調べる時間を短縮できます。
関連記事
動作確認: ffmpeg 6.1 / Ubuntu 24.04 (検証スクリプトで実行確認) 一次ソース: ffmpeg.org/ffmpeg-filters.html#scdet / ffmpeg.org/ffmpeg-filters.html#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 後に pts_time を grep。
明らかなカットを見逃す
クロスフェード / フラッシュカットが閾値の下に隠れる場合があります。blackdetect と組み合わせるとフェードアウト系も拾える。
検出シーンで自動分割するには?
はい — タイムスタンプを wrapper スクリプトに渡し、各範囲に ffmpeg -ss A -to B -c copy partN.mp4 を実行する流れ。
アニメでも動く?
はい、ただし閾値を調整。アニメは色分布が均一なため、0.25〜0.3 まで下げるとリアルなカットが拾えます。