ffmpeg 4.3から使えるフィルタ。映像の切り替わり、シーンチェンジの時間を調べてそのフレームを出力するのに便利なscdetフィルタの使い方。似たフィルタにselectフィルタのscenevmafmotionフィルタがあるがこれらとは計算方法が異なるが、vmafmotionフィルタのmotionスコアの値とmafdスコアの値の傾向はすごく似ている。

基本コマンド

調べた内容をコンソールとscdet.txtに出力する。
ffmpeg -i input -vf scdet,metadata=print:file=scdet.txt -an -f null -

scdet.txtの内容例。lavfiで始まるmetadataは下で解説している。

frame:0    pts:0       pts_time:0
lavfi.scd.mafd=0.000
lavfi.scd.score=0.000
frame:1    pts:2002    pts_time:0.0417083
lavfi.scd.mafd=0.026
lavfi.scd.score=0.026
:
frame:27   pts:54054   pts_time:1.12613
lavfi.scd.mafd=23.721
lavfi.scd.score=23.718
lavfi.scd.time=1.12613

調べた内容を映像に描写する。selectフィルタも併用し、‘gte(scene,0)’でシーンチェンジが0以上、つまりすべてのフレームを出力してscene-scoreも計算している。
ffplay -i input -vf scdet,select='gte(scene,0)',drawtext=y=20:fontfile=C\\://WINDOWS/Fonts/arial.ttf:fontsize=20:fontcolor=white:box=1:boxcolor=black@0.4:text='"mafd "%{metadata\:lavfi.scd.mafd}',drawtext=y=40:fontfile=C\\://WINDOWS/Fonts/arial.ttf:fontsize=20:fontcolor=white:box=1:boxcolor=black@0.4:text='"score "%{metadata\:lavfi.scd.score}',drawtext=y=60:fontfile=C\\://WINDOWS/Fonts/arial.ttf:fontsize=20:fontcolor=white:box=1:boxcolor=black@0.4:text='"time "%{metadata\:lavfi.scd.time}',drawtext=y=80:fontfile=C\\://WINDOWS/Fonts/arial.ttf:fontsize=20:fontcolor=white:box=1:boxcolor=black@0.4:text='"pts-time "%{pts\:hms}',drawtext=y=100:fontfile=C\\://WINDOWS/Fonts/arial.ttf:fontsize=20:fontcolor=white:box=1:boxcolor=black@0.4:text='"scene-score "%{metadata\:lavfi.scene_score}'

描写内容をテキストで指定する。
ffplay -i input -vf scdet,select='gte(scene,0)',drawtext=y=20:fontfile=C\\://WINDOWS/Fonts/arial.ttf:fontsize=20:fontcolor=white:box=1:boxcolor=black@0.4:line_spacing=2:textfile=scdet_drawtext.txt

ffprobeで調べる。
ffprobe -v error -f lavfi -i movie=input.mp4,scdet -select_streams v:0 -show_entries packet=pts_time -show_entries packet_tags=lavfi.scd.mafd,lavfi.scd.score,lavfi.scd.time -of csv > output.csv
ffprobe -v error -f lavfi -i movie=input.mp4,scdet -select_streams v:0 -show_entries packet=pts_time -show_entries packet_tags=lavfi.scd.mafd,lavfi.scd.score,lavfi.scd.time -of csv > output.csv

上のままだとスコアすべて出力するのでthresholdの既定値である10以上だけ出力する。
ffprobe -v error -f lavfi -i movie=input.mp4,scdet,metadata=select:key=lavfi.scd.score:value=10:function=greater -select_streams v:0 -show_entries packet=pts_time -show_entries packet_tags=lavfi.scd.score -of csv > output.csv

ffmpegから標準出力してgrepで整形する。
ffmpeg -v error -i input -vf scdet,metadata=print:file=- -an -f null - | grep mafd - > output.txt

映像の下にlavfi.scd.scoreを重ねる。映像の横幅と同じ値をsで指定する。
ffplay -i input -vf split[0],scdet,drawgraph=lavfi.scd.score:min=0:max=30:s=640x256,drawgrid=0:0:0:85,format=yuv420p,[0]vstack

全部まとめる。
ffplay -i input -vf split[0],scdet,drawgraph=lavfi.scd.score:min=0:max=30:s=640x256,drawgrid=0:0:0:85,format=yuv420p[1];[0]scdet,select='gte(scene,0)',drawtext=y=20:fontfile=C\\://WINDOWS/Fonts/arial.ttf:fontsize=20:fontcolor=white:box=1:boxcolor=black@0.4:text='"mafd "%{metadata\:lavfi.scd.mafd}',drawtext=y=40:fontfile=C\\://WINDOWS/Fonts/arial.ttf:fontsize=20:fontcolor=white:box=1:boxcolor=black@0.4:text='"score "%{metadata\:lavfi.scd.score}',drawtext=y=60:fontfile=C\\://WINDOWS/Fonts/arial.ttf:fontsize=20:fontcolor=white:box=1:boxcolor=black@0.4:text='"time "%{metadata\:lavfi.scd.time}',drawtext=y=80:fontfile=C\\://WINDOWS/Fonts/arial.ttf:fontsize=20:fontcolor=white:box=1:boxcolor=black@0.4:text='"pts-time "%{pts\:hms}',drawtext=y=100:fontfile=C\\://WINDOWS/Fonts/arial.ttf:fontsize=20:fontcolor=white:box=1:boxcolor=black@0.4:text='"scene-score "%{metadata\:lavfi.scene_score}'[0];[0][1]vstack

公式ドキュメント:FFmpeg Filters Documentation : scdet

オプション

  • threshold, t[double]
    シーンチェンジを検出するしきい値を最大変化量の%で指定する。推奨値は8から14まで。YUVの映像だとYの値が、RGBの映像だとすべてのチャンネルの係数で計算する
    既定値:10
    範囲:0から100まで
  • sc_pass, s[boolean]
    有効にするとシーンチェンジのフレームだけ出力する。シーンチェンジの画像出力で使う
    既定値:0(無効)
    範囲:0と1

sc_passの利用例

シーンチェンジを連番JPGで出力する。-anで音声無効。-vsync 0でシーンチェンジ以外のフレームを出力しない。-vframesで出力フレーム数の指定。
ffmpeg -i input -vf scdet=sc_pass=1 -an -vsync 0 -vframes 10 scenechange-%3d.jpg

連番画像のファイル名を任意の数値で指定するなら-start_numberを使う。
ffmpeg -i input -vf scdet=sc_pass=1 -an -start_number 0 -vsync 0 -vframes 10 scenechange-%3d.jpg

ffmpeg でのフレームレート設定の違い
【ffmpeg】動画から特定フレームを画像で出力する方法

メタデータキーの解説

  • lavfi.scd.mafd
    フレーム毎にmafd(Mean absolute frame difference:前後フレーム間のピクセル絶対値の平均)が指定される
  • lavfi.scd.score
    フレーム毎にシーンチェンジを検出するためのシーンチェンジスコアが指定される
  • lavfi.scd.time
    シーンチェンジを検出するためにフィルタリングされた現在のフレーム時間が指定される。シーンチェンジが検出されないと指定されない

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)