Jump to content

FFMPEG An Intermediate Guide/image sequence

From Wikibooks, open books for an open world

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

Overview

[edit | edit source]

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 image-%03d.png part is a filename pattern. This particular pattern corresponds to image-000.png, image-001.png, image-002.png up to image-999.png. The "%03d" 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 -f image2 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

[edit | edit source]
 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

[edit | edit source]

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 -start_number 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

[edit | edit source]

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 -framerate 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

[edit | edit source]

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

[edit | edit source]

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


Creating mp4[1]

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

[edit | edit source]
 ffmpeg -i video.webm image-%03d.png

This will extract 25 images per second from the file video.webm and save them as image-000.png, image-001.png, image-002.png up to image-999.png. 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

[edit | edit source]

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:

pattern type corresponding filenames description
image-%03d.png
 image-000.png
 image-001.png
 image-002.png
 ...
 image-999.png
Numbered with leading zeroes
image-%d.png
 image-1.png
 image-2.png
 ...
 image-9.png
 image-10.png
 image-11.png
 ...
 image-99.png
 image-100.png
 ...
Numbered without leading zeroes
image-*.png

(needs an argument to enable)

 image-a.png
 image-b.png
 image-c.png
 ...
 image-foo.png
 image-bar.png
 ...
 image-.png
 ...
Not numbered or no regular pattern

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

[edit | edit source]

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 image- followed by three digits followed by the string .png.

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

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

Note: the %0Nd 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

[edit | edit source]

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

[edit | edit source]

If the number in the filenames are not padded with leading zeroes then the pattern is %d.

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

[edit | edit source]

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 -pattern_type glob. 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 image- followed by anything followed by the string .png.

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

[edit | edit source]

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 image-bar.png is the second filename argument while video.webm 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

[edit | edit source]

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. 015 clearly comes before 110. Without leading zeroes things get a bit more complicated. Most computers will sort 15 after 110. But this problem is solved by the %d notation.

When the files are no longer numbered or not regularly then things can get very strange. For example should ae sort before or after aaa? 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 LC_COLLATE. 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 %0Nd pattern.

References

[edit | edit source]

The fine ffmpeg manual and wiki located at:

More specific the following pages:

  1. fractalforums.org : creating-a-video