You have a folder full of photos and you want a smooth slideshow video with a soundtrack, crossfades, and the right resolution for sharing. This is a common thread in dev communities, and the most flexible answer usually involves FFmpeg.
How to create videos from images using FFmpeg?
I have a set of images (some numbered, some not). I want to stitch them into an MP4 at a specific frame rate, optionally add audio, ensure the output is 1920×1080 without distortion, and maybe add basic crossfade transitions or a Ken Burns pan and zoom. What are the recommended FFmpeg commands and pitfalls to avoid?
FFmpeg’s image2 demuxer makes this straightforward and very configurable. Here are practical patterns you can mix and match.
If your files are zero-padded like img_0001.jpg, img_0002.jpg, and so on:
ffmpeg -framerate 30 -i imgs/img_%04d.jpg \
-c:v libx264 -pix_fmt yuv420p -r 30 output.mp4
- -framerate sets input frame rate, -r sets output frame rate
- Use yuv420p for wide player compatibility
For images like frameA.jpg, frameB.jpg:
ffmpeg -pattern_type glob -framerate 24 -i "imgs/*.jpg" \
-c:v libx264 -pix_fmt yuv420p slideshow.mp4Code language: JavaScript (javascript)
Tip: Ensure the glob expands in the order you expect. Sorting at the OS level before running FFmpeg helps.
To give each image its own display duration, use the concat demuxer:
# list.txt
file 'img1.jpg'
duration 2.5
file 'img2.jpg'
duration 3
file 'img3.jpg'
duration 4
# Repeat the last image line once more to finalize timing
file 'img3.jpg'
ffmpeg -f concat -safe 0 -i list.txt \
-vf fps=30,format=yuv420p -c:v libx264 output.mp4Code language: PHP (php)
Preserve aspect ratio and pad to full HD with a neutral background:
ffmpeg -framerate 30 -i imgs/img_%04d.jpg \
-vf "scale=1920:1080:force_original_aspect_ratio=decrease,\
pad=1920:1080:(ow-iw)/2:(oh-ih)/2,format=yuv420p" \
-c:v libx264 -r 30 slideshow_1080p.mp4Code language: JavaScript (javascript)
Map in audio and end when either video or audio finishes:
ffmpeg -framerate 30 -i imgs/img_%04d.jpg -i music.mp3 \
-vf "scale=1920:1080:force_original_aspect_ratio=decrease,\
pad=1920:1080:(ow-iw)/2:(oh-ih)/2,format=yuv420p" \
-c:v libx264 -r 30 -c:a aac -b:a 192k -shortest slideshow_music.mp4Code language: JavaScript (javascript)
Loop each image for a few seconds, then xfade:
ffmpeg \
-loop 1 -t 3 -i img1.jpg \
-loop 1 -t 3 -i img2.jpg \
-filter_complex "\
[0:v]scale=1920:1080:force_original_aspect_ratio=decrease,\
pad=1920:1080:(ow-iw)/2:(oh-ih)/2,format=yuv420p[v0];\
[1:v]scale=1920:1080:force_original_aspect_ratio=decrease,\
pad=1920:1080:(ow-ih)/2:(oh-ih)/2,format=yuv420p[v1];\
[v0][v1]xfade=transition=fade:duration=0.7:offset=2.3[v]" \
-map "[v]" -c:v libx264 -r 30 xfade.mp4Code language: JavaScript (javascript)
Repeat the xfade chaining to add more images.
Create gentle motion with zoompan. For a 5 second 1080p clip at 30 fps:
ffmpeg -loop 1 -t 5 -i photo.jpg \
-vf "zoompan=z='min(zoom+0.0015,1.5)':x='iw/2-(iw/zoom/2)':\
y='ih/2-(ih/zoom/2)':d=150,scale=1920:1080,format=yuv420p" \
-c:v libx264 -r 30 kenburns.mp4Code language: JavaScript (javascript)
For more on creative approaches, see the Ken Burns guide.
- Use -crf 18 to 23 for H.264 quality. Lower is higher quality.
- Set -preset faster to slower depending on time vs. compression.
- Stick to yuv420p for broad compatibility.
- Read this overview of FFmpeg’s strengths and tradeoffs: FFmpeg features and pros and cons.
- For broader encoding best practices, see Video encoding best practices.
- Preprocess images at source. Standardize dimensions and aspect ratio via URL-based transformations so FFmpeg receives consistent inputs. This reduces filter complexity and mismatched sizes.
- Apply zoompan or crop variants on demand to audition looks before baking them into a final slideshow.
- Once the slideshow is exported, upload it, allowing the delivery layer to manage format adjustments, thumbnails, and other variations.
- Numbered images: use -framerate on input and yuv420p output.
- Use concat or -loop with xfade for durations and transitions.
- Scale and pad to 1920×1080 to avoid distortion.
- Add audio with -shortest to stop at the right time.
- Tune quality with -crf and -preset. Review FFmpeg best uses and encoding tips.
Ready to optimize your media pipeline from source images to finished video and delivery? Sign up for free and start building a faster, more reliable workflow today.