DEV Community

Javid Jamae
Javid Jamae

Posted on • Originally published at ffmpeg-micro.com

How to Create a Video from Images with FFmpeg

Originally published at ffmpeg-micro.com

Turning a folder of images into a playable video file is one of the most common FFmpeg tasks. Product screenshots for a demo reel, AI-generated frames for a social post, timelapse photos from a construction site. The command is short but the flags trip people up, especially -pix_fmt, -framerate, and image naming patterns.

FFmpeg can convert a numbered image sequence into an H.264 MP4 with one command.

The Basic Command: Image Sequence to MP4

If your images are named with sequential numbers (frame_001.png, frame_002.png, etc.):

ffmpeg -framerate 1 -i frame_%03d.png -c:v libx264 -pix_fmt yuv420p -r 30 output.mp4
Enter fullscreen mode Exit fullscreen mode

What each flag does:

  • -framerate 1 tells FFmpeg to read one image per second. Change to 2 for half-second images, or 1/5 for five seconds per image.
  • -i frame_%03d.png is the input pattern. %03d matches zero-padded three-digit numbers.
  • -c:v libx264 encodes with H.264, the most widely supported video codec.
  • -pix_fmt yuv420p forces a pixel format compatible with every browser and player.
  • -r 30 sets the output frame rate to 30fps for smooth playback.

With 5 input images at -framerate 1, the output is a 5-second video.

Using Glob Patterns Instead of Numbered Files

ffmpeg -framerate 1 -pattern_type glob -i '*.png' -c:v libx264 -pix_fmt yuv420p -r 30 output.mp4
Enter fullscreen mode Exit fullscreen mode

FFmpeg sorts glob matches alphabetically. Rename files with a numeric prefix if the order matters. Glob patterns work on macOS and Linux only.

One Image, Specific Duration

ffmpeg -loop 1 -i title-card.png -c:v libx264 -t 10 -pix_fmt yuv420p -r 30 output.mp4
Enter fullscreen mode Exit fullscreen mode

-loop 1 keeps reading the same image. -t 10 sets 10 seconds of output.

Controlling Quality with CRF

ffmpeg -framerate 1 -i frame_%03d.png -c:v libx264 -pix_fmt yuv420p -crf 18 -r 30 high_quality.mp4
ffmpeg -framerate 1 -i frame_%03d.png -c:v libx264 -pix_fmt yuv420p -crf 28 -r 30 small_file.mp4
Enter fullscreen mode Exit fullscreen mode

For 5 images at 640x360, CRF 18 produces a 176KB file. CRF 28 produces 61KB, a 2.9x size reduction. For product screenshots, stay between 18 and 22. For social media, 23 to 28 is fine.

Common Pitfalls

Dimensions must be even. H.264 requires width and height divisible by 2. Fix with -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2".

Alpha channels in PNGs cause playback failures. Always use -pix_fmt yuv420p.

Numbering gaps skip images. FFmpeg stops at gaps. Switch to a glob pattern.

Framerate confusion: -framerate (before -i) controls input read rate. -r (after -i) controls output frame rate.

FAQ

What image formats does FFmpeg support? JPEG, PNG, BMP, TIFF, WebP, and most standard formats.

How do I control duration per image? -framerate 1 = 1 second. -framerate 1/3 = 3 seconds per image.

Can I add transitions? Yes. FFmpeg's xfade filter supports 40+ transition styles.

Read the full post with API examples at ffmpeg-micro.com.

Top comments (0)