Preface
In this post, I will share how I use FFmpeg to make a video from images, and I will show some effects that I use to make the video more interesting.
Installation
- Linux (Ubuntu)
sudo apt install ffmpeg
- Windows
- Download the FFmpeg.
- Extract the zip file.
- Add the
exe
file to the system path.
Prepare Images
I set up my camera to take a photo every 3 seconds, so I got 12000 images for 10 hour.
If you want to make a video with me, but you do not have images yet, you can extract images from a video file with the command:
ffmpeg -i input.mp4 -vf fps=30 output/image_%05d.png
the command will extract images from input.mp4
, 30 images per second, and save them to the output
directory with the file name format image_00001.png
, image_00002.png
, etc.
Make Video
Now we have the images, let’s make a video with these images.
The command is to take sequence images and make it as each frame of the video.
So I got 12000 images, framerate 30, it will make a 400 (12000 / 30) seconds video.
ffmpeg -framerate 30 -pattern_type sequence -start_number 00001 -i image_%05d.png \
-s 1920x1080 -crf 18 -c:v libx264 -pix_fmt yuv420p -y origin.mp4
-framerate 30
: set the framerate(fps) to 30.-pattern_type sequence
: input file pattern type to sequence.-start_number 00001
: start number of the image sequence.-i image_%04d.png
: input image file pattern.origin.mp4
: output file name.
optional parameters:
-s 1920x1080
: set the resolution to 1920x1080.-crf 18
: set the constant rate factor to 18, where- Constant Rate Factor (CRF) is a quality setting from 0 to 51, where 0 is lossless, 23 is the default, and 51 is the worst quality.
-c:v libx264
: use libx264 codec, known as H.264.- codec use algorithms to calculate the difference between frames, to reduce the file size.
-pix_fmt yuv420p
: use color model to yuv420p.- color model is a way to save the color information of the image.
-y
: overwrite the output file if it exists.
Now I have the video, but it is too long, so I want to cut it with in 1 minute.
I have to speed up the video. I use the setpts filter to speed up the video.
ffmpeg -i "origin.mp4" -r 30 -filter:v "setpts=0.2*PTS" -y "speed-up.mp4"
filter:v
: use the video filter.setpts=0.2*PTS
: set PTS as 0.2 times of the original PTS.- PTS is stands for Presentation Time Stamp, it is the time that the frame should be displayed.
The command will make every frame display 5 times earlier than the original, and maintain the original framerate.
So the frame at second 1
will be displayed at second 0.2
, and 2
will be displayed at 0.4
, etc.
Therfore, the video will be 5 times faster than the original. 400 seconds will be speed up to 80 seconds.
Now I have the video, and I would like to add some effects.
Effects
Stop Motion
I want the video stop when I finish the puzzle, so people can enjoy the final image. So I take the last image, and create a video loop with same images.
ffmpeg -framerate 30 -loop 1 -i end.png -t 3 -y stop-motion.mp4
-loop 1
: set the input image to loop.-t 3
: set the duration to 3 seconds.
Zoom In/Out
After the stop motion, I want to zoom in the final image, so people can see the details of the image. Still use the last image, and use the zoompan filter to zoom in the image.
ffmpeg -loop 1 -framerate 30 -i end.png -filter:v "scale=3840:-1,zoompan=z='zoom+0.001':x=iw/2-(iw/zoom/2):y=ih/2-(ih/zoom/2):d=5*30:s=1920x1080:fps=30" -t 5 -y zoom-in.mp4
scale=3840:-1
: scale the image to 3840 width, height set to -1, it will be calculated automatically.- not sure the reason, but after I test with different resolution, I found that bigger the resolution, the smoother the zoom effect.
- My wonder - to my understanding, the zoom effect is by percentage, so the scale should not affect the zoom effect?
zoompan=z='zoom+0.001'
: zoom in the image with 0.1% per frame.x=iw/2-(iw/zoom/2):y=ih/2-(ih/zoom/2)
: set the x, y position to the center of the image, so the image will zoom in the center.d=5*30
: framerate is 30, so 5 seconds will be 5*30 frames.- each frame will zoom in 0.1%, so 5 seconds will zoom in 15%.
s=1920x1080
: set the output resolution to 1920x1080.fps=30
: output framerate to 30.
Merge Videos
Now I have 3 videos, I want to merge them into one video.
To merge them into one video, I use the concat demuxer.
First create a text file list.txt
with the list of the video files.
file 'speed-up.mp4'
file 'stop-motion.mp4'
file 'zoom-in.mp4'
Then use the concat demuxer to merge the videos.
ffmpeg -f concat -i list.txt -c copy -y merged.mp4
The command will merge the videos in order.
-f concat
: set the format to concat.-c copy
: copy the video directly, without re-encode.
Add Audio
Also I want to add some background music to the video. Get the audio file, and add it to the video.
ffmpeg -i "merged.mp4" -i "audio.mp3" -map 0:v -map 1:a -c:v copy -shortest -y audio.mp4
-map 0:v -map 1:a
: map the video part from the first input, and audio part from the second input.-shortest
: set the output duration to the shortest input duration, so the audio will stop when the video stop.
Fade Out
After all this effect, I got the final effect, I want to fade out the video. I want to fade out the video at last 3 seconds, during the zoom in effect.
Adjust the st
as the start time of the fade out, and d
as the duration of the fade out.
ffmpeg -i "audio.mp4" \
-filter_complex "[0:v]fade=t=out:st=85:d=3;[0:a]afade=t=out:st=85:d=3" \
-y "final.mp4"
fade=t=out:st=85:d=3
: fade out the video at 85 seconds, during 3 seconds.afade=t=out:st=85:d=3
: fade out the audio at 85 seconds, during 3 seconds.
Now I have the video, with all the effects.
All these commands are simple, but take time to understand, test and adjust the parameters. Sometimes I got the video with unexpected results, sometimes with errors, but I enjoy the process to find the solution. This process push me to learn more knowledge about the video, the codec, the filter, etc. I would like to share this knowledge with you next time, and hope you enjoy the process too.