FFMPEG An Intermediate Guide/image sequence

FFMPEG has a powerful set of features relating to creating video from images, or generating an image sequence from a video.

Overview
To create a video from a set of images:

ffmpeg -i image-%03d.png video.webm

To create a set of images from a video:

ffmpeg -i video.webm image-%03d.png

When no further arguments are given a set of defaults will be used. For example the framerate will be 25 and the encoding will be inferred from the filenames.

The  part is a filename pattern. This particular pattern corresponds to,  ,   up to. The " " represents a sequence of three, zero-padded, decimal digits. There is more to know about filename patterns which will explained in a later section.

The canonical form to work with image sequences is to use the  argument like this:

ffmpeg -f image2 -i image-%03d.png video.webm

and

ffmpeg -i video.webm -f image2 image-%03d.png

But ffmpeg is very good with inferring that information so this chapter will omit that argument in all examples unless absolutely necessary.

↙

Making a video from an Image Sequence
ffmpeg -i image-%03d.png video.webm

This will create a video with the filename video.webm from the image files named image-000.png, image-001.png, image-002.png, up to the last sequentially numbered three digit image file.

The encoding of the images and of the video is inferred from the extensions. The framerate is 25 fps by default. The video width and height is taken from the images. The images have to be all of the same dimension.

Filename numbering
Ffmpeg expects the numbering to start at 0 (or 000 in this example). If your files do not start at 000 then use the argument  to tell ffmpeg the first number of your files:

ffmpeg -start_number 100 -i image-%03d.png video.webm

The same argument can be used to skip over a number of files and start at a certain number.

The numbering has to be consecutive. Ffmpeg will stop at the last consecutive numbered filename.

For example if you have following files:

image-000.png image-001.png image-002.png image-005.png

Then ffmpeg will only process the first three and ignore the last file. If you have missing numbers you can use a glob pattern or rename all the remaining files to close the gap.

Framerate
The default framerate is 25 fps. That means each image is shown 1/25 of a second. This is a speed which creates the illusion of a smooth animation for most humans eyes. If you still want more frames per second then use the  argument:

ffmpeg -framerate 60 -i image-%03d.png video.webm

If you want to have a slideshow then you have to lower the input framerate. The following command will show each image 5 seconds long:

ffmpeg -framerate 1/5 -i image-%03d.png video.webm

It may be necessary to force the video framerate up:

ffmpeg -framerate 1/5 -i image-%03d.png -r 30 video.webm

Slideshow with different durations
You can make a slideshow with different duration for each picture, by using the zoompan filter. In the following example each picture is shown 1 second (25 frames), except the 4th picture (the enumeration start with 0) is shown 3 seconds (25+50 frames) and the 6th picture is shown 5 seconds (25+100 frames):

ffmpeg -i image-%3d.jpg -vf "zoompan=d=25+'50*eq(in,3)'+'100*eq(in,5)'" test.mp4

Slideshow with crossfading between the pictures
You can make a slideshow with crossfading between the pictures, by using a combination of the zoompan and framerate filters. "A" is the duration in seconds how long each picture is shown (without the crossfade duration), and "B" is the crossfade duration in seconds.

* This example is completely broken and only includes the first 3 images*

ffmpeg -i IMG_%3d.jpg -vf zoompan=d=(A+B)/B:fps=1/B,framerate=25:interp_start=0:interp_end=255:scene=100 -c:v mpeg4 -maxrate 5M -q:v 2 out.mp4

mp4
Creating mp4 ffmpeg -framerate 60 -r 60 -i image%06d.png -pix_fmt yuv420p -profile:v high -level:v 4.1 -crf:v 20 -movflags +faststart output.mp4


 * for other than 60 fps, change framerate and r
 * input is image000001.png, image000002.png, ..., %06d means a zero-padded number with six digits, change if your input images are named differently
 * -pix_fmt yuv420p is required for compatibility with most players (default is yuv444 or maybe even rgb, which most players don't handle well if at all)
 * -profile:v, -level:v also control compatibility settings, 4k probably needs a higher level setting
 * -crf:v is the quality-vs-size control, lower numbers are higher quality larger file size, higher numbers are lower quality smaller file size, crf 20 is pretty high quality, iirc changing by 6 affects the file size by a factor of 2
 * -movflags +faststart is required for streaming (otherwise the whole file has to be downloaded before playback can start)
 * ffmpeg can also add/encode a soundtrack if you want one

Making an Image Sequence from a video
ffmpeg -i video.webm image-%03d.png

This will extract 25 images per second from the file video.webm and save them as,  ,   up to. If there are more than 1000 frames then the last image will be overwritten with the remaining frames leaving only the last frame.

The encoding of the images and of the video is inferred from the extensions. The framerate is 25 fps by default. The images width and height is taken from the video.

Extract one image per second:

ffmpeg -i video.webm -vf fps=1 image-%03d.png

Extract one image from a specific time:

ffmpeg -i video.webm -ss 00:00:10 -vframes 1 thumbnail.png

Filename patterns
Usually ffmpeg has one input file and one output file, but when we want to create a video from a set of image then we have a set of input files. Likewise, when extracting images from a video file there is a set of output files. A filename pattern is a pseudo filename to describe a set of filenames.

There are roughly three types of filename patterns:

Technically there is a fourth form: the single image form. But that is a trivial special case and will not be discussed further in this section.

Numbered with leading zeroes
This pattern:

image-%03d.png

Corresponds to the following filenames:

image-000.png image-001.png image-002.png ... image-999.png

In words: the string  followed by three digits followed by the string.

The heart of the filename expansion mechanism is the substring starting at the character  and ending at the character. Everything before the  and after the   is taken literally. Everything from  to   is replaced by one or more digits.

The general form is  where   is a number larger than zero which determines how many digits there are.

Note: the  notation is commonly used in many programming languages. The notation is so complex because it is designed to accommodate many different use cases. The ffmpeg developers borrowed the notation and stripped it down to just one use case: how many digits. That is why it may seem unnecessarily complex.

Percent in filename
There is a special case if the filenames itself contains the  character. Because the  character has a special meaning in the pattern care has to be taken. A single  character in the pattern will be interpreted as the beginning of the substring to be replaced by digits. To specify a literal  the character has to be doubled in the pattern. The technical jargon for this is to "escape" the character.

For example this pattern:

image-%02d%%.png

Corresponds to the following filenames:

image-00%.png image-01%.png image-02%.png ... image-99%.png

Numbered without leading zeroes
If the number in the filenames are not padded with leading zeroes then the pattern is.

This pattern:

image-%d.png

Corresponds to the following filenames:

image-1.png image-2.png ... image-9.png image-10.png image-11.png ... image-99.png image-100.png ...

Not numbered or no regular pattern
If the filenames are not numbered using digits or are otherwise not formated regularly then one can use the glob pattern. Glob patterns must be enabled using the argument. Note that this is not supported on Windows.

Example ffmpeg command with glob pattern enabled:

ffmpeg -pattern_type glob -i "image-*.png" video.webm

This pattern:

"image-*.png"

Corresponds to the following filenames:

image-a.png image-b.png image-c.png

but also to the following filenames:

image-foo.png image-bar.png

and also to:

image-.png

and to any filename which follows the pattern string  followed by anything followed by the string.

Generally the pattern  corresponds to anything of any length and that means even nothing.

There are more glob patterns. For example  which corresponds to any single character. But we will not go in to more details here. The interested reader can read more in depth information in the wikipedia page about glob (programming).

Quote the glob pattern
It is necessary to place the glob pattern in quotes otherwise the shell will expand the glob before executing the command.

For example the glob pattern in this command:

ffmpeg -pattern_type glob -i image-*.png video.webm

will be expanded by the shell to:

ffmpeg -pattern_type glob -i image-foo.png image-bar.png video.webm

before it is executed. Note that this command has a different meaning because now  is the second filename argument while   is a third filename argument.

When placed in quotes the shell will not expand the glob pattern:

ffmpeg -pattern_type glob -i "image-*.png" video.webm

Order of files from glob pattern
Numbered files have a clearly defined ordering. For the most part humans and computers alike agree how to sort the numbers. This is especially true for numbers with leading zeroes. clearly comes before. Without leading zeroes things get a bit more complicated. Most computers will sort  after. But this problem is solved by the  notation.

When the files are no longer numbered or not regularly then things can get very strange. For example should  sort before or after  ? Computers are deterministic and always have an idea of how to sort things, but that idea of order does not necessarily makes sense for a human.

The order of the files from a glob pattern is determined by the glob system call. On most systems the idea of order of the glob system call can be manipulated using an environment variable named. But this book will not discuss that.

For small number of files the order returned by a glob can be inspected by letting a shell expand the glob. This works because most shells uses the same glob system call as ffmpeg would.

This command typed in a shell:

echo image-*.png

will print a list of filenames. That same list in the same order will be the list of files processed by ffmpeg if given the glob pattern.

If the order is not satisfactory or the number is too large to inspect by humans then the best course of action is to rename the files to be regularly numbered and then use the  pattern.