ffmpeg 4.3から使えるフィルタ。映像の切り替わり、シーンチェンジの時間を調べてそのフレームを出力するのに便利なscdet
フィルタの使い方。似たフィルタにselect
フィルタのsceneとvmafmotion
フィルタがあるがこれらとは計算方法が異なるが、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
- ffprobe の使い方
- 文字を描写する drawtext
- 一定間隔で映像に線を引く drawgrid
- 新しい映像の動きの評価 vmafmotion
- メタデータを映像化する drawgraph, adrawgraph
- メタデータをコンソールに表示する metadata, ametadata
- 特定の映像フレームや音声サンプルを出力する select, aselect
公式ドキュメント: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
シーンチェンジを検出するためにフィルタリングされた現在のフレーム時間が指定される。シーンチェンジが検出されないと指定されない