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


202

Как я могу использовать, ffmpegчтобы уменьшить размер видео за счет снижения качества (естественно, в минимально возможной степени, но мне нужно, чтобы оно работало на мобильном устройстве, на котором мало свободного места)?

Я забыл написать еще одну вещь. Когда видео может использовать субтитры (* .srt или * .sub), я бы тоже хотел конвертировать их, чтобы соответствовать параметрам преобразованного видеофайла.


4
Я не использовал его, но на ffmpegстранице man показана -fsопция ограничения размера вывода, что-то вроде ffmpeg -i in.avi -fs 100M out.aviработы?
Кевин

1
Я не буду перенаправлять вас на страницу man ffmpeg | wc -l --> 5254

3
Это .aviне главная проблема .. aviэто просто контейнер. Основная проблема заключается в том, какие кодеки вы используете. Многие (большинство?) .aviВидео-роликов используют кодеки более старого стиля (например, XviD), которые хороши, но больше при том же качестве по сравнению с кодеками более позднего поколения. Обычно вы можете получить жесткое кодирование с использованием H.264стандарта сжатия видео (например, кодека x264) и aacсжатия аудио. Используемый вами контейнер и кодеки зависят от вас и вашего телефона ... .mp4Контейнер хорошо принят ... (но может ли ваш телефон справиться с этим: см. эту ссылку
Peter.O

@Kevin Это хочет больше параметров для преобразования.
xralf

@hesse Что это значит?
xralf

Ответы:


277

Смотрите этот ответ. Приведено ниже для удобства:

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

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

Дополнительные опции, которые стоит рассмотреть, - это установить коэффициент постоянной скорости, который снижает среднюю скорость передачи данных, но сохраняет лучшее качество. Изменяйте CRF между 18 и 24 - чем ниже, тем выше битрейт.

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

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


Видео размером 338 МБ было уменьшено на 130 МБ. Качество быстро снижается. Есть ли какое-то объяснение этому процессу? Первоначальный автор не объясняет свою рекомендацию.
xralf

13
Вторая команда, используя, -crf 24взяла 255,3 МБ видео, которое у меня было, и уменьшила его до 72,7 МБ без заметного снижения качества. Имейте upvote!
Патрик Робертс

2
Впечатляюще уменьшил видео ~ 2G до 14 МБ, все еще выглядит хорошо, это был первый результат поиска, и это именно то, что я искал, спасибо!
sinisterstuf

5
Может быть, стоит отметить, что теперь вы можете использовать libx265для еще большего уменьшения размера.
ZN13

6
Используется ffmpeg -i input.avi -vcodec libx264 -crf 24 output.avi. Это уменьшило 100 МБ видео до 9 МБ. Очень небольшое изменение качества видео. Спасибо!
alpha_989

32

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

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


3
Пожалуйста, приведите примеры полной команды вместо ссылки на внешний сайт (который может когда-нибудь сломаться :)
Джейк Бергер,

1
@Vicky Chijwani предоставляет код в приведенном выше примере. Это лучше подходит для комментариев, но это было мое первое действие на этом сайте. Ссылка содержит более подробное описание опции crf, но не обязательна, чтобы заставить код работать.
Том Келли

27

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

ffmpeg -i input.mkv -vf "scale=iw/2:ih/2" half_the_frame_size.mkv
ffmpeg -i input.mkv -vf "scale=iw/3:ih/3" a_third_the_frame_size.mkv
ffmpeg -i input.mkv -vf "scale=iw/4:ih/4" a_fourth_the_frame_size.mkv

20

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

(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 - Как узел помогает продвигать 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 _ By - Ли Костелло-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 понижения скорости передачи может не дать желаемых результатов.

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


13

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

ffmpeg -i input.mp4 output.mp4

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


1
Ездил с 4Gb до 2Gb с этим, спасибо !!
Сэм Хоссейни

1
(от 10Mo до 1.2Mb, ffmpeg автоматически конвертировал мое видео, которое было в VP8 в VP9 )
sodimel

Это увеличило размер моего видео с 10,8 МБ до 14 МБ
pjtnt11

3

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

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

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

На следующих шагах мы сделаем 3-проходное сжатие с помощью 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 .

  • Альтернативы для пресета veryslow - медленный , медленный , средний и т. Д. Полный список см. В руководстве по 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( не 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
  • -of lavf -lavfopts format=mp4Генерирует mp4формат файл , используя lavopts мультиплексоры.

3

Я сжал 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 » ) реф документы
  • -preset faster: выглядит в 2 раза быстрее, чем время кодирования по умолчанию для средних документов
  • -tune film: указать, что ввод - это HQ-видео (другие опции включают 'cartoon', 'stillimage' ..) 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 является альтернативой с открытым исходным кодом с пользовательским интерфейсом


Оно работает. но это занимает слишком много времени. Есть ли улучшение за меньшее время выполнения
Нирали


1

Я написал 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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.