FFmpeg. Трюки и хитрости

Введение

FFmpeg — мультимедийный комбайн, набор библиотек которые позволяют записывать, обрабатывать и конвертировать видео и/или аудио материалы в различные форматы. С помощью этого инструмента можно производить видео монтаж практически любой сложности. Его используют многие плееры, конвертеры, редакторы и библиотеки компьютерного зрения. В этой статье я поделюсь трюками и хитростями с FFmpeg, которые и сам часто использую в работе.

Обрезка видео по времени

Довольно часто нужно вырезать из видео небольшой фрагмент с n по m секунды. Для этого нужно указать секунду, с которой вырезать, и длительность.

ffmpeg -i i.mp4 -ss 00:01:00 -t 00:02:00 -c copy o.mp4

Параметр -ss указывает на начальную точку, а -t на длительность.

Важное замечание! Если длительность видео 5 минут, начальную точку укажем в 00:04:00, а длительность в 00:02:00, длительность конечного видео будет 1 минута.

Тут и далее по тексту статьи, i.mp4 - это путь к входному файлу, а o.mp4 - к выходному.

Создание видео из фотографий

Предположим, у нас есть камера наблюдения, которая делала фото каждую минуту в течение суток, а мы хотим получить одно непрерывное видео.

Используя код ниже, можно превратить все фото с расширением .jpg из текущей папки в видео, с кадровой частотой 10 FPS, используя H.264 кодек.

ffmpeg -framerate 10 -pattern_type glob -i '*.jpg' -c:v libx264 o.mp4

Извлечение фотографий из видео

А теперь сделаем действие противоположное действию из предыдущего пункта — разобьем видео по кадрам на фотографии.

ffmpeg -i o.mp4 -r 1 -q:v 2 -f image2 img-3%d.jpeg

Склейка двух и больше видео в одно

Для склейки множества видео в одно нам потребуется создать файл, например list.txt, в котором по порядку перечислим пути к видео, которые хотим склеить, например:

file 'video1.mp4'
file 'video2.mp4'
file 'videoN.mp4'

А после этого выполним:

ffmpeg -f concat -i list.txt -c copy o.mp4

Создавать такой файл вручную не лучшая идея, можно его наполнить автоматически, например, так:

for f in ./*.mp4; do echo "file '$f'" >> list.txt; done

или так:

printf "file '%s'\n" ./*.mp4> list.txt

Удаление и извлечения аудио из видео

Для удаления используем:

ffmpeg -i i.mp4 -c:v copy -an o.mp4

А для извлечения:

ffmpeg -i i.mp4 -vn 0.wav

Обрезка видео по высоте и ширине

В начале статьи я рассказал о способе обрезки видео по времени, но его также можно обрезать и по размеру кадра, например превратить 16:9 формат в 3:4, обрезав кадр слева и справа.

ffmpeg -i i.mp4 -filter:v "crop=w:h:x:y" o.mp4

В фильтре crop по очереди нужно указать ширину, высоту нового кадра, а также его смещение по координатам.

Размещение видео рядом в одном кадре (stack video)

Перед тем, как мы это сделаем, есть пара моментов, которые нужно рассмотреть:

  • Видео должны иметь одинаковую высоту.

  • Видео должны иметь тот же формат пикселей.

Горизонтальное размещение:

ffmpeg -i i0.mp4 -i i1.mp4 -filter_complex hstack=inputs=2 o.mp4

Вертикальное размещение:

ffmpeg -i i0.mp4 -i i1.mp4 -filter_complex vstack=inputs=2 o.mp4

Сетка 2x2:

ffmpeg \
-i i0.mp4 -i i1.mp4 -i i2.mp4 -i i3.mp4 \
-filter_complex \
"[0:v][1:v]hstack=inputs=2[top]; \
[2:v][3:v]hstack=inputs=2[bottom]; \
[top][bottom]vstack=inputs=2[v]" \
-map "[v]" \
o.mp4

Сетка 3x2:

ffmpeg \
-i i0.mp4 -i i1.mp4 \
-i i2.mp4 -i i3.mp4 \
-i i4.mp4 -i i5.mp4 \
-filter_complex \
"[0:v][1:v][2:v]hstack=inputs=3[top];\
[3:v][4:v][5:v]hstack=inputs=3[bottom];\
[top][bottom]vstack=inputs=2[v]" \
-map "[v]" \
o.mp4

Поворот видео

ffmpeg -i i.mp4 -vf "transpose=0" o.mp4

Параметр transpose в коде выше может принимать такие значения:

  • 0 - Повернуть на 90 градусов против часовой стрелки и развернуть по вертикали. По умолчанию.

  • 1 - Повернуть на 90 градусов по часовой стрелке.

  • 2 - Повернуть на 90 градусов против часовой стрелки.

  • 3 - Повернуть на 90 градусов по часовой стрелке и развернуть по вертикали.

Послесловие

FFmpeg очень мощный инструмент для обработки видео. С его помощью, имея шпаргалку по его возможностям, можно сэкономить много времени — куда быстрее ввести несколько команд, чтобы обработать видео, чем запускать редактор.

Если вы знаете еще полезные хитрости и трюки — милости прошу поделиться ими в комментариях. Спасибо!

Similar posts

Ads
AdBlock has stolen the banner, but banners are not teeth — they will be back

More

Comments 59

    0
    Может знает кто? Как совместить захват части экрана
    1. под виндовз
    2. чтобы был показ рамки вокруг захватываемой области
    3. чтобы со звуком
    Без рамки или без звука работает. Если с рамкой и звуком — захватывает черноту.
      +2
      ShareX всё это умеет. OpenSource, под капотом использует ffmpeg, можно кастомизировать параметры записи (я делаю сразу resize в 2 раза меньше, чтобы видео с 4k экрана было разумного размера).
      getsharex.com
        0

        Camtasia studio?
        OBS studio

          0
          Не, обсом все умеют. Тут челенж в том, чтоб сделать это скриптом и одной кнопкой. Нажал на и конку и запись пошла. Без лишних менюшек.
        0
        А есть под ffmpeg какая нибудь обертка, которая позволяет использовать его функционал без командной строки?
          +3
          HandBrake, но там, понятное дело, не весь функционал командной строки, а только самый базовый.
            +1
            Смотря что надо. Если просто пережатие видео без наворотов — вполне справляется VLC или
            handbrake.fr

            Если идти глубже, то лучше командная строка.
              0
              Machete (Trialware), XMedia Recode (Free), LosslessCut (Free), MyFFmpeg, Avanti, WinFF, AutoMKV и многое другое, ищите по запросу ffmpeg GUI
                +2
                Я коллекционировал разные команды ffmpeg под себя, а потом купил Wondershare UniConverter lifetime на распродаже и оказалось, что почти всё там гораздо удобнее и проще. Плюс ещё куча всего полезного, например, загрузка видео с разных хостингов.
                И как бы знаю и за youtube-dl, и за ffmpeg и всякие другие утилиты, но простой рабочий инструмент с GUI часто реально удобнее.
                  +7

                  ffmpeg это и есть обёртка, добавляющая командную строку. Можно без неё — изучить api libavformat и прочего. Оказалось что в целом это более-менее несложно, несмотря на отсутствие адекватной документации.


                  На самом деле я понял что ваш вопрос не об этом, но понял только после того, как прочёл ответы на него (вам нужно не "без командной строки" а "с гуи").

                    0
                    Avidemux, нашёл его как замену почившему VirtualDub (использую для вырезки кусочков видео и перекодировки)
                      +1
                      virtualdub2.com — тут попытались возродить, вроде неплохо получается
                        0
                        Благодарю
                      0
                      Использую FFQueue ffqueue.bruchhaus.dk
                        0
                        А смысл? Тогда уж легче редактор включить
                        –4
                        И сколько таких статей выходит на хабре каждый год, 2-3-5-10?
                          +10
                          В этом году пока была только вот эта :)
                            +4

                            С одной стороны да, все, что описано в статье гуглится на раз-два или ищется в мануалах. С другой стороны люди которые не в теме, могут и не знать, что библиотека умеет такие вещи делать.

                              +2

                              Мир вокруг нас изменчив…
                              Хотите вечно читать туторы 2009 года?

                              0

                              Для всего этого использую AviSynth. Там можно и Lua прикрутить и накладывать текст osd на видео и много чего еще.

                                0
                                Пользуясь случаем.
                                А как понизить количество кадров в секунду, не выбрасывая лишние кадры, а усреднив N кадров?
                                  +1

                                  Как вы хотите их усреднять? Если нужна интерполяция, то надо взять что-то типа SVP. Но результат будет не фонтан. И копать дальше в сторону DAIN.
                                  Если хотите как-то суммировать, то это ваш кастомный алгоритм — разбиваете на кадры, суммируете, склеиваете обратно в видео.

                                    +1

                                    virtual dub

                                    +4
                                    Команду обрезки по времени нужно дополнить тем, что если начало обрезаемого куска не попадает на ключевой кадр видео, начало видео может быть смазано, это выглядит некрасиво.
                                    Там был параметр, если мне память не изменяет, -noaccurate_seek, по которому FFmpeg старается сдвинуть начало обрезаемого куска так, чтобы оно на ключевой кадр попадало. Если же нужно точно задать при этом время начала, можно сохранить отдельно часть от начального кадра до следующего ключевого кадра с перекодированием в тот же формат, чтобы кадры перекодировались начиная с ключевого, а потом часть с ключевого кадра без перекодирования, и объединить их.
                                      –1
                                      Размещение видео рядом в одном кадре (stack video)

                                      А можно их по очереди разворачивать на весь экран, а потом снова сворачивать в уголок?

                                        +1
                                        Можно — см. «Обрезка видео по времени» + «Размещение видео рядом в одном кадре (stack video)» + «Склейка двух и больше видео в одно»
                                          +1

                                          А можно склеить без пережатия?

                                            +1
                                            Mkvtoolnix хорошо делает склейку без пересжатия — режим append.
                                              +2
                                              Можно, надо просто добавить -c:a copy -c:v copy
                                          0
                                          Воевал с ffmpeg осенью. Юзкейс — создание видео презентации по аудиозаписи и исходным слайдам.
                                          К сожалению, так и не получилось сделать в один проход сборку изображений в видео (с последующим наложением аудио). Файл собирался, но подручные программы-плееры его нормально не воспроизводили (слайды не менялись).

                                          Обошел так: сначала каждую картинку-слайд преобразовал в отдельное видео с нормальным фреймрейтом, потом склеил, потом наложил аудио. Пришлось написать небольшой питон-скрипт для разметки, но в целом работало.
                                            0
                                            Для Python есть библиотека moviepy, питоновская обертка над тем же ffmpeg и не только. Для приведенных в посте примеров-однострочников получится сильно длиннее, а для более сложных случаев начинает вполне иметь смысл.
                                              0
                                              Судя по import subprocess в коде, подозреваю, что эта обертка делает тоже, что и все остальные трэш-обертки: предоставляет отдельный интерфейс для формирования командной строки ffmpeg, а потом вызывает бинарник. Что во-первых, требует таскать этот бинарник с собой, а во-вторых, наследует весь гемморой с юникодными путями которым страдает сам ffmpeg (на дворе 2021й год, Карл!)
                                                0
                                                Откровенно говоря, как-то пох. Работать — работает, на сложных задачах мне удобнее написать и отладить питоновский скрипт, чем ломать пальцы в командной строке, а что там с юникодными путями — я вырос во времена MS DOS и до сих пор файлы без пробелов называю, куда мне в юникодные пути. Но, с другой стороны, если знаете что-то лучше, так скажите.
                                                  0
                                                  Ну я примерно так и делал в итоге. Просто досадно — таких оберток я уже видел штуки три, и все работают по одному и тому же принципу и с одними и теми же косяками. Но вот выше в комментах назвали libavformat, может, попробую к ней питоном прицепиться в следующий раз.
                                              +2

                                              Дорогие Друзья, те кто хотел несколько видео компоновать во фрейме, с анимированными сдвигами и прочими плюшками-хрюшками!
                                              Неожиданно: в blender (3D software) довольно неплохой секвенсор. С подрезками, смещениями, переходами, композитингом, цветовыми гаммами и прочими наворотами.
                                              Почему я вспомнил? Много всяких редакторов видео бывает: тяжеленные, условно бесплатные и соответственно, с ограничениями: то водяной знак, то ограничение размера, то ещё что-нибудь.
                                              А эта штука совсем свободная, почти ничего не весит, устанавливать не обязательно. Единственный минус — новичку сложно искать все настройки, нужно изучить гуй, хоткеи.
                                              В общем, видео-редактор там — огонь!
                                              Вот пример, что эта штука умеет делать с видео- и аудио-дорожками.

                                                +1
                                                Единственный минус — новичку сложно искать все настройки, нужно изучить гуй, хоткеи.

                                                Гуй в блендере довольно нестандартный всё-таки, для новичков проще будет освоиться с kdenlive (тоже полностью свободный, хватает для непрофессионального использования с головой).
                                                Заголовок спойлера
                                                Под виндой вроде какие-то проблемы с производительностью были, но может уже поправили, я не знаю.
                                                  0

                                                  Там с GUI намутили что-то несуразное. Революционный переворот: 2.7Х и 2.8Х два абсолютно разных интерфейса, порой диаметрально противоположные. Что было внизу — выкинули наверх, что было в настройках — теперь в "файл" и д. д.
                                                  Убрали H254.

                                                  0
                                                  Кстати, не подскажите по редактору видео в блендере. Есть ли там возможность связать (через редактор нод или еще как-то), редактор видео и 3D?

                                                  Скажем чтобы вывод какой-то камеры шел в редактор, там накладывались эффекты, а потом видеопоток из вьюпорта редактора в качестве текстуры накладывался на какой-то объект на сцене…

                                                  Понятно с промежуточным рендером в кадры это все можно сделать, но интересно можно ли это провернуть в реальном времени? Конечно логичнее использовать что-то вроде touchdesigner, но интересно насколько блендер универсален в этом плане.
                                                    0

                                                    Да, на видео-дорожку можно наложить 3D сцену. Причём не просто наложить, а с трекингом камеры или маркеров. Трекинг в блендере тоже есть.

                                                      0
                                                      Спасибо за ответ! А не подскажите где об этом посмотреть более подробно?

                                                      Вчера пробовал, но как-то оно неудобно, получается что положить можно любую сцену кроме текущей, а значит править сцену и сразу сразу видеть результат в монтажке — не получится? Плюс у меня какие-то проблемы с обновлением (после изменения сцена в видеоредакторе остается старой). В общем как-то оно нестабильно работает, но может я что-то делаю не так.

                                                      Кстати, а обратный процесс: назначить ввод видеоредактора в качестве текстура материала? Это возможно?
                                                        0
                                                        назначить ввод видеоредактора в качестве текстура материала? Это возможно?

                                                        Если правильно понял вопрос — то да, нода шейдера Image Texture принимает в числе прочих допустимых форматов на вход AVI файлы. Может и MPEG тоже принимает, не помню, но не удивлюсь.
                                                        Ещё можно распаковать на кадры и запихнуть нумерованной последовательностью(указать первый файл последовательности, которая вся размещена в одной директории, перевести тип в Image Sequence, указать начальный и конечный кадр и тип зацикливания, включая отсутствие зацикливания).


                                                        Upd. Впрочем, не факт. Вы, возможно, хотите результат видеоредактора блендера сразу в ту же сцену помещать как часть материала объекта — и в таком прочтении я не уверен что можно сделать, но тут просто не знаю, не копал.

                                                          0

                                                          Да, я, конечно, хочу видеть результат в именно реальном времени, без промежуточного просчёта в файл.


                                                          Пока похоже, что это сделать нельзя.

                                                            0
                                                            Да, я, конечно, хочу видеть результат в именно реальном времени

                                                            Так не получится, сам текстурируемый объект ещё не просчитан.

                                                          +1

                                                          В блендере не всё так однозначно. Видеоредактора как такового нет, есть выходной секвенсор, всё что там компонуется — отдаётся на рендер. Для сцены в качестве текстуры нельзя брать что-то из секвенсора. На сцене объектам можно назначать видео-текстуры. В секвенсоре можно добавлять любые созданные или загруженные сцены, в т. ч. — несколько.
                                                          Подробно посмотреть здесь, по разделам.

                                                            +1
                                                            Спасибо за ответ!

                                                            Я примерно так и понял, что редактор, по сути, только позволяет в простых случаях уйти от шага «рендерим каждую сцену и монтируем», и получить готовый видеофайл «за один заход». Тоже неплохо на самом деле. Может не настолько универсально как хотелось бы, и не позволяет полноценно использовать блендер еще и как мультимедия-сервер для различных шоу и пр. Но никто такой функционал и не обещал:)
                                                    0
                                                    Прошло 6 лет, задам вопросы:
                                                    1) починили конкотинацию в виндовс?
                                                    ffmpeg -i «copy:1.jpg|2.jpg» out.gif
                                                    2) добавили конкотинацию с полными путями в линуксе?
                                                    ffmpeg -i «concat:/home/userMo/test/dir1/4.jpg|/home/userMo/pics/late/sada_342.jpg» -loop -1 out.gif
                                                    3) склейка видео с разными разрешениями, добавили режим cover? с вычислением минимальной ширины\высоты из ВСЕХ видео чтобы от неё отталкиваться для соотношения сторон?
                                                      +1
                                                      Сетку проще челать с помощью фильтра tile.

                                                      Обрезка видео для большинства современных кодеков будет крайне не точной при использовании «кодека» copy, особенно если ключевые кадры будут достаточно редко идти.
                                                      А вообще, не в обиду, но я не понял смысл этой заметки, даже если от новичка новичку информации довольно мало…

                                                      0

                                                      Самый мною частый сценарий использования ffmpeg — перегон аудио файла в формат opus, в моно, с битрейтом 8кб/с и сжатием динамического диапазона встроенным аудиофильтром -af compand. Это для голосового контента (интервью, аудиокнига, пранк). Файл получается без перепадов по громкости (бесит когда один орет а второго еле слышно) с очень малым размером и качеством, достаточным для разговорного жанра.


                                                      Второй сценарий — заготовленный пресет под старый телевизор, ffmpeg очень хорошо умеет аппаратно кодировать видео, и на моей ноутбучной 1050ti, двухчасовой фильм в формате fullhd пережимается в p720 h264 за считанные минуты.


                                                      Третий сценарий — сделать из любого видео — плавные 60 fps фильтром minterpolate=fps=60. Иногда это выглядит даже без артефактов, особенно геймплеи игр.

                                                        0

                                                        А вырезание фрагмента без перекодирования есть?

                                                          +2

                                                          Есть -c:v copy

                                                          0
                                                          А могут гуру помочь решить такую задачу: взять видео с камеры, и разбить поток на два, один закодировать в h.264 и отправить в tcp, а второй с меньшим fps и разрешением без кодирования (raw yuv) выдать в другой tcp поток (скажем исходный fps 15 и разрешение 720p а без кодирования сделать 5 fps и разрешение 320х200). такой режим нужен бы для мобильного робота, чтобы транслировать видео человеку и его же (видео), но в «упрощенном» виде обрабатывать техническим зрением.
                                                            0

                                                            Информацию о кодировках можно в официальной документации найти, по поводу передачи — проще за все сделать через nginx rtmp модуль, в контейнере rtmp будет ниже задержка, но с его проигрыванием напрямую в браузере возникнут трудности — поддержка rtmp выпиливается, а в контейнере hls, задержка више будет, но откроется в хроме напрямую.

                                                              +1
                                                              НУ дело в том что raw видео я никуда по сети передавать не собираюсь, в «соседний» процесс, казалось бы nginx мне не нужен, да и сжатый поток лучше передавать например через вебсокеты, вопрос как разделить один поток с камеры на два таких разных потока…
                                                                0

                                                                Два разных приложения в одно время не смогут получить с usb камеры поток, нужно с ffmpeg стримить на себя, а потом доставать этот поток с двух других приложений, например с двух других инстансов ffmpeg, и делать с потоками уже что угодно. Но если у вас ip камера, то, в зависимости от модели, можно к ней создать несколько подключений, обычно (1-4). Создайте 2 подключения через
                                                                ffmpeg -i,
                                                                обработайте, и через
                                                                -f flv rtmp://myserver/live/mystream
                                                                делитесь с другими приложениями. Ну, или, напрямую, например, через opencv python доставайте потоки через
                                                                camera = cv2.VideoCapture("IP:PORT/video")

                                                            +2

                                                            Статья в целом и неплохая, но только как введение в тему. Я ожидал немного больше аналога "Hello world" под заголовком "Хитрости и трюки".


                                                            Ещё очень полезно знать про разные кодировщики и декодировщики, так как аппаратное ускорение кодирования может снизить время в разы. Из ещё менее известного — другие утилиты из пакета, например ffplay, передача по сети через UDP/TCP даже с поддержкой multicast.


                                                            P.S.: справедливости ради, ffmpeg как утилиту почти никто не использует, всё-таки пользуются библиотечным интерфейсом.

                                                              +1

                                                              Спасибо, очень полезная статья.
                                                              Взял себе на вооружение.
                                                              Автору респект

                                                                +1
                                                                Самая главная фича ffmeg это возможность pipe как по мне. Что в свою очередь дает уже возможности по потоковой обработке видео не на одном компутере, а на кластере. И почему то в статьях о ffmpeg об этом часто не упоминают, даже вскользь.

                                                                Only users with full accounts can post comments. Log in, please.