How to take screenshots with FFmpeg

With FFmpeg, you can export an image of a specific point in time in the video. You can specify the point in time with a time code or a frame number.

How to take a screenshot

We can use the seek option to set a point in time to specify what we want a still image of.

ffmpeg -ss 00:07:35 -i input.mkv -vframes 1 00-07-35.png

The time code here (-ss 00:07:35) is hours:minutes:seconds. This is probably the fastest and easiest way to take a screenshot.

How to take a screenshot using a frame number

We can also export the same image by specifying the exact frame at a given time. Let’s calculate the frame number for 00:07:35, shall we? The point in the video is 7 minutes and 35 seconds, right? That equals to is 455 seconds in the video (60*7+35). Since the video is playing at 23.976 frames per second we need to multiply the seconds we have with the FPS. This gives us the frame number: 10909.

(7*60+35)*23,976=10909,08
(7,35 minutes in seconds)*(frame rate of video)

You can also use a frame calculator if you think that is easier. So now we can easily export frame 10909 with:

ffmpeg -i input.mkv -vf select=gte(n\,10909) -vframes 1 frame-10909.png

-i is your video file input. -vf select=gte(n\,10909) tells FFmpeg to start at the 10909th frame. -vframes 1 sets the number of video frames to output. frame-10909.png generates the file name.

How to take a screenshot every # second

Note that this way of exporting images is very slow and I suspect that this is either a bug in FFmpeg or something that has not been paid much attention to.

If you want to export an image from the video every 10 seconds, you would use fps=1/10.

If you want to export an image every 1 hour and 23 minutes you will have to calculate that in seconds (which is 60 minutes + 23 minutes * 60=4980). Then you can use fps=1/4980.

ffmpeg -i input.mkv -vf fps=1/1800 %04d.bmp

Here are some time examples:

  • Every second: fps=1
  • Every ten seconds: fps=1/10
  • Every minute: fps=1/60
  • Every ten minutes: fps=1/600
  • Every five minutes: fps=1/300
  • Every 15 minutes: fps=1/900

There are many ways you can name the output files. Here are some examples:

Filename patterns:

  • video-%03d.png = video-000.png, video-001.png…
  • video-%d.png = video-1.png, video-2.png…
  • video-*.png = video-a.png, video-b.png…

Note: You can of course change the file extension to something different. I like to use PNG because it is lossless. However if you do not care about the quality you can use, for example:

ffmpeg -i input.mkv -qscale:v 2 %04d.jpg

Taking screenshots from all videos in a folder

The following code will use FFmpeg to take screenshots from every video file in a folder at the given time codes and save them as PNG files.

It will name the images according to the video file names and append the time code as a prefix to the file name.

This is great for comparing video quality for multiple videos, without having to load up each video side by side.

Here is the example for Windows Command Prompt.

for /r %i in (*.mp4) do (
ffmpeg -ss 00:00:01.710 -i "%i" -vframes 1 00.00.01.710-"%~ni".png
ffmpeg -ss 00:00:02.574 -i "%i" -vframes 1 00.00.02.574-"%~ni".png
ffmpeg -ss 00:00:07.920 -i "%i" -vframes 1 00.00.07.920-"%~ni".png
ffmpeg -ss 00:00:09.062 -i "%i" -vframes 1 00.00.09.062-"%~ni".png
ffmpeg -ss 00:00:10.996 -i "%i" -vframes 1 00.00.10.996-"%~ni".png
ffmpeg -ss 00:00:12.301 -i "%i" -vframes 1 00.00.12.301-"%~ni".png
ffmpeg -ss 00:00:18.506 -i "%i" -vframes 1 00.00.18.506-"%~ni".png
ffmpeg -ss 00:00:20.905 -i "%i" -vframes 1 00.00.20.905-"%~ni".png
)

Sources:

FFmpeg Wiki: Seeking

FFmpeg Wiki: Create a thumbnail image every X seconds of the video

FFMPEG An Intermediate Guide/image sequence

Thumbnails (iframe / scene change) – 2018

Leave a Reply

Your email address will not be published. Required fields are marked *