I want to extract the keyframes of a video by ffmpeg and determine if each keyframe is blurred or not using a predefined thershold. I noticed the new blurdetect
filter in ffmpeg5, so I tried the following command:
ffmpeg -i test.mp4 -filter_complex "select=eq(pict_type,I),blurdetect=block_width=32:block_height=32:block_pct=80" -vsync vfr -qscale:v 2 -f image2 ./I_frames_ffmpeg/image%08d.jpg
Using this command I can get the keyframes and at the end in the terminal I can see the average blur value of those frames being printed out. blur mean
My question is, can I use the blurdetect
filter to get the blur value for each frame? Can I use this blur value as a precondition for keyframe selection, e.g. only select this frame as a keyframe if the blur value is less than 5?
Yes, blurdetect
filter pushes the blur value of each frame to stream metadata, which you can capture with metadata
filter. Try the following filtergraph:
select=eq(pict_type,I),\
blurdetect=block_width=32:block_height=32:block_pct=80,\
metadata=print:file=-
The metadata
filter outputs to stdout, so you'll see 2 lines for each frame like:
frame:1295 pts:1296295 pts_time:43.2098
lavfi.blur=4.823009
Note that the terminal may get cluttered with other logs, but these lines should be the only lines actually on stdout (standard logs are on stderr) so you should be able to capture easily. From there a simple regex should help you retrieve the blur values.
Can I use this blur value as a precondition for keyframe selection, e.g. only select this frame as a keyframe if the blur value is less than 5?
I believe (not verified) that metadata
filter can do exactly this:
metadata=select:key=lavfi.blur:value=5:function=less
Not the best documentation, but it's all there