Extract images frame by frame from a video file using FFMPEG

If you need to extract images from a video you can use FFMPEG. You can extract all frames from a video file to image files. Use the following command to extract all frames from a video file called video.webm:

ffmpeg -i video.webm thumb%04d.jpg -hide_banner

We are using the parameters:

  • -i with the input file video.webm.
  • thumb%04d.jpg this is the output file. In this case it is a jpg file so ffmpeg will output jpg image files. As we have specified thumb%04d.jpg with the pattern "%04d" inside the file name, FFMPEG will extract a serie of images thumb0000.jpg, thumb0001.jpg, thumb0002.jpg, thumb0003.jpg and so on... We are indicating ffmpeg to output files with 4 decimal numbers with the "%04d" pattern but we can also use more numbers (for example to use 6 decimal numbers we can change the pattern to "%06d".
  • -hide_banner we are using this parameter to hide ffmpeg compilation information.

In this example we used jpg files as output, but we can also use another formats like png or bmp. Anyway I recommend and I usually work with jpg files as they offer good quality images in a reduced disk space.

Warning: If we use this command to extract all frames from a long video, we can obtain hundreds or even thousands of images. It can be a disk space problem or even a system problem to handle all these files.

Extract only one frame

Since working with all those images can not be a comfortable process, it is usually more practical to extract a single video image. And in this case it is better to take an image from the most important part of the video.

So imagine that in the same video file called video.webm, we want to extract an image in the seventh second of the video, as we think it is the most important part of the video. We can use ffmpeg to extract a frame from that moment with the following command:

ffmpeg -i video.webm -ss 00:00:07.000 -vframes 1 thumb.jpg

We are using new parameters:

  • -ss we are using this parameter with a time (00:00:07.000 is the second 7 from the video in this case). This parameter makes ffmpeg to seek for that second to start its processing, so it will extract frames from that moment.
  • -vframes with this parameter we are telling ffmpeg the number of frames to extract (1 in this case). FFMPEG will extract only one image and it will use thumb.jpg as output file. You might notice that in this case we are not using a pattern like "%04d" as we are extracting only one frame.

Sometimes we check the quality of the images and we find that they have not the quality we want (extracting frames from video files could result in some low quality frames, as they appear pixelated). It may be a good idea to extract more than one frame from the important part of the video. We can use the following command:

ffmpeg -i video.webm -ss 00:00:07.000 -vframes 3 thumb%04d.jpg -hide_banner

Notice that this time we are using the pattern "%04d" for the output file as we are asking to extract 3 frames, so we are getting 3 jpg images. With this command we would obtain the first 3 frames from the video after ffmpeg seeks for the second 7 of the video.

Extract frames in a regular time basis

Another method that can be used to extract images from a video file, is to extract an image every X seconds. With this method we do not get as many files as in the first case in which we extracted all images from a video file, and we do not limit ourselves to choose images only from a particular moment of the video.

We can get one frame every second from the video file called video.webm using the following command:

ffmpeg -i video.webm -vf fps=1 thumb%04d.jpg -hide_banner

In this example we used one new parameter:

  • -vf this parameter is used to apply video filters with ffmpeg. We can use a lot of filters. In this example we are using "fps=1" so ffmpeg will filter the video and extract one image (1 frame per second) for the output. As ffmpeg will be extracting multiple files we are using thumb%04d.jpg (with the pattern "%04d") as output file.

So we get a jpg image for each second of the video file, thumb0000.jpg, thumb0001.jpg, thumb0002.jpg (and so on)

We have used this filter to extract one image per second, but we can use it to extract images with other periodicity. We can extract one image every 5 seconds (as a website can do to extract some images as a video summary) with the following command:

ffmpeg -i video.webm -vf fps=1/5 thumb%04d.jpg -hide_banner

In this example we are indicating ffmpeg to use a video filter "fps=1/5" so it will extract one frame every 5 seconds. We can change this parameter to extract a frame every 10 seconds "fps=1/10", or every minute "fps=1/60" that would be ideal for longer videos.

Extract all keyframes from a video file

As a last variant of this article we will show you how to extract all keyframes from a video file.

Keyframes (sometimes called index frames) are pictures that are used as a reference in video files. Keyframes concept is a little more complex, but as a summary we can say that they are used as reference so video players can seek them easily, and they serve as reference to the following frames so video codecs can compress video storing differences between keyframes and the following frames instead of storing all frames.

That is why we can expect better image quality on this frames.

Time period between keyframes depends on the video file (it also depends on the video codec used). Keyframe configuration can be changed when we create a video file so it may vary depending on the configuration that the video author used to create the video. The period is usually between 2 and 5 seconds.

To extract the keyframes from a video file using ffmpeg we can use the following command:

ffmpeg -i video.webm -vf "select=eq(pict_type\,I)" -vsync vfr thumb%04d.jpg -hide_banner

We are using parameters:

  • -vf we are using a video filter here. In this case the video filter is a bit more complex than before. We are using "select=eq(pict_type\,I)" which will make the filter to select all images that are keyframes. ("pict_type\,I" refers to Index picture type, "eq" refers to equal, so we can read it as "select all equal to index images")
  • -vsync vfr: This is a parameter that tells the filter to use a variable bitrate video synchronization. If we do not use this parameter ffmpeg will fail to find only the keyframes and shoud extract other frames that can be not processed correctly.

In our case we have extracted 6 images from a 14 seconds video (so the video has a keyframe every 2 seconds) but as we have said before, this varies depending on the video file.

    Did you find this article helpful?