Как я могу уменьшить размер видео с ffmpeg?

(адаптированный от моего ответа до более раннего, подобного вопроса о пакетах, установленных из источника)

Если Вы начнете иметь много программ, установленных вне Вашего распределения, то Вы начнете сталкиваться с проблемами управления пакета: какую версию нечто я установил? Какие файлы принадлежат нечто, так, чтобы я мог удалить его (если Вам смешали нечто с другими пакетами)? Я устал от добавления еще одного каталога к моему PATH (если у Вас есть нечто в собственном каталоге). Таким образом, я рекомендую использовать некоторую форму управления пакетом.

Уберите диспетчер пакетов плохого человека. Принцип должен сохранить каждый пакет в своем собственном каталоге, но поддержать символьные ссылки в стандартных каталогах.

  • Установка под /usr/local/stow/PACKAGE-VERSION (или ~/usr/stow/PACKAGE-VERSION или везде, где). (PACKAGE и VERSION представьте имя и версию пакета. Эти имена для Вашего удобства только.)
  • Если Вы выбрали каталог кроме /usr/local/stow, добавить ~/usr/bin (или везде, где) к Вашему PATH.
  • Выполненный stow PACKAGE-VERSION от /usr/local/stow (или …) каталог. Это создает символьные ссылки в “нормальных” каталогах, например. /usr/local/bin/foo-command -> ../../stow/foo-4.2/bin/foo-command.
  • Если Вы когда-нибудь хотите удалить эту программу, просто работать stow -D PACKAGE-VERSION удалить символьные ссылки и удалить /usr/local/stow/PACKAGE-VERSION.

Существует также xstow, который является подобными, но более мощными программами (одно из его преимуществ - то, что это может иметь дело с конфликтами).

222
11.01.2012, 10:38
11 ответов

См. этот ответ. Заключенный в кавычки ниже для удобства:

Вычислите скорость передачи, в которой Вы нуждаетесь путем деления 1 ГБ на видео длину в секундах. Так, для видео длины 16:40 (1 000 секунд), используйте скорость передачи 1 000 000 байтов/секунда:

ffmpeg -i input.mp4 -b 1000000 output.mp4

Дополнительные опции, которые могли бы быть достойными рассмотрения, устанавливают Постоянный Фактор Уровня, который понижает среднюю скорость передачи данных, но сохраняет лучшее качество. Варьируйтесь CRF приблизительно между 18 и 24 — чем ниже, тем выше скорость передачи.

ffmpeg -i input.mp4 -vcodec libx265 -crf 20 output.mp4

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

303
27.01.2020, 19:28
  • 1
    Second, с помощью -crf 24 снял видео 255.3 МБ, я имел и уменьшил его до 72.7 МБ, не понижая качество заметно. Имейте upvote! –  Patrick Roberts 25.03.2017, 20:14
  • 2
    Выразительно уменьшенный ~2G видео до 14 МБ, все еще хорошие взгляды, это было первым результатом поиска, и это точно, что я искал, Спасибо! –  sinisterstuf 30.03.2018, 15:20
  • 3
    Могло бы быть хорошим, чтобы отметить, что можно теперь использовать libx265 еще для большего количества сокращения размера. –  ZN13 13.04.2018, 22:55

Вам нужно будет использовать двухпроходное кодирование, чтобы «подогнать» видео под заданный размер файла (битрейт), не слишком сильно снижая качество. Это довольно подробная тема: http://web.archive.org/web/20171130050515/http://www.mpabo.com/2014/12/14/ffmpeg-and-x264-encoding-guide/

2
27.01.2020, 19:28

Если вы не ищете конкретный битрейт, я бы порекомендовал вариант -crf . Это наиболее часто используется для кодирования x264 : http://slhck.info/articles/crf

Вкратце: CRF 23 сделает фильм качества "DVD" (~ 700 МБ -1 ГБ) и более низкие значения CRF будут более качественными (файлы большего размера).

34
27.01.2020, 19:28

У меня есть рецепт, который я изначально придумал для себя, чтобы преобразовать видео в формате Motion JPEG, создаваемое моей старой камерой (это очень большие видео, поскольку каждый кадр представляет собой целое изображение JPEG) в формат h264. Вот адаптация для других видов видео (курсов и т. Д.).

Я использую не ffmpeg , а mplayer и mencoder . Во-первых, мы должны демультиплексировать звук с помощью mplayer:

mplayer -vo null -ao pcm:fast:file=<audio_pcm.wav> <video>
  • Параметры -vo null и -ao null указывают mplayer не извлекать видео.

В следующих шагах мы сделаем трехпроходное сжатие с помощью mencoder. На первом проходе мы выберем подходящее сжатие в режиме постоянного качества (параметр crf ) в качестве начальной точки:

mencoder <video> -ovc x264 \ 
         -x264encopts ratetol=100:preset=veryslow:crf=<value>:pass=1 \
         -nosound -o video1.h264
  • Вы можете добавить параметр slow_firstpass к параметру -x264encopts , если вас не устраивает конечное качество видео. В руководстве Mencoder сказано, что эта опция отключает некоторые параметры, которые «значительно улучшают скорость кодирования, практически не влияя на качество последнего прохода». Так что используйте его только на последнем этапе.

  • Вы должны попробовать несколько значений для crf - попробуйте, начиная с 25, и продолжайте увеличивать его, пока не заметите артефакты в результирующем видео (более высокие значения сжимают больше). Помните, что последующие проходы кодирования улучшат качество, которое вы выбрали для crf .

  • Альтернативы предустановке очень медленный : медленный , медленный , средний и т. Д. Полный список см. В руководстве Mencoder.

  • ratetol управляет изменением битрейта - я не уверен, правильно ли я поступаю здесь, но я установил максимальное значение, чтобы дать Mencoder полную свободу выбирать правильный битрейт для каждого сцена.

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

(...)
x264 [info]: kb/s:526.43

Измените параметр crf , рекомендованный на первом проходе, на битрейт , требуемый на последующих проходах:

mencoder <video> -ovc x264 \
       -x264encopts slow_firstpass:ratetol=100:preset=veryslow:bitrate=526:pass=3 \
       -nosound -o video2.h264

При кодировании второго прохода будет считываться статистика, сгенерированная на первом проходе ( divx2pass.log и divx2pass.log.mbtree ) для оптимизации сжатия.

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

  • Обратите внимание, что pass = 3 ( not pass = 2 ) создаст новый файл статистики, поэтому вы можете повторять последний шаг столько раз, сколько захотите. . Обычно я выполняю pass = 3 дважды, всегда обращая внимание на битрейт результата.

Между тем, вы также можете сжимать аудио, используя lame или oggenc :

oggenc -q<n> <audio_pcm.wav>

Наконец, мы повторно объединим аудио и видео

mencoder -audiofile <audio>.ogg video2.h264 -oac copy -ovc copy \
         -of lavf -lavfopts format=mp4 -o <video>.mp4
  • The -of lavf -lavfopts format = mp4 создает файл формата mp4 с использованием мультиплексоров lavopts.
3
27.01.2020, 19:28

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

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

Дополнительную информацию см. в документации ffmpeg по масштабированию .

Масштабирование до половинного размера:

ffmpeg -i input.mkv -vf "scale=trunc(iw/4)*2:trunc(ih/4)*2" -c:v libx265 -crf 28 half_the_frame_size.mkv

Третий размер:

ffmpeg -i input.mkv -vf "scale=trunc(iw/6)*2:trunc(ih/6)*2" -c:v libx265 -crf 28 a_third_the_frame_size.mkv

Четверть размера:

ffmpeg -i input.mkv -vf "scale=trunc(iw/8)*2:trunc(ih/8)*2" -c:v libx265 -crf 28 a_fourth_the_frame_size.mkv

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

145
27.01.2020, 19:28

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

(BR )Измените битрейт, используя:

ffmpeg -i $infile -b $bitrate $newoutfile 

(CR )Варьируйте коэффициент постоянной скорости, используя:

ffmpeg -i $infile -vcodec libx264 -crf 23 $outfile

(SZ )Измените размер видеоэкрана -(, например, на половину его размера в пикселях ), используя:

ffmpeg -i $infile -vf "scale=iw/2:ih/2" $outfile

(BL )Измените профиль H.264 на «базовый», используя:

ffmpeg -i $infile -profile:v baseline $outfile

(DF )Использовать обработку ffmpeg по умолчанию, используя:

ffmpeg -i $infile $outfile

ДАННЫЕ

  • "размер" -процентный размер преобразованного видео в пикселях по отношению к оригиналу.
  • "битрейт" -битрейт исходного и конвертированного видео.
  • "определение" -размер видео в пикселях.
  • "конвертировать" -время конвертации видео в секундах.

Я рассчитал целевой битрейт для (BL )с помощью предложенного метода.

=== Файл A -Как Node помогает продвигать Angular -Fnbixa7Ts6M.mkv ===

            original    BR         CR         SZ         BL         DF
            --------    ---        --         --         --         --
size        64152 kb    214%       76%        40%        83%        76%
bitrate     411 kb/s    883        313        165        342        313
definition  1920x1080   1920x1080  1920x1080  960x540    1920x1080  1920x1080
convert     --          648        509        225        427        510

=== Файл B -Использование GraphQL с Angular _Автор -Lee Costello -OGyFxqt5INw.mkv ===

            original    BR         CR         SZ         BL         DF
            --------    ---        --         --         --         --
size        410301 kb   33%        109%       28%        143%       109%
bitrate     2687 kb/s   880        2920       764        3843       2920
definition  3840x2160   3840x2160  3840x2160  1920x1080  3840x2160  3840x2160   
convert     --           2307       3188       1116       2646       3278

ВЫВОДЫ

  • Метод (SZ )определенно является самым быстрым методом. Это было в 2-4 раза быстрее. Это может быть серьезной проблемой для видео с высоким -разрешением, поскольку все другие методы конвертировали дольше, чем фактическая длина видео! Например,Методу (CR )потребовалось 53 минуты для преобразования 21-минутного видео.

  • Метод (SZ )определенно является лучшим методом, если разрешение видео больше, чем разрешение экрана, на котором оно будет отображаться. Например, если ваш телефон может отображать только изображение 1080p, отправлять на него видео 3840x2160 просто расточительно. Было бы лучше вдвое уменьшить его размер до 1080p.

  • Некоторые из предложенных ответов на самом деле УВЕЛИЧИЛИ размер некоторых видео. Например, метод (BR )более чем удвоил размер выборки 1080p. Однако это сделало размер 2160p одной -третью. Для образца с высоким разрешением -методы (CR ), (BL )и (DF )УВЕЛИЧИЛИ размер видео.

Правильный (или лучший )Ответ

Всегда лучше сначала снизить разрешение до максимального, поддерживаемого целевым дисплеем.

Если вы хотите еще больше уменьшить размер файла, это будет зависеть от вашего личного выбора. Вы можете либо уменьшить информативность, либо увеличить сжатие.

  • Вы можете еще уменьшить разрешение, если это вас не беспокоит.

  • Если в видео нет сцен с быстрыми действиями, можно уменьшить частоту кадров.

  • Если у вас мощный процессор и единственной проблемой является пространство, вы можете увеличить степень сжатия.

  • Битрейт представляет собой комбинацию нескольких факторов. Таким образом, простое указание ffmpeg снизить скорость передачи данных может не дать желаемых результатов.

  • Другим способом снижения содержания информации является снижение глубины цвета. Как это сделать, пока не обсуждалось.

94
27.01.2020, 19:28

Я сжал 40-минутную -видеопрезентацию HD с 505 МБ до 183 МБ
Это похоже на переход от 100 МБ к 36 МБ.
Оригинальное видео было HD, а на выходе разница почти нулевая.
Это видеофайл «Хочу оставить себе,но HD — это излишество».
Вот команда, которую я использовал с причинами:

ffmpeg -n -loglevel error -i inputfile.mp4 -vcodec libx264 -crf 28 -preset faster -tune film outputfilename.mp4

  • -n:избегать перезаписи выходных файлов (безопаснее для тестирования, чем для пакетной обработки)
  • -loglevel error:показывать ошибки и скрывать строки и строки прогресса
  • -i inputfile.mp4:имя входного файла
  • -vcodec libx264:взято из главного ответа выше
  • -crf 28:однопроходное -сжатие с незначительной заметной разницей("0 = без потерь, 23 = по умолчанию, 51 = наихудшее; субъективно нормальный диапазон 17– 28 ")ref docs
  • -preset faster:выглядит в 2 раза быстрее, чем время кодирования по умолчанию для «среднего» ref docs
  • -tune film:указать, что ввод является видео HQ (другие параметры включают «мультфильм», «неподвижное изображение»..)ref docs
  • outputfilename.mp4:имя выходного файла

Для каталога видеофайлов:

for i in *.{avi,flv,m4v,mov,wmv,mp4,MP4,TS,mkv}; do ffmpeg -n -loglevel error -i "$i" -vcodec libx264 -crf 28 -preset faster -tune film "cc${i}"; done

Проблемы:

  • более чистый способ сбора «всех видеофайлов» без указания всех расширений в команде
  • Более чистый способ вывода имени файла без префикса «cc» И возможность подтверждения видео перед удалением
  • .webmфайлы не работают с командой. Пришлось поменять местами "cc${i}""${i%.*}.mp4"

Handbrake — это альтернатива с открытым -исходным кодом и пользовательским интерфейсом

13
27.01.2020, 19:28

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

ffmpeg -i input.mp4 output.mp4

В моем случае это уменьшило битрейт как видео, так и аудио (вы можете проверить и сравнить входной и выходной файл, запустив ffprobeна них ), преобразовав видео размером 700 МБ в видео размером 60 МБ. вроде похожего качества.

71
27.01.2020, 19:28

Я написал bash-скрипт для уменьшения размера видео и автоматической проверки разных значений crf.

В основном вы будете

  • выбрать диапазон значений crf
  • запустить скрипт
  • проверьте размер сгенерированных видео и выберите нужный

Это очень удобно, когда у вас есть предел размера, который вы хотите достичь, и вы не знаете, какое значение crf позволит вам это сделать.

Надеюсь, это кому-нибудь поможет. Я поделился с моими коллегами, и все нашли это полезным.

#!/bin/bash

# bigger values of crf will lead to a bigger compression (smaller video size)
#for i in 1 2 3 4 5
for i in {25..28}
do
# you can remove the option -y if you want to be asked if to overwrite a file with the same name (leave the -y only if you understand what you are doing, otherwise you might rewrite an important file)
   ffmpeg -y -i NAMEOFTHEVIDEOTOCOMPRESS.mp4 -c:v libx264 -crf $i -preset veryfast -profile:v baseline -level 3.0 -strict -2 out_$i.mp4
   printf "\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>Done compression at crf=$i \n\n"
done
3
27.01.2020, 19:28

Вот пример с двумя проходами. Довольно жестко закодировано, но это действительно сжимает
#!/bin/bash ffmpeg -y -i "$1" -c:v libvpx-vp9 -pass 1 -deadline best -crf 30 -b:v 664k -c:a libopus -f webm /dev/null && ffmpeg -i "$1" -c:v libvpx-vp9 -pass 2 -crf 30 -b:v 664k -c:a libopus -strict -2 "$2"

2
30.01.2020, 15:19

Еще не упомянутая опция -r 30для ограничения частоты кадров до 30 кадров в секунду или любого другого значения.

1
12.03.2021, 02:41

Теги

Похожие вопросы