Как я могу подогнать видео под определенный размер, но не масштабировать его с помощью FFmpeg?

Мне нужно, чтобы соответствовать видео до 640x360 (максимум плеер моего телефона может обрабатывать), а также сохранение пропорций, но я также хочу, чтобы видео быть неизменным, если он меньше чем 640х360 (не масштабирование это, в конце концов).

есть ли способ получить это поведение с помощью командной строки ffmpeg?

29
задан slhck
18.11.2022 14:39 Количество просмотров материала 3324
Распечатать страницу

3 ответа

С более новыми версиями ffmpeg, вы можете использовать scale фильтр force_original_aspect_ratio option. Например, чтобы поместить видео в размер 1280×720 без масштабирования (см. этот пост для получения дополнительной информации):

ffmpeg -i input.mp4 -filter:v "scale='min(1280,iw)':min'(720,ih)':force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2" output.mp4

здесь scale фильтр масштабируется до 1280×720, если входное видео больше. Если он меньше, он не будет масштабироваться. The pad фильтр необходим, чтобы вывести выходное видео на 1280×720, если его соотношение сторон или размер отличается от целевого размер.


С более старыми версиями ffmpeg есть несколько хакерский обходной путь. Сначала определите ширину, высоту и соотношение сторон выходных данных. Это избавит нас от необходимости печатать.

width=640; height=360
aspect=$( bc <<< "scale=3; $width / $height") # <= floating point division

теперь давайте применим супер сложную команду фильтра, которая Джим Уорролл написал:

ffmpeg -i input.mp4 -vf "scale = min(1\,gt(iw\,$width)+gt(ih\,$height)) * (gte(a\,$aspect)*$width + \
lt(a\,$aspect)*(($height*iw)/ih)) + not(min(1\,gt(iw\,$width)+gt(ih\,$height)))*iw : \
min(1\,gt(iw\,$width)+gt(ih\,$height)) * (lte(a\,$aspect)*$height + \
gt(a\,$aspect)*(($width*ih)/iw)) + not(min(1\,gt(iw\,$width)+gt(ih\,$height)))*ih" \
output.mp4

Я не буду вдаваться в объяснения того, что все это делает, но в основном вы можете кормить его любым видео, и это будет только масштабирование, а не масштабирование. Если вы для этого можно разделить фильтр на отдельные выражения. Возможно, это можно сократить, но это также работает.

6
отвечен slhck 2022-11-19 22:27

более читаемая версия может выглядеть следующим образом:

-filter_complex "scale=iw*min(1\,min(640/iw\,360/ih)):-1"

640 / iw-коэффициент горизонтального масштабирования, а 360 / ih-коэффициент вертикального масштабирования

вы хотите разместить масштабированное изображение внутри выходного окна и сохранить соотношение сторон (для хранения). Это можно сделать, выбрав наименьший коэффициент масштабирования с функцией minimum: min (640/iw, 360/ih)

вы хотите предотвратить любое масштабирование (т. е. коэффициент масштабирования > 1.0), поэтому вы добавляете еще одну минимальную функцию: min (1, min (640/iw, 360/ih))

следующим шагом является вычисление выходного разрешения путем умножения коэффициента масштабирования на input-width и input-height:

output-width = iw * min(1, min(640/iw, 360/ih))

output-height = ih * min(1, min (640/iw, 360/ih))

последний шаг-создание команды фильтра. Нет необходимости указывать выходную высоту, вы можете указать -1, и ffmpeg сохранит пропорции, применяя тот же коэффициент масштабирования, что и для ширина.

10
отвечен immerzl 2022-11-20 00:44

У меня тоже была такая же проблема, но решена путем установки видео в квадрат 640x640 (из-за вертикальных видеороликов, сделанных со смартфонами).

так с помощью immerzi логика и некоторые исследования, я в конечном итоге с этим:

-vf "scale=iw*min(1\,if(gt(iw\,ih)\,640/iw\,(640*sar)/ih)):(floor((ow/dar)/2))*2"

последняя часть для высота делится на 2, что нужно много датчиков.

4
отвечен Shebuka 2022-11-20 03:01

Постоянная ссылка на данную страницу: [ Скопировать ссылку | Сгенерировать QR-код ]

Ваш ответ

Опубликуйте как Гость или авторизуйтесь

Имя
Вверх