FFmpeg | Объединение файлов, слайдшоу (concat)
от aNNiMON
Часто приходится объединить несколько видео в одно или склеить множество изображений в одной видео.
Содержание:
- Объединение из списка файлов
- Создание списка файлов из командной строки
- Объединение фильтром concat
- Слайдшоу
Объединение из списка файловДопустим, есть 5 видео файлов: 1.mp4, 2.mp4, 3.mp4, 4.mp4 и 5.mp4
Если все они имеют одинаковые кодеки, частоту кадров и разрешение, то их можно будет объединить очень быстро с поддержкой копирования потоков.
Для этого необходимо создать текстовый файл, в котором перечислить все видео в нужном порядке:
list.txt
После чего выполнить объединение:
Этот способ очень быстр, но, к сожалению, зависим от параметров видео. Если какие-то видео отличаются в частоте кадров или прочих параметрах, то объединённое видео может неправильно воспроизводиться. Поэтому, при таком способе обязательно проверяйте результат.
Если возникли проблемы с быстрым объединением, тогда можно убрать копирование потоков:
В таком случае объединение будет происходить дольше из-за перекодирования, но зато результат будет правильно воспроизводиться.
⚠️ Некоторые форматы видео поддерживают файловое копирование. Например, в случае ts (mpegts) новое видео можно просто дописывать в конец другого без перекодирования (и даже без участия ffmpeg).
Windows:
Linux:
Этот способ работает не только с видео, но и с аудио:
И даже с изображениями.
⚠️ Файлы можно указывать несколько раз. Например, если есть заставка, которая должна быть в начале и в конце видео, можно создать такой файл:
Создание списка файлов из командной строки
Чтобы вручную не вписывать названия файлов, особенно, если их много, на Windows можно выполнить команду:
Либо для вложенных папок:
Для Linux:
Или для вложенных папок:
Объединение фильтром concatЕсли нужно объединить несколько видео с разным форматом или отличающимися кодеками, можно воспользоваться фильтром concat
Параметры:
n — количество частей (по умолчанию 2)
v — количество выходных видеопотоков (и видеопотоков в каждой части). По умолчанию, 1.
a — количество выходных аудиопотоков (и аудиопотоков в каждой части). По умолчанию, 0.
Объединить три видео в один файл (в каждом 1 видеопоток и 1 аудиопоток):
Вначале перечисляем пары (видеопоток + аудиопоток) для каждого входного файла, после чего указываем, что объединять будем 3 части (n=3), а на выходе ожидаем один видеопоток (v=1) и один аудиопоток (a=1).
Перед началом обработки, FFmpeg выведет информацию о потоках, можно проверить, что всё нормально:
Объединить аудиопотоки у трёх видеофайлов и сохранить в result.mp3:
СлайдшоуПри объединении изображений из списка файлов, можно указывать длительность показа изображения в секундах:
Если же изображений очень много и их нужно объединить с определённой частотой кадров, можно указать шаблон.
Допустим, есть 500 картинок с именами frame_001.jpg, frame_002.jpg, ..., frame_500.jpg. Чтобы объединить их в видео с частотой 60 кадров в секунду:
%03d — специальный формат шаблона, означающий, что под порядковый номер отводится 3 цифры и есть лидирующий ноль.
Если объединять файлы "img (1).jpg", "img (2).jpg", .., "img (2000).jpg", то шаблон будет таким:
Смотрите также ответы к Собрать видео из множества фотографии, там инструкция и скрипт объединения картинок.
Следующая статья →Содержание:
- Объединение из списка файлов
- Создание списка файлов из командной строки
- Объединение фильтром concat
- Слайдшоу
Объединение из списка файловДопустим, есть 5 видео файлов: 1.mp4, 2.mp4, 3.mp4, 4.mp4 и 5.mp4
Если все они имеют одинаковые кодеки, частоту кадров и разрешение, то их можно будет объединить очень быстро с поддержкой копирования потоков.
Для этого необходимо создать текстовый файл, в котором перечислить все видео в нужном порядке:
list.txt
- file '1.mp4'
- file '2.mp4'
- file '3.mp4'
- file '4.mp4'
- file '5.mp4'
- ffmpeg -f concat -safe 0 -i list.txt -c copy result.mp4
Этот способ очень быстр, но, к сожалению, зависим от параметров видео. Если какие-то видео отличаются в частоте кадров или прочих параметрах, то объединённое видео может неправильно воспроизводиться. Поэтому, при таком способе обязательно проверяйте результат.
Если возникли проблемы с быстрым объединением, тогда можно убрать копирование потоков:
- ffmpeg -f concat -safe 0 -i list.txt result.mp4
⚠️ Некоторые форматы видео поддерживают файловое копирование. Например, в случае ts (mpegts) новое видео можно просто дописывать в конец другого без перекодирования (и даже без участия ffmpeg).
Windows:
- copy /b video1.ts + video2.ts result.ts
- cat video1.ts video2.ts > result.ts
Этот способ работает не только с видео, но и с аудио:
- file '1.mp3'
- file '2.mp3'
- file '3.mp3'
- ffmpeg -f concat -safe 0 -i list.txt result.mp3
И даже с изображениями.
⚠️ Файлы можно указывать несколько раз. Например, если есть заставка, которая должна быть в начале и в конце видео, можно создать такой файл:
- file 'splash.mp4'
- file 'video1.mp4'
- file 'video2.mp4'
- file 'splash.mp4'
Создание списка файлов из командной строки
Чтобы вручную не вписывать названия файлов, особенно, если их много, на Windows можно выполнить команду:
- (for %i in (*.mp4) do @echo file '%i') > list.txt
- (for /r %i in (*.mp4) do @echo file '%i') > list.txt
Для Linux:
- (for f in *.mp4; do echo "file '$f'"; done) > list.txt
- find . -type f -iname "*.mp4" -printf "file '%p'\n" > list.txt
Объединение фильтром concatЕсли нужно объединить несколько видео с разным форматом или отличающимися кодеками, можно воспользоваться фильтром concat
Параметры:
n — количество частей (по умолчанию 2)
v — количество выходных видеопотоков (и видеопотоков в каждой части). По умолчанию, 1.
a — количество выходных аудиопотоков (и аудиопотоков в каждой части). По умолчанию, 0.
Объединить три видео в один файл (в каждом 1 видеопоток и 1 аудиопоток):
- ffmpeg -i 1.mp4 -i 2.mp4 -i 3.mp4 ^
- -filter_complex "[0:v][0:a][1:v][1:a][2:v][2:a]concat=n=3:v=1:a=1[outv][outa]" ^
- -map "[outv]" -map "[outa]" result.mp4
Перед началом обработки, FFmpeg выведет информацию о потоках, можно проверить, что всё нормально:
- Stream mapping:
- Stream #0:0 (h264) -> concat:in0:v0
- Stream #0:1 (aac) -> concat:in0:a0
- Stream #1:0 (h264) -> concat:in1:v0
- Stream #1:1 (aac) -> concat:in1:a0
- Stream #2:0 (h264) -> concat:in2:v0
- Stream #2:1 (aac) -> concat:in2:a0
- concat:out:v0 -> Stream #0:0 (libx264)
- concat:out:a0 -> Stream #0:1 (aac)
Объединить аудиопотоки у трёх видеофайлов и сохранить в result.mp3:
- ffmpeg -i 1.mp4 -i 2.mp4 -i 3.mp4 ^
- -filter_complex "[0:a][1:a][2:a]concat=n=3:v=0:a=1[outa]" ^
- -map "[outa]" result.mp3
СлайдшоуПри объединении изображений из списка файлов, можно указывать длительность показа изображения в секундах:
- file 'cat.jpg'
- duration 2
- file 'dog.jpg'
- duration 4
- file 'cat and dog.jpg'
- duration 2
- file 'cat and dog 2.jpg'
- duration 2
- ffmpeg -f concat -safe 0 -i list.txt slideshow.mp4
Если же изображений очень много и их нужно объединить с определённой частотой кадров, можно указать шаблон.
Допустим, есть 500 картинок с именами frame_001.jpg, frame_002.jpg, ..., frame_500.jpg. Чтобы объединить их в видео с частотой 60 кадров в секунду:
- ffmpeg -framerate 60 -i frame_%03d.jpg -pix_fmt yuv420p output.mp4
Если объединять файлы "img (1).jpg", "img (2).jpg", .., "img (2000).jpg", то шаблон будет таким:
- ffmpeg -framerate 30 -i "img (%4d).jpg" -pix_fmt yuv420p output.mp4
Смотрите также ответы к Собрать видео из множества фотографии, там инструкция и скрипт объединения картинок.
Удобная цветокоррекция с помощью LUT