Create a video (using the encoder libx264) from series of numerically sequential images such as img001.png, img002.png, img003.png, etc.
You can specify two frame rates:
- The rate according to which the images are read, by setting -framerate before -i. The default for reading input is -framerate 25 which will be set if no -framerate is specified.
- The output frame rate for the video stream by setting -r after -i or by using the fps filter. If you want the input and output frame rates to be the same, then just declare an input -framerate and the output will inherit the same value.
By using a separate frame rate for the input and output you can control the duration at which each input is displayed and tell ffmpeg the frame rate you want for the output file. If the input -framerate is lower than the output -r then ffmpeg will duplicate frames to reach your desired output frame rate. If the input -framerate is higher than the output -r then ffmpeg will drop frames to reach your desired output frame rate.
In this example each image will have a duration of 5 seconds (the inverse of 1/5 frames per second). The video stream will have a frame rate of 30 fps by duplicating the frames accordingly:
ffmpeg -framerate 1/5 -i img%03d.png -c:v libx264 -r 30 -pix_fmt yuv420p out.mp4
Starting with a specific image
For example if you want to start with img126.png then use the -start_number option:
ffmpeg -framerate 1/5 -start_number 126 -i img%03d.png -c:v libx264 -r 30 -pix_fmt yuv420p out.mp4
If your video does not show the frames correctly
If you encounter problems, such as the first image is skipped or only shows for one frame, then use the fps video filter instead of -r for the output framerate (see ticket:1578 and ticket:2674 / ticket:3164 for more info):
ffmpeg -framerate 1/5 -i img%03d.png -c:v libx264 -vf fps=25 -pix_fmt yuv420p out.mp4
ffmpeg -framerate 1/5 -i img%03d.png -c:v libx264 -vf "fps=25,format=yuv420p" out.mp4
Color space conversion and chroma sub-sampling
By default when using libx264, and depending on your input, ffmpeg will attempt to avoid color subsampling. Technically this is preferred, but unfortunately almost all video players, excluding FFmpeg based players, and many online video services only support the YUV color space with 4:2:0 chroma subsampling. Using the options -pix_fmt yuv420p or -vf format=yuv420p will maximize compatibility.
Using a glob pattern
ffmpeg also supports bash-style globbing (* represents any number of any characters). This is useful if your images are sequential but not necessarily in a numerically sequential order as in the previous examples.
ffmpeg -framerate 1 -pattern_type glob -i '*.jpg' -c:v libx264 out.mp4
For PNG images:
ffmpeg -framerate 1 -pattern_type glob -i '*.png' -c:v libx264 -pix_fmt yuv420p out.mp4
Using a single image as an input
If you want to create a video out of just one image, this will do (output video duration is set to 30 seconds with -t 30):
ffmpeg -loop 1 -i img.png -c:v libx264 -t 30 -pix_fmt yuv420p out.mp4
If you want to add audio (e.g. audio.wav) to one "poster" image, you need -shortest to tell it to stop after the audio stream is finished. The internal AAC encoder is used in this example, but you can use any other supported AAC encoder as well:
ffmpeg -loop 1 -i img.jpg -i audio.wav -c:v libx264 -c:a aac -strict experimental -b:a 192k -shortest out.mp4
If your audio file is using a codec that the output container supports (e.g. MP3 audio in AVI or M4A/AAC audio in MP4), you can copy it instead of re-encoding, which will preserve the audio quality:
ffmpeg -loop 1 -i img.jpg -i audio.m4a -c:v libx264 -c:a copy -shortest out.mp4