Изменить размер видео с помощью 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"