webm encoding - pituz/webm-thread GitHub Wiki
Основным (и в большинстве случаев достаточным) инструментом конвертирования видео в формат webm является ffmpeg. Здесь рассматриваются его параметры при использовании кодеков формата WebM.
Формат WebM позволяет использовать следующие форматы видео и аудио:
- Видео:
- VP8: устаревший формат, с выходом VP9 остался нужен только в тех случаях, когда важна скорость и наплевать на эффективность сжатия;
- VP9 (
-c:v libvpx-vp9
, либо-c:v vp9
, для WebM используется по умолчанию): основной формат для пиления WebM'ок; работает значительно медленнее, но сжимает в 1.5-2 раза лучше; - AV1 (
-c:v libsvtav1
, либо не рекомендуемые-c:v libaom-av1
или-c:v librav1e
): лучший по качеству формат из числа поддерживаемых WebM на данный момент. Играется всеми современными браузерами. Из перечисленных энкодеров хорошую производительность имеет толькоSVT-AV1
, остальные вы просто не дождётесь. Так как энкодер относительно новый, не всякий билдffmpeg
содержит его, и даже при наличии версия может быть старой и медленной. Рекомендуем скачать последний билд отсюда (ищите архивы с суффиксом-gpl.tar.xz
).
- Аудио:
Примеры кодирования WebM с использованием ffmpeg
Уровень порнотреда
Пожать фрагмент animu.mkv с 1:10 по 1:50 в VP9/Opus одним проходом:
ffmpeg -i animu.mkv -ss 1:10 -t 40 -b:v 0 -crf 30 out.webm
либо замените -t 40
на -to 1:50
.
Ускорить можно одним из двух способов:
- с увеличением размера файла, указав кодек vp8 (
-c:v vp8
передout.webm
); -c:v libsvtav1
с более высоким значением-preset
(в районе 8-10); моар тут.
Сжатие двумя проходами с подсчётом битрейта под лимит
Допустим, нужно пожать amv.mp4
длиной 4 минуты и разрешением 1280x720 целиком, попав при этом в лимит 10240 KiB.
- Считаем битрейт по длине фрагмента:
10240KiB * 8bit / (4m * 60s) == 341kbit/s
, вычитаем из него желаемый битрейт звука (допустим, 64kbit/s):341 - 64 == 277kbit/s
. - Оцениваем визуально, влезет ли вообще в этот битрейт видео с приемлемым качеством, и если влезет, то с каким разрешением. Для видео с высокой динамикой и сменой сцен на каждом такте такой битрейт явно мал: для такого бывает надо полмегабита, а то и больше. Допустим, наше amv должно влезать с разрешением 960x540px.
- Первый проход сжатия видео: кодек определяет сжимаемость кадров видео, сохраняя информацию о ней в файле
ffmpeg2pass-0.log
в текущем каталоге.
ffmpeg -i amv.mp4 -map 0:v -vf scale=-1:540 -c:v vp9 -pass 1 -f null -
- Второй проход сжатия видео: при этом, собственно, и происходит сжатие.
ffmpeg -i amv.mp4 -map 0:v -vf scale=-1:540 -pass 2 -b:v 277k video.webm
во время сжатия можно смотреть готовые кадры плеером и принимать решение об остановке кодирования (клавиша q) и разбивке видео на два фрагмента (удваиваем битрейт, переделываем второй проход) или смене разрешения (придётся переделать также первый проход).
- Смотрим размер результата, считаем оставшийся битрейт для звука, жмём звук и муксим с видео:
ffmpeg -i amv.mp4 -i video.webm -map 0:a -b:a 64k -map 1:v -c:v copy out.webm
-
Смотрим размер результата, если он вышел за лимит — переделываем пт. 5 с корректировкой битрейта.
-
Постим webm и наблюдаем чёрное превью.
AV1
Начиная с билдов ffmpeg
примерно середины-конца 2023, во всех выше перечисленных командах энкодер можно заменить на libsvtav1
, получив заметно более высокое качество при прежнем размере.
Минимальный пример:
ffmpeg -i animu.mkv libsvtav1 -crf 38 -preset 6 out.webm`
-crf
влияет на соотношение размер/качество — есть смысл использовать значения в диапазоне 38-50; чем ниже значение — тем выше качество результата и выше размер.-preset 6
заставляет ffmpeg тратить чуть больше времени на энкод в обмен на заметное улучшение результата.
Разбор параметров кодеков
Видео
Контроль ширины потока
Ширина потока — это, другими словами, битрейт — количество информации, производимое кодеком за единицу времени дорожки.
Для контроля ширины потока у libvpx есть 4 основных параметра:
- -crf, по умолчанию
-1
; -b:v
(устар.-vbitrate
), по умолчанию200k
;-qmin
, по умолчанию-1
;-qmax
, по умолчанию-1
.
Они приведены в порядке повышения приоритета: значения -qmin
/-qmax
важнее всех и будут соблюдены в любом случае, даже если это приведёт к превышению указанного битрейта.
Параметры -crf
, -qmin
и -qmax
управляют т.н. фактором квантизации — числом, которым указывается уровень снижения детализации картинки. Оно может принимать значения от 0 (потерь нет) и до 63. По умолчанию все эти параметры имеют значение -1, т.е. не используются. VP8 не может без потерь, его минимальный фактор квантизации — 4. Значение -crf
должно находиться между -qmin
и -qmax
, иначе кодек откажется работать.
Грубо говоря, ширина потока для каждого кадра определяется по следующему алгоритму:
- считается битрейт для кадра с квантизацией по
-crf
; - если битрейт превысил допустимый (указанный параметром
-b:v
), то уровень квантизации повышается так, чтобы битрейт остался в пределах лимита; - если уровень квантизации вышел за пределы
-qmin
/-qmax
, то он корректируется до ближайшей находящейся в допустимом диапазоне величины.
Битрейт здесь фигурирует не напрямую, а опосредованно: не использованный в одних кадрах битрейт может быть распределён на другие. Чтобы распределение битрейта происходило адекватно изменению динамики картинки, нужно жать её двумя проходами.
Управление соотношением скорость/качество
Для этого есть два параметра:
-
-deadline 0..over9000
(синоним:-quality
) — допустимое кол-во микросекунд на кодирование одного кадра; специальные значения и константы:- 0 (best): без ограничений, максимальное качество;
- 1 (realtime): завершить кодирование как можно быстрее;
- 1000000 (good): 1 секунда, значение по умолчанию.
При значениях больше единицы:
- в однопроходном режиме опаздывающие кадры кодируются в режиме realtime, укладывающиеся в указанный лимит времени — по профилю -cpu-used;
- в двухпроходном режиме всегда используется профиль -cpu-used.
Ещё.
-cpu-used 0..8
(синоним:-speed
, по умолчанию 1) — профили энкодера для -quality good, от более ресурсоёмких и эффективных к менее, см. vp9/encoder/vp9_speed_features.c.
Звук
Opus
Тут всё элементарно: ставишь битрейт (-b:a
, значения от 4k
до 510k
) и кодируешь, все дополнительные параметры по умолчанию имеют адекватные кодированию вебмок значения.
-frame_duration
: длина кадра в миллисекундах, от 2.5 до 60, по умолчанию 20. Имеет смысл увеличивать на крайне низких битрейтах (ниже 24кбпс);-application
: профиль кодека (audio
/voip
/lowdelay
), по умолчаниюaudio
;-vbr
: переменный битрейт, по умолчанию включено.
Firefox имеет особенность зацикливать вебмки с Opus не с первого кадра, а с последнего ключевого. Для создания лупов лучше использовать Vorbis.
Vorbis
ffmpeg
имеет две реализации энкодера vorbis'а: встроенную (-c:a vorbis
) и через специализированную библиотеку libvorbis (-c:a libvorbis
). Имеет смысл использовать только второй вариант.
У libvorbis'а есть неприятная особенность: при указании битрейта (-b:a
) он включает режим CBR (постоянный битрейт), что сильно снижает его эффективность и, соответственно, качество звука. Для режима VBR (переменный битрейт) следует указывать качество (-q:a), его значения можно посмотреть тут
tl,dr: -c:a libvorbis -q:a 0..10