How to create a video from images with FFmpeg?
This line worked fine but I want to create a video file from images in another folder. Image names in my folder are:
img001.jpg img002.jpg img003.jpg .
How could I input images files from a different folder? Example: C:\mypics I tried this command but ffmpeg generated a video with the first image (img001.jpg) only.
ffmpeg -r 1/5 -start_number 0 -i C:\myimages\img%03d.png -c:v libx264 -r 30 -pix_fmt yuv420p out.mp4
9 Answers 9
-pattern_type glob
This great option makes it easier to select the images in many cases.
Normal speed video with one image per frame at 30 FPS
ffmpeg -framerate 30 -pattern_type glob -i '*.png' \ -c:v libx264 -pix_fmt yuv420p out.mp4
ffmpeg -framerate 30 -pattern_type glob -i '*.png' \ -i audio.ogg -c:a copy -shortest -c:v libx264 -pix_fmt yuv420p out.mp4
These are the test media I’ve used:
wget -O opengl-rotating-triangle.zip https://github.com/cirosantilli/media/blob/master/opengl-rotating-triangle.zip?raw=true unzip opengl-rotating-triangle.zip cd opengl-rotating-triangle wget -O audio.ogg https://upload.wikimedia.org/wikipedia/commons/7/74/Alnitaque_%26_Moon_Shot_-_EURO_%28Extended_Mix%29.ogg
It is cool to observe how much the video compresses the image sequence way better than ZIP as it is able to compress across frames with specialized algorithms:
Convert one music file to a video with a fixed image for YouTube upload
Slideshow video with one image per second
ffmpeg -framerate 1 -pattern_type glob -i '*.png' \ -c:v libx264 -r 30 -pix_fmt yuv420p out.mp4
Add some music to it, cutoff when the presumably longer audio when the images end:
ffmpeg -framerate 1 -pattern_type glob -i '*.png' -i audio.ogg \ -c:a copy -shortest -c:v libx264 -r 30 -pix_fmt yuv420p out.mp4
Here are two demos on YouTube:
ffmpeg -framerate 1 -pattern_type glob -i '*.png' -i audio.ogg \ -c:a copy -shortest -c:v libtheora -r 30 -pix_fmt yuv420p out.ogv
Your images should of course be sorted alphabetically, typically as:
0001-first-thing.jpg 0002-second-thing.jpg 0003-and-third.jpg
I would also first ensure that all images to be used have the same aspect ratio, possibly by cropping them with imagemagick or nomacs beforehand, so that ffmpeg will not have to make hard decisions. In particular, the width has to be divisible by 2, otherwise conversion fails with: «width not divisible by 2».
Full realistic slideshow case study setup step by step
There’s a bit more to creating slideshows than running a single ffmpeg command, so here goes a more interesting detailed example inspired by this timeline.
mkdir -p orig cd orig wget -O 1.png https://upload.wikimedia.org/wikipedia/commons/2/22/Australopithecus_afarensis.png wget -O 2.jpg https://upload.wikimedia.org/wikipedia/commons/6/61/Homo_habilis-2.JPG wget -O 3.jpg https://upload.wikimedia.org/wikipedia/commons/c/cb/Homo_erectus_new.JPG wget -O 4.png https://upload.wikimedia.org/wikipedia/commons/1/1f/Homo_heidelbergensis_-_forensic_facial_reconstruction-crop.png wget -O 5.jpg https://upload.wikimedia.org/wikipedia/commons/thumb/5/5a/Sabaa_Nissan_Militiaman.jpg/450px-Sabaa_Nissan_Militiaman.jpg wget -O audio.ogg https://upload.wikimedia.org/wikipedia/commons/7/74/Alnitaque_%26_Moon_Shot_-_EURO_%28Extended_Mix%29.ogg cd .. # Convert all to PNG for consistency. # https://unix.stackexchange.com/questions/29869/converting-multiple-image-files-from-jpeg-to-pdf-format # Hardlink the ones that are already PNG. mkdir -p png mogrify -format png -path png orig/*.jpg ln -P orig/*.png png
Now we have a quick look at all image sizes to decide on the final aspect ratio:
png/1.png PNG 557x495 557x495+0+0 8-bit sRGB 653KB 0.000u 0:00.000 png/2.png PNG 664x800 664x800+0+0 8-bit sRGB 853KB 0.000u 0:00.000 png/3.png PNG 544x680 544x680+0+0 8-bit sRGB 442KB 0.000u 0:00.000 png/4.png PNG 207x238 207x238+0+0 8-bit sRGB 76.8KB 0.000u 0:00.000 png/5.png PNG 450x600 450x600+0+0 8-bit sRGB 627KB 0.000u 0:00.000
so the classic 480p (640×480 == 4/3) aspect ratio seems appropriate.
Do one conversion with minimal resizing to make widths even (TODO automate for any width, here I just manually looked at identify output and reduced width and height by one):
mkdir -p raw convert png/1.png -resize 556x494 raw/1.png ln -P png/2.png png/3.png png/4.png png/5.png raw ffmpeg -framerate 1 -pattern_type glob -i 'raw/*.png' -i orig/audio.ogg -c:v libx264 -c:a copy -shortest -r 30 -pix_fmt yuv420p raw.mp4
This produces terrible output, because as seen from:
ffmpeg just takes the size of the first image, 556×494, and then converts all others to that exact size, breaking their aspect ratio.
Now let’s convert the images to the target 480p aspect ratio automatically by cropping as per ImageMagick: how to minimally crop an image to a certain aspect ratio?
mkdir -p auto mogrify -path auto -geometry 640x480^ -gravity center -crop 640x480+0+0 png/*.png ffmpeg -framerate 1 -pattern_type glob -i 'auto/*.png' -i orig/audio.ogg -c:v libx264 -c:a copy -shortest -r 30 -pix_fmt yuv420p auto.mp4
So now, the aspect ratio is good, but inevitably some cropping had to be done, which kind of cut up interesting parts of the images.
The other option is to pad with black background to have the same aspect ratio as shown at: Resize to fit in a box and set background to black on «empty» part
mkdir -p black mogrify -path black -thumbnail 640x480 -background black -gravity center -extent 640x480 png/*.png ffmpeg -framerate 1 -pattern_type glob -i 'black/*.png' -i orig/audio.ogg -c:v libx264 -c:a copy -shortest -r 30 -pix_fmt yuv420p black.mp4
Generally speaking though, you will ideally be able to select images with the same or similar aspect ratios to avoid those problems in the first place.
About the CLI options
Note however that despite the name, -glob this is not as general as shell Glob patters, e.g.: -i ‘*’ fails: https://trac.ffmpeg.org/ticket/3620 (apparently because filetype is deduced from extension).
-r 30 makes the -framerate 1 video 30 FPS to overcome bugs in players like VLC for low framerates: VLC freezes for low 1 FPS video created from images with ffmpeg Therefore it repeats each frame 30 times to keep the desired 1 image per second effect.
- cut up the part of the audio that you want before joining it: Cutting the videos based on start and end time using ffmpeg
ffmpeg -i in.mp3 -ss 03:10 -to 03:30 -c copy out.mp3
Alternatively, you can also cut it directly in the conversion command by adding the -ss just before the audio -i :
ffmpeg -framerate 1 -pattern_type glob -i 'raw/*.png' -ss 0:36 -i orig/audio.ogg -c:v libx264 -c:a copy -shortest -r 30 -pix_fmt yuv420p raw.mp4
TODO: learn to cut and concatenate multiple audio files into the video without intermediate files, I’m pretty sure it’s possible:
Different duration for each image
You create a file in.txt like:
file png/1.png outpoint 5 file png/2.png outpoint 2 file png/3.png outpoint 7
and outpoint sets the duration of the previous image in seconds.
Then we just remove -framerate from the previous conversion commands:
ffmpeg -f concat -i in.txt -framerate 1 -i orig/audio.ogg -c:v libx264 -c:a copy -shortest -r 30 -pix_fmt yuv420p black.mp4
I also like that that approach with file names in a file is nicer than having to rename the input files to have the correct order, which makes it easier to quickly reorder images on a text editor (multiple -i did not work). Having two lines per input file makes that a bit more annoying, I didn’t manage to combine the file and outpoint into a single line, but still, good to know.
This approach is also convenient if you are just going to convert a subset of your images. Then, to save time on the ImageMagick, you can reuse that in.txt file to loop over only the images you care about:
grep -E '^file ' in.txt | sed -E 's/^file //; s/\..*//' | while read f; do echo $f convert -thumbnail 1280x720 -background black -gravity center -extent 1280x720 "$(command ls -1 ../$f.* | grep -v .xcf | head -n1)" "out/$f.jpg" done
ffmpeg 3.4.4, vlc 3.0.3, Ubuntu 18.04.
Bibliography
19 команд ffmpeg для любых нужд
От переводчика:
Многие знают, что ffmpeg — это сила, но не все знают, какая именно. Он многогранен и безграничен, а его man объёмен и местами малопонятен, лишь немногие постигли дао профессиональной работы с ним. И тем не менее, этот инструмент может быть полезен почти всем, кто хоть иногда работает с видео и звуком, даже на бытовом уровне. О некоторых полезных консольных командах ffmpeg и пойдёт речь в статье. В некоторых местах я взял на себя смелость вставить ссылки на поясняющие статьи.
ffmpeg — это кроссплатформенная open-source библиотека для обработки видео- и аудиофайлов. Я собрал 19 полезных и удивительных команд, покрывающих почти все нужды: конвертация видео, извлечение звуковой дорожки, конвертирование для iPod или PSP, и многое другое.
1. Получение информации о видеофайле
2. Превратить набор картинок в видео
ffmpeg -f image2 -i image%d.jpg video.mpg
Эта команда преобразует все картинки из текущей директории (названные image1.jpg, image2.jpg и т.д.) в видеофайл video.mpg
(примечание переводчика: мне больше нравится такой формат:
ffmpeg -r 12 -y -i "image_%010d.png" output.mpg
здесь задаётся frame rate (12) для видео, формат «image_%010d.png» означает, что картинки будут искаться в виде image_0000000001.png, image_0000000002.png и тд, то есть, в формате printf)
3. Порезать видео на картинки
ffmpeg -i video.mpg image%d.jpg
Эта команда создаст файлы image1.jpg, image2.jpg и т.д., поддерживаются так же форматы PGM, PPM, PAM, PGMYUV, JPEG, GIF, PNG, TIFF, SGI.
4. Конвертировать видео в формат iPod/iPhone
ffmpeg -i source_video.avi input -acodec aac -ab 128kb -vcodec mpeg4 -b 1200kb -mbd 2 -flags +4mv+trell -aic 2 -cmp 2 -subcmp 2 -s 320x180 -title X final_video.mp4
- Источник: source_video.avi
- Аудио кодек: aac
- Битрейт аудио: 128kb/s
- Видео кодек: mpeg4
- Битрейт видео: 1200kb/s
- Размер видео: 320 на 180 пикселей
- Полученное видео: final_video.mp4
5. Конвертировать видео в формат PSP
ffmpeg -i source_video.avi -b 300 -s 320x240 -vcodec xvid -ab 32 -ar 24000 -acodec aac final_video.mp4
- Источник: source_video.avi
- Аудио кодек: aac
- Битрейт аудио: 32kb/s
- Видео кодек: xvid
- Битрейт видео: 1200kb/s
- Размер видео: 320 на 180 пикселей
- Полученное видео: final_video.mp4
6. Извлечь звуковую дорожку из видео и сохранить в mp3
ffmpeg -i source_video.avi -vn -ar 44100 -ac 2 -ab 192K -f mp3 sound.mp3
- Источник: source_video.avi
- Битрейт аудио: 192kb/s
- Выходной формат: mp3
- Полученный аудиофайл: sound.mp3
7. Конвертировать wav в mp3
ffmpeg -i son_origine.wav -vn -ar 44100 -ac 2 -ab 192 -f mp3 son_final.mp3
8. Конвертировать .avi в .mpg
ffmpeg -i video_origine.avi video_finale.mpg
9. Конвертировать .mpg в .avi
ffmpeg -i video_origine.mpg video_finale.avi
10. Конвертировать .avi в .gif (без сжатия)
ffmpeg -i video_origine.avi gif_anime.gif
11. Добавить звук к видео
ffmpeg -i son.wav -i video_origine.avi video_finale.mpg
12. Конвертировать .avi в .flv
ffmpeg -i video_origine.avi -ab 56 -ar 44100 -b 200 -r 15 -s 320x240 -f flv video_finale.flv
13. Конвертировать .avi в .dv
ffmpeg -i video_origine.avi -s pal -r pal -aspect 4:3 -ar 48000 -ac 2 video_finale.dv
ffmpeg -i video_origine.avi -target pal-dv video_finale.dv
14. Конвертировать .avi в mpeg для DVD-плееров
ffmpeg -i source_video.avi -target pal-dvd -ps 2000000000 -aspect 16:9 finale_video.mpeg
- Выходной формат: pal-dvd
- Максимальный размер для выходного файла: 2000000000 (2 Gb)
- Широкоэкранный формат: 16:9
15. Сжать .avi в DivX
ffmpeg -i video_origine.avi -s 320x240 -vcodec msmpeg4v2 video_finale.avi
16. Сжать OGG Theora в mpeg DVD
ffmpeg -i film_sortie_cinelerra.ogm -s 720x576 -vcodec mpeg2video -acodec mp3 film_termin.mpg
17. Сжать .avi в SVCD mpeg2
ffmpeg -i video_origine.avi -target ntsc-svcd video_finale.mpg
ffmpeg -i video_origine.avi -target pal-svcd video_finale.mpg
18. Сжать .avi в VCD mpeg2
ffmpeg -i video_origine.avi -target ntsc-vcd video_finale.mpg
ffmpeg -i video_origine.avi -target pal-vcd video_finale.mpg
19. Многопроходное кодирование с помощью ffmpeg
ffmpeg -i fichierentree -pass 2 -passlogfile ffmpeg2pass fichiersortie-2
Примечание переводчика:
Предлагаю в комментариях привести и другие полезные команды ffmpeg, их ведь гораздо больше, чем 19. 😉