Я новичок в ffmpeg и не знаю, как продолжить.
У меня есть два видео, которые я хотел бы объединить в одно видео с наложением цвета фона/изображения.
Изображение ниже — это то, чего я пытаюсь добиться, прямоугольник — это основное видео, круг — это другое видео, а красный цвет — это фоновый цвет/изображение.
информация о видео:
один.mp4
исходный размер: 1280x720
положение/размер: (x20, y20, w980, h:keep-aspect-ratio)
два.mp4
исходный размер: 1280x720
положение/изменение размера: (x-внизу, y-внизу-слева, w:keep-aspect-ratio, h200)
Пока мне удалось добавить только bg-color, но с проблемой пропал звук, не говоря уже о том, что я даже не добавил второе видео как часть своей команды.
ffmpeg -f lavfi -i color=c=white:s=1920x1080:r=24 -i video.mp4 -filter_complex "[0:v][1:v]overlay=shortest=1,format=yuv420p[out]" -map "[out]" output.mp4
Любое предложение о том, как этого достичь? Заранее спасибо.
200 был для круга, но я могу понять, что вы имеете в виду, поскольку круг / круг - это маска поверх двух.mp4
Я отредактировал свой ответ с помощью новой команды. Попробуйте
[править 19 марта: добавлена полная команда для нужд ОП]
Попробуй это:
ffmpeg -i one.mp4, -i two.mp4, \
-f lavfi -i color=c=white:s=1920x1080:r=30 \
-f lavfi -i color=c=white:s=400x400:r=1,\
format=yuva444p,\
geq='lum(X,Y)':'cb(X,Y)':'cr(X,Y)':\
a='if (lt((X-200)^2+(Y-200)^2,200^2),0,255)' \
-filter_complex \
[0:v]scale=980:-1[L0];\
[1:v]crop=600:600:20:20,scale=400:-1[L1];\
[L1][3:v]overlay=shortest=1[L2];\
[2:v][L0]overlay=20:20:shortest=1[L3];\
[L3][L2]overlay=W-420:H-420[vout] \
-map [vout] -map 0:a output.mp4
color
(2:v
): служит фоновым холстом. Его частота кадров r=30
будет выходной частотой кадров.color
(3:v
): это круглая маска для обрезанного two.mp4
. Обратите внимание, что я исправил фильтр geq
, чтобы цвет сохранялся должным образом (мой предыдущий дубль был сделан для видео в градациях серого)one.mp4
(0:v
) масштабируется до окончательного размера -> [L0]
two.mp4
(1:v
) сначала обрезается до квадрата, захватывая то, что должно быть показано в круглом вырезе. crop
аргументы — это w:h:x:y
, где x:y
— координата верхнего левого угла. Затем обрезанный кадр масштабируется до конечного размера (400x400
в этом примере) -> [L1]
two.mp4
([L1]
) маскируется вводом 3:v
, чтобы показать его через круглый вырез с первым фильтром overlay
.shortest=1
опция для overlay
фильтров, которые заканчиваются, когда заканчивается видео (а не color
источники, которые будут продолжаться вечно)overlay
помещают 2 подготовленных видео в нужные места на холсте. При необходимости отрегулируйте его аргументы, чтобы изменить позицииscale
из графика фильтров. Для one.mp4
подходит первая цепочка фильтров, поэтому замените метку [L0]
на [0:v]
в измененном графике фильтров.Это должно сработать. Как мы уже говорили ранее, когда вы запускаете его, убедитесь, что вы удалили все пробелы, новые строки и обратную косую черту в середине каждого выражения filtergraph.
[оригинал]
Подход, который я реализовал в прошлом, состоит в том, чтобы манипулировать маскирующим изображением с помощью фильтра geq
. Вы можете попробовать следующее:
Для иллюстрации я использую прямоугольник с левым верхним углом в точке (10,10) и правым нижним углом в точке (1500 900) и круг с центром в точке (1700 950) и радиусом 100.
ffmpeg -i input.mp4 \
-vf color=c=red:s=1920x1080:r=1:d=1,\
format=rgba,\
geq=lum='lum(X,Y)':a='if (between(X,10,1500)*between(Y,10,900)+lt((X-1700)^2+(Y-950)^2,100^2),0,255)',\
[v:0]overlay \
output.mp4
color
исходный фильтр генерирует только 1 кадр (1 кадр/с за 1 секунду) и overlay
применяет его к каждому кадру входного видеоcolor
вывод не имеет альфа-канала, поэтому вам нужно конвертировать в pix_fmtgeq
устанавливает альфа-значения всех пикселей: если координата (X,Y)
замаскирована (поэтому она присваивает альфа-значение 255 = непрозрачная) или True, если (X,Y)
не замаскирована (альфа = 0, 100% прозрачность). См. Документация по выражениям FFmpeg.overlay
получает входной видеопоток v:0
и накладывает на него выход geq
фильтра.-vf
, входной аудиопоток будет отображаться автоматически.[редактировать однострочную версию]
ffmpeg -i input.mp4 -vf color=c=red:s=1920x1080:r=1:d=1,format=rgba,geq=lum='lum(X,Y)':a='if (between(X,10,1500)*between(Y,10,900)+lt((X-1700)^2+(Y-950)^2,100^2),0,255)',[v:0]overlay output.mp4
Спасибо @kesh, когда я испортил эту команду, я получил синтаксическую ошибку следующей ошибки рядом с неожиданным токеном ("` и после помещения всего в один поток ffmpeg -I video.mp4 -vf 'color=c=red:s=1920x1080:r=1:d=1,format=rgba, geq=lum=lum(X,Y):a=if (between(X,10,1500)*between(Y,10,900)+lt((X-1700)^2+(Y-950)^2,100^2),0,255),[v:0]overlay' output.mp4
я получил еще одну ошибку Missing ')' or too many args in 'lum(X
(1) У меня есть лишний '
прямо перед color
(исправлено в посте), поэтому, пожалуйста, удалите (2) когда вы делаете это одной длинной строкой, убедитесь, что после ,
нет пробела в графе фильтра
Спасибо, после обновления вылезла еще одна ошибка Unable to find a suitable output format for 'format=rgba,' format=rgba,: Invalid argument
Я добавил однострочную версию в конце поста, попробуйте (я знаю, что это сложно сделать правильно)
Я пробовал одиночную версию и столкнулся с ошибкой. Missing ')' or too many args in 'lum(X' [AVFilterGraph @ 0x123e0a050] Error initializing filter 'geq' with args 'lum=lum(X' Error reinitializing filters! Failed to inject frame into filter network: Invalid argument
У меня должно быть неправильное экранирование (обычно я тестирую его на Python и публикую то, что я считаю версией командной строки). Посмотрите, что произойдет, если поставить обратную косую черту (\) перед всеми кавычками '
Спасибо, скрипт работает, хотя я не могу добиться того, что ищу (возможно, я недостаточно хорошо сформулировал свой вопрос). То, что я получаю, это изображение/рисунок поверх видео
Думаю, я ошибся в своем предложении. Я почему-то думал, что у тебя 1 видео и 1 маска, а не 2 видео и маска. Вы можете упростить маску, так как большое видео не нужно маскировать. Я вернусь к вам позже сегодня для полного решения.
Не могли бы вы добавить размеры исходных видео (один.mp4 и два.mp4) и расположение этих видео на выходном видео: (x0, y0, w, h) одного.mp4 и расположение круга на two.mp4, а также на output.mp4. Если бы вы могли добавить эту информацию в свой пост, я могу придумать точную необходимую команду.
Я добавил некоторую информацию, дайте мне знать, если это имеет смысл. Спасибо
Большое спасибо, новая добавленная команда работает!! визуал выглядит как надо, но звук не работает, есть идеи, как это исправить?
Что ты хочешь делать? Звук с какого входа воспроизводить? Или вы хотите смешать оба корма?
Я хотел бы сохранить звук из one.mp4
Добавить второй вариант -map
как отредактированный ответ
Спецификация для two.mp4 недостаточна/неясна. Вы хотите уменьшить масштаб видео до 200x112, а затем поместить центр круга в (180, 92) с радиусом 20? (цифры кажутся слишком маленькими, чтобы быть правильными)