58

У меня есть html 5 видеоплеер, который имеет ширину 700 пикселей и высоту 400 пикселей. Я пытаюсь использовать avconv чтобы использовать ffmpeg для изменения размера (при сохранении соотношения сторон) и проверяю, подходит ли он моему проигрывателю.

Входными данными может быть файл любого размера, поэтому мне нужно изменить размер больших файлов, но центрировать меньшие с черными полосами. До сих пор я пробовал: -s и -aspect , я видел использование pad с ключом -vf но не понимаю, как он работает достаточно, чтобы получить то, что мне нужно.

Изображений

Это грубое представление о том, что мне нужно. Я не уверен, возможно ли это вообще. Это почти как CSS max-width/max-height. Я понимаю, что это может быть просто путаница слов, но если кто-то поймет, о чем я говорю, буду признателен за помощь, спасибо.

команда avconv:

avconv -y -i control.avi -vcodec libx264 -b 2000k -bufsize 20M -acodec aac -strict experimental -ar 44100 -ab 256k bigbuck_out.mp4

3 ответа3

59

Вот команда, которая добавит столб или почтовый ящик для фиксированной ширины вывода. Это немного долго, но вы должны будете указать отступы каким-то образом.

Сначала в вашей оболочке определите ширину и высоту вывода:

width=700
height=400

Затем выполните команду:

ffmpeg -i in.mp4 -filter:v "scale=iw*min($width/iw\,$height/ih):ih*min($width/iw\,$height/ih), pad=$width:$height:($width-iw*min($width/iw\,$height/ih))/2:($height-ih*min($width/iw\,$height/ih))/2" out.mp4

Это урезано до самого необходимого, необходимого для изменения размера и дополнения - добавьте ваши другие видео и аудио параметры, как вы считаете нужным. Обратите внимание, что числа для width и height должны делиться на 2, чтобы работать для большинства кодеков.

Вот объяснение того, что происходит:

  • Масштабирование:
    • Сначала нам нужно выяснить, масштабировать ли по ширине или высоте.
    • Чтобы сделать это, мы разделим ширину вывода на ширину ввода, а высоту вывода на высоту ввода. Это даст нам масштабные коэффициенты для каждого измерения.
    • Затем мы проверяем, какой из них ниже (с помощью min()), и выбираем только этот коэффициент для изменения размера.
    • Наконец, мы умножаем ширину и высоту ввода на этот коэффициент (iw*min(…):ih*min(…)).
  • Обивка:
    • $width:$height - ширина и высота вывода
    • Чтобы выяснить, где разместить полученное видео, нам нужно вычесть масштабированную ширину из максимальной выходной ширины и масштабированную высоту из максимальной выходной высоты.
    • Масштабированные ширины и высоты являются выражениями из фильтра scale .
    • Мы делим полученное смещение на 2, чтобы добавить границы с обеих сторон.
42

Простой метод - использовать опцию force_original_aspect_ratio в фильтре масштабирования.

исходное изображение
Исходное изображение. Представляет видео с форматным соотношением 640x480, 4:3.

В этих примерах исходное изображение будет масштабировано для соответствия форматному соотношению 16:9 с сохранением исходного форматного соотношения. Для этого вы можете:

Pillarbox или почтовый ящик

изображение в виде столба
Pillarboxed изображение. Установка входа 640x480 (4:3) на выход 1280x720 (16:9).

ffmpeg -i input -vf "scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2" output
  • Это увеличит изображение. Если вы хотите избежать масштабирования, посмотрите пример ниже.

  • Вместо этого будет использоваться форматирование по буквам, если входное соотношение сторон шире, чем выходное соотношение сторон. Например, ввод с соотношением сторон 2,35:1, вписывающийся в вывод 16:9, приведет к почтовому ящику.

То же, что и выше, но без апскейлинга

без апскейлинга
Вход 640x480 (4:3) на выход 1280x720 (16:9) без увеличения.

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

урожай


Обрезанное изображение. Соотношение сторон 4:3, соотношение сторон 16:9.

ffmpeg -i input -vf "scale=1280:720:force_original_aspect_ratio=increase,crop=1280:720" output
8

Мне кажется, что вам нужно сделать это в три этапа:

  1. Проверьте входное соотношение сторон
  2. Масштабируйте видео с DAR> 7/4 по ширине (измените ширину на 700 и масштабируйте высоту, чтобы сохранить соотношение сторон), и масштабируйте видео с DAR <7/4 по высоте
  3. Дополните видео так, чтобы оно уместилось в пространстве 700:400.

FFmpeg/avconv может выполнять масштабирование / заполнение с помощью видеофильтров за один шаг, транскодируя только один раз. Например, чтобы взять видео в формате 16:9, масштабировать его по ширине, а затем пометить в поле результаты:

ffmpeg -i input.avi -filter:v 'scale=700:-1,pad=700:400:(ow-iw)/2:(oh-ih)/2' \
-c:v libx264 -b:v 2000k -bufsize 20M -c:a aac -strict experimental -ar 44100 -b:a 256k output.mp4

... но для первого шага (определение соотношения сторон и сравнение его с требуемым 7:4) вам придется использовать какой-то скрипт.

ffprobe input.avi 2>&1 | sed -n '/Video:/s/.*DAR \([0-9]*:[0-9]*\)].*/\1/p'

... вы получите соотношение сторон видео, которое будет выглядеть как «16:9» или «4:3». В скрипте bash я бы использовал что-то вроде:

#!/bin/bash

##  Get the aspect ratio in the form x/y
dar=$(ffprobe test0.mp4 2>&1 | sed -n '/Video:/s/.*DAR \([0-9]*:[0:9]*\)].*/\1/p' | sed 's|:|/|')
##  use bc to do x/y*100 (bash can't handle floats)
DAR=$(bc <<< 'scale=2; $dar*100')

##  ${DAR%.00} will remove the trailing .00 left by bc
if [ ${DAR%.00} -ge 175 ]; then
    ffmpeg -i "$1" -filter:v 'scale=700:-1,pad=700:400:(ow-iw)/2:(oh-ih)/2' \
    -c:v libx264 -b:v 2000k -bufsize 20M -c:a aac -strict experimental -ar 44100 -b:a 256k "${1%.*}.mp4
else
    ffmpeg -i "$1" -filter:v 'scale=-1:400,pad=700:400:(ow-iw)/2:(oh-ih)/2' \
    -c:v libx264 -b:v 2000k -bufsize 20M -c:a aac -strict experimental -ar 44100 -b:a 256k "${1%.*}.mp4
fi

exit 0

Очевидно, вам придется адаптировать его к вашим потребностям.

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