Изменить размер видео с помощью ffmpeg - сохранить соотношение сторон

Я пытаюсь написать скрипт для телеграммы userbot, который может конвертировать любое видео / анимацию в .mp4, У меня уже есть, поэтому скрипт связывает и использует API https://cloudconvert.com/.

Теперь моя проблема заключается в команде ffmpeg, которую я передаю в CC, так как мне нужно, чтобы видео было меньше 1280 пикселей по обе стороны. Неважно, будет ли конечное видео 720*1280 или 1280*1280 или что-то совсем другое, если ни одна из двух сторон не превосходит 1280 пикселей.

Здесь начинается сложная часть: я не хочу портить соотношение сторон и не хочу увеличивать масштаб видео, если оно меньше 1280.

Часть кода, которая на самом деле актуальна, это часть масштаба. Этот следующий фрагмент изменит размер видео до максимальной 1280 пикселей в высоту, но не учитывает ширину, он просто сохраняет соотношение.

-vf "scale=min'(1280,iw)':-2"

Теперь, как я должен был бы или адаптировать это или изменить это так, чтобы это фактически изменило размер в зависимости от того, какая сторона больше чем 1280 пикселей?

Я надеюсь, что я достаточно конкретен и с нетерпением жду вашей помощи.

1 ответ

Решение

Проблема появляется только, если высота больше, чем ширина, это увеличивает количество ограничений для ширины с 2 до 3:

  • ширина должна быть меньше или равна 1280 (не превышать ширину)
  • ширина должна быть меньше или равна начальной ширине (не масштабировать)
  • ширина должна быть меньше или равна 1280* ширина / высота (не превышать высоту)

Чтобы проверить для всех случаев, вы бы использовали min(1280,min(iw,round(1280*iw/ih))), создавая фильтр

-vf "scale=min(1280,min(iw,round(1280*iw/ih))):-2"

РЕДАКТИРОВАТЬ

В некоторых версиях ffmpeg вышеприведенная строка не будет работать, ссылаясь на проблемы с самоссылкой. В этом случае мы можем создать альтернативную линию мышления:

  • Если ширина больше (или равна) высоты, мы масштабируем по ширине, используя min(iw,1280)
  • Если высота больше ширины, мы масштабируем по высоте, используя min(ih,1280)

Тогда выражение будет -vf 'scale=if(gte(iw,ih),min(1280,iw),-2):if(lt(iw,ih),min(1280,ih),-2)'

Не забывайте, что вы можете запустить это через какой-то механизм разбора оболочки, который дополнительно создаст необходимость экранировать запятые. Выражение

-vf 'scale=if(gte(iw\,ih)\,min(1280\,iw)\,-2):if(lt(iw\,ih)\,min(1280\,ih)\,-2)'

Проверено на работу с версиями 2.7.2 до 3.4.4 на Ubuntu Linux

ffmpeg -i a.mp4 -vf "scale=:-1:force_original_aspect_ratio=decrease"
Другие вопросы по тегам