Страницы

Поиск по вопросам

среда, 10 июля 2019 г.

Склейка видео с помощью ffmpeg

Добрый день, встала задача склеить несколько видео в одно (количество видео всегда разное (т.е. возможно 1, возможно 2, возможно n), собственно нагуглил такой вот пример:
ffmpeg -i new_1.mp4 -i new_2.mp4 -i new_3.mp4 -i new_4.mp4 -filter_complex "nullsrc=size=640x480 [base]; \ [0:v] setpts=PTS-STARTPTS, scale=320x240 [upperleft]; \ [1:v] setpts=PTS-STARTPTS, scale=320x240 [upperright]; \ [2:v] setpts=PTS-STARTPTS, scale=320x240 [lowerleft]; \ [3:v] setpts=PTS-STARTPTS, scale=320x240 [lowerright]; \ [base][upperleft] overlay=shortest=1 [tmp1]; \ [tmp1][upperright] overlay=shortest=1:x=320 [tmp2]; \ [tmp2] [lowerleft] overlay=shortest=1:y=240 [tmp3]; \ [tmp3][lowerright] overlay=shortest=1:x=320:y=240" -c:v output.mp4
в данном примере идет склейка 4-х видео, но не совсем понимаю, возможно ли вместо upperright - писать позицию видео?
пример. положим что канва на которой работает будет 1280 на 768 и у нас есть 6 видео (все видео одинакового размера, но имеют разную продолжительность, положим что размер одного видео 1024 на 768). Пробуем разместить их в две строки, по три видео на строку. получаем следующие размеры для видео: ширина: 1280/3 = 426 пикселей высота: 768 / 2 = 384, где 2 - количество строк
собственно вопросы: 1) могу ли я задавать позицию видео не так
[0:v] setpts=PTS-STARTPTS, scale=320x240 [upperleft];
а вот так например:
[0:v] setpts=PTS-STARTPTS, scale=426x384 [0,384];
[1:v] setpts=PTS-STARTPTS, scale=426x384 [426,384];
или как-то по другому? как правильно сделать сетку в ffmpeg?
2) в случае с видео, которые разные по времени, по истечению самого короткого видео картинка дальше тормозиться, но звуковая дорожка идет, как решить данные вопрос? подогнать короткое видео по таймингу к самому длинному? тогда как это делается? нечто вроде заполняем 4-ми кадрами остаток?
спасибо за помощь.


Ответ

upperleft здесь - это не позиция, а псевдоним для потока-результата scale
[0:v] setpts=PTS-STARTPTS, scale=320x240 [upperleft];
Взять поток 0:v, пожать его до 320x240 и обозвать upperleft для дальнейшего использования. Здесь видео пока никак не компонуется с другими - только пережимается до нужного размера.
[base][upperleft] overlay=shortest=1 [tmp1]
Взять потоки base и upperleft, применить overlay с такими параметрами и выдать результат в поток tmp1. Сами имена потоков могут быть любые. Вот тут как раз и идёт склейка видео.
Позиция оверлея на результирующем потоке - это параметры overlay x и y, которые видны в последних 3 строках. Вот список возможных параметров. По второму вопросу посмотрите eof_action и repeatlast
Для 6 видео что-то вроде этого получится:
ffmpeg -i new_1.mp4 -i new_2.mp4 -i new_3.mp4 -i new_4.mp4 -i new_5.mp4 -i new_6.mp4 -filter_complex "nullsrc=size=1280x768 [base]; \ [0:v] setpts=PTS-STARTPTS, scale=426x384 [upper1]; \ [1:v] setpts=PTS-STARTPTS, scale=426x384 [upper2]; \ [2:v] setpts=PTS-STARTPTS, scale=426x384 [upper3]; \ [3:v] setpts=PTS-STARTPTS, scale=426x384 [lower1]; \ [4:v] setpts=PTS-STARTPTS, scale=426x384 [lower2]; \ [5:v] setpts=PTS-STARTPTS, scale=426x384 [lower3]; \ [base][upper1] overlay=shortest=1 [tmp1]; \ [tmp1][upper2] overlay=shortest=1:x=426 [tmp2]; \ [tmp2][upper3] overlay=shortest=1:x=852 [tmp3]; \ [tmp3][lower1] overlay=shortest=1:y=384 [tmp4]; \ [tmp4][lower2] overlay=shortest=1:y=384:x=426 [tmp5]; \ [tmp5][lower3] overlay=shortest=1:y=384:x=852" -c:v output.mp4

Комментариев нет:

Отправить комментарий