10

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

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

3 ответа3

10

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

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

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

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

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

Следующим шагом является вычисление выходного разрешения путем умножения масштабного коэффициента на input-width и input-height:
ширина вывода = iw * min(1, min(640/iw, 360/ih))
Выходная высота = ih * min(1, min(640/iw, 360/ih))

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

9

С новыми версиями FFmpeg, вы можете использовать опцию scale force_original_aspect_ratio фильтра. Например, чтобы разместить видео в разрешении 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, если входное видео больше этого. Если он меньше, он не будет увеличен. 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

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

4

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

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

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

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .