Як я можу зменшити розмір відео за допомогою ffmpeg?


201

Як я можу ffmpegзменшити розмір відео, знизивши його якість (як мінімум, природно, але мені потрібно, щоб він працював на мобільному пристрої, у якому мало місця)?

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


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

1
Я не переспрямую вас на сторінку чоловіка:man ffmpeg | wc -l --> 5254

3
.aviЧи не головне питання .. aviце просто контейнер. Основне питання полягає в тому, які кодеки ви використовуєте. Багато (більшість?) .aviVID-кодів використовують старі кодеки стилів (наприклад, 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 24255,3 Мб відео, яке я мав, і зменшило його до 72,7 МБ, не помітно знижуючи якість. Майте нагороду!
Патрік Робертс

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

ДАНІ

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

Я розраховував цільовий бітрейт для (BL), використовуючи запропонований метод.

=== Файл A - як вузол допомагає приводити кут-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 з кутовим _ Автор - Лі Костелло-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
МБ

3

У мене є рецепт, який я спочатку підробив для себе, щоб перетворити відео JPEG Motion Motion, яку створює моя стара камера (вони дуже великі відео, оскільки кожен кадр є цілим зображенням 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 є повільнішими , повільнішими , середніми і т. Д. Дивіться посібник з управління кодами для повного списку.

  • 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 від 505MB до 183MB.
Це як би переходити від 100MB → 36MB.
Оригінальне відео було високою роздільною здатністю, а вихідний сигнал майже не помітний.
Це відеофайл "Я хотів би тримати, але 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 відео (інші варіанти включають «мультик», «stillimage» ..) реф документи
  • 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"

Ручний гальмо - це альтернатива з відкритим кодом з інтерфейсом користувача


Це працює. але це займає занадто багато часу. Чи є покращення за менший час виконання
Ніралі


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.