FFmpeg is extremely useful for combining photos into a slideshow video or creating a timelapse from a long-duration recording. Here are the commands verified with FFmpeg 6.1, organized by use case.


Sequential PNG → Video (Slideshow)

Generate a video from a series of sequentially numbered image files such as img001.png, img002.png.

ffmpeg -framerate 1 -i img%03d.png -c:v libx264 output.mp4

The sequential pattern like %03d is shown in a text block as it falls outside CI rewrite rules.

  • -framerate 1 — Sets the input frame rate to 1fps (1 second per image)
  • -i img%03d.png — Reads img001.png, img002.png, … in order
  • %03d is zero-padded 3 digits (use %04d for 4 digits)

Making the slideshow smoother:

Increasing the frame rate makes playback smoother. However, if there aren’t enough images the video will be short, so also specify -r 25 for the output frame rate.

ffmpeg -framerate 1 -i img%03d.png -c:v libx264 -r 25 output.mp4

In this case, converting 1fps input (1 image per second) to 25fps output causes each frame to repeat 25 times, resulting in smooth playback.


Single Image → Short Video (Loop)

To turn a single image into a video of a specified duration, combine -loop 1 with -t.

ffmpeg -loop 1 -i image.png -t 5 -c:v libx264 output.mp4
  • -loop 1 — Loop the input stream infinitely
  • -t 5 — Limit the output video length to 5 seconds
  • image.png is included in KNOWN_EXTS so it can be used in bash blocks

The Importance of pix_fmt yuv420p

When encoding with libx264, the default pix_fmt depends on the source image. For PNG files, it may become yuv444p or rgba, which can prevent playback in QuickTime (macOS player) or some mobile devices.

Always add -pix_fmt yuv420p when compatibility is important:

ffmpeg -loop 1 -i image.png -t 3 -c:v libx264 -pix_fmt yuv420p output.mp4

yuv420p is the most widely supported color space format. At the cost of a slight quality reduction, it ensures playback compatibility in virtually all environments.


Timelapse (Frame Dropping from Video)

Create a high-speed playback video (timelapse) by dropping frames from an existing video. Use -vf fps=1/N to extract “one frame every N seconds”, which at normal playback speed results in an N× speed timelapse.

ffmpeg -i input.mp4 -vf fps=1/10 output.mp4
  • -vf fps=1/10 — Extract one frame every 10 seconds (results in a 10× speed timelapse)
  • If the original video is 60 minutes, the output will be approximately 6 minutes

Speed reference:

-vf fps= valueDrop intervalSpeed
fps=1/51 frame per 5 seconds5× speed
fps=1/101 frame per 10 seconds10× speed
fps=1/301 frame per 30 seconds30× speed
fps=1/601 frame per minute60× speed

It is also recommended to add -pix_fmt yuv420p here for compatibility:

ffmpeg -i input.mp4 -vf fps=1/10 -c:v libx264 -pix_fmt yuv420p output.mp4

Sequential JPG → Video (From Timelapse Source Material)

To create a video from sequential JPEGs obtained by interval shooting with a camera:

ffmpeg -framerate 24 -i photo%04d.jpg -c:v libx264 -pix_fmt yuv420p output.mp4

%04d handles 4-digit zero-padded sequential names like photo0001.jpg, photo0002.jpg, …

Specifying a start number (e.g., starting from photo0100.jpg):

ffmpeg -framerate 24 -start_number 100 -i photo%04d.jpg -c:v libx264 -pix_fmt yuv420p output.mp4

Frame Rate Summary

PurposeRecommended setting
Slideshow at 1 second per image-framerate 1
Smooth slideshow-framerate 1 -r 25
Normal video-framerate 24 or 30
Timelapse (10× speed)-vf fps=1/10

About the image2 Demuxer

FFmpeg internally uses the image2 demuxer for image sequence input. It is usually auto-detected, but can also be specified explicitly:

ffmpeg -f image2 -framerate 25 -i img%03d.png -c:v libx264 output.mp4

Specifying -f image2 is usually unnecessary, but it is useful to know as a workaround when auto-detection fails.


Related articles:


Frequently Asked Questions

How do I make a slideshow from a folder of images?

ffmpeg -framerate 1/3 -pattern_type glob -i "*.jpg" -c:v libx264 -pix_fmt yuv420p out.mp4. 1/3 means 3 seconds per image.

How do I add a Ken Burns zoom?

zoompan=z='min(zoom+0.0015,1.5)':d=125:s=1280x720 zooms each image over ~5 s. Combine with xfade for crossfades between slides.

Why is my timelapse choppy?

Source frame rate is too low or shutter speed too fast — frames have no motion blur. Increase frame interval at capture or apply tmix=frames=3 to smooth motion.

Slideshow audio cuts off — how to match audio to image count?

Calculate duration = images × seconds_per_image and set -t duration on the audio input, plus -shortest to align both streams.

Can I mix portrait and landscape photos?

Yes — pad both to the same canvas with pad=1920:1080:(ow-iw)/2:(oh-ih)/2:black so portraits get sidebars and landscapes fit naturally.


Tested with: ffmpeg 6.1.1 / Ubuntu 24.04 (GitHub Actions runner)
Primary sources: ffmpeg.org/ffmpeg.html / ffmpeg.org/ffmpeg-filters.html / trac.ffmpeg.org/wiki/Slideshow