I know how to extract a set of frames as jpg files from a video using ffmpeg if you know the frame numbers (given below)
Extracting Frames: [40, 59, 73, 110]
/usr/bin/ffmpeg -y -hide_banner -nostats -loglevel error -i /home/pi/movie.mp4 -vf select='eq(n\,40)+eq(n\,59)+eq(n\,73)+eq(n\,110)',scale=640:-1 -vsync 0 /tmp/%04d.jpg
That will extract frames [40, 59, 73, 110] as files /tmp/0000.jpg, /tmp/0001.jpg, etc.
I also know how to extract all key frames for a given time interval:
ffmpeg -ss <start_time> -i video.mp4 -t <duration> -q:v 2 -vf select="eq(pict_type\,PICT_TYPE_I)" -vsync 0 frame%03d.jpg
That will get all I-frames from start_time
through start_time+duration
.
But what I would like to do is give a list of frame numbers and have ffmpeg extract the closest key-frames to each frame-number. Is there a way to do this with ffmpeg or would I have to write my own program ontop of libavcodec to do this?
First we need some test data. Note you can skip to the FFmpeg commands if you are doing this yourself; this is just how I came about the final commands:
Now let us find the largest window:
Running this yields 240, which means the radius is 120. If our target frame is 1000:
If our targets frames are 1000 and 2000:
http://ffmpeg.org/ffmpeg-utils.html#Expression-Evaluation