Перекодировка видео библиотеки в x265 (HEVC) без потери качества

43

Я пытаюсь преобразовать мою библиотеку видео в формат HEVC, чтобы освободить место. Я выполнил следующую команду для всех видеофайлов в моей библиотеке:

#!/bin/bash
for i in *.mp4;
do 
    #Output new files by prepending "X265" to the names
    avconv -i "$i" -c:v libx265 -c:a copy X265_"$i"
done

Сейчас большинство видео конвертируются нормально, а качество остается прежним. Однако несколько видео очень высокого качества (например, один фильм размером 5 ГБ) теряет качество - все видео имеет пикселизацию.

Я не уверен, что делать в этом случае. Мне нужно изменить crfпараметр в моей командной строке? Или что-то другое?

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

UPDATE-1

Я обнаружил, что crfэто ручка, которую мне нужно отрегулировать. CRF по умолчанию равен 28. Для лучшего качества я мог бы использовать что-то меньше 28. Например:

avconv -i input.mp4 -c:v libx265 -x265-params crf=23 -c:a copy output.mp4

Однако проблема заключается в том, что для некоторых видео значение CRF достаточно хорошее, в то время как для некоторых видео требуется более низкая CRF. Это то, что я должен проверить вручную путем преобразования небольших разделов больших видео. Но в массовом преобразовании, как бы я проверил каждое видео вручную? Есть ли какой-то способ, которым avconvможно грамотно настроить CRF в соответствии с входным видео?

ОБНОВЛЕНИЕ-2

Я обнаружил, что --losslessв x265 есть опция: http://x265.readthedocs.org/en/default/lossless.html .

Однако я не знаю, как правильно его использовать. Я попытался использовать его следующим образом, но это дало противоположные результаты (видео было еще более точечным):

avconv -i input.mp4 -c:v libx265 -x265-params lossless -c:a copy output.mp4
shivams
источник
1
--losslessможет на самом деле увеличить файл, если он декодирует ранее кодек с потерями, а затем включает то, что он декодировал без потерь. Качество останется таким же, как на входе.
Голар Рамблар,
2
Если ваши источники закодированы с потерями (что наиболее вероятно), то то, что вы пытаетесь достичь, невозможно. Любое транскодирование, которое не является без потерь, будет ухудшать качество в дальнейшем (даже если оно не будет сразу видно для вас), и если вы преобразуете с потерями в без потерь, вы получите файлы большего размера.
Сардж Борщ

Ответы:

58

Исходя из моего собственного опыта, если вы хотите абсолютно без потерь в качестве, --lossless - это то, что вы ищете.

Не уверен, avconvно введенная вами команда выглядит идентично тому, что я делаю FFmpeg. В FFmpegвы можете передать параметр , как это:

ffmpeg -i INPUT.mkv -c:v libx265 -preset ultrafast -x265-params lossless=1 OUTPUT.mkv

Большинство x265ключей (опции без значения) могут быть указаны следующим образом (кроме тех, которые предназначены только для CLI, они используются только с x265двоичным кодом напрямую).

В связи с этим я бы хотел поделиться своим опытом с x265кодированием. Для большинства видео (будь то WMV, или MPEG, или AVC / H.264) я использую crf=23. x265определяет остальные параметры и обычно выполняет достаточно хорошую работу.

Однако часто, прежде чем я решу полностью перекодировать видео, я проверяю свои настройки, конвертируя небольшую часть рассматриваемого видео. Вот пример, предположим, что файл mkv с потоком 0 является видео, поток 1 является аудио DTS, а поток 2 является субтитром:

ffmpeg -hide_banner \
-ss 0 \
-i "INPUT.mkv" \
-attach "COVER.jpg" \
-map_metadata 0 \
-map_chapters 0 \
-metadata title="TITLE" \
-map 0:0 -metadata:s:v:0 language=eng \
-map 0:1 -metadata:s:a:0 language=eng -metadata:s:a:0 title="Surround 5.1 (DTS)" \
-map 0:2 -metadata:s:s:0 language=eng -metadata:s:s:0 title="English" \
-metadata:s:t:0 filename="Cover.jpg" -metadata:s:t:0 mimetype="image/jpeg" \
-c:v libx265 -preset ultrafast -x265-params \
crf=22:qcomp=0.8:aq-mode=1:aq_strength=1.0:qg-size=16:psy-rd=0.7:psy-rdoq=5.0:rdoq-level=1:merange=44 \
-c:a copy \
-c:s copy \
-t 120 \
"OUTPUT.HEVC.DTS.Sample.mkv"

Обратите внимание, что обратная косая черта прерывается в длинной команде, я делаю это, чтобы помочь мне отслеживать различные биты сложного ввода CLI. Прежде чем я объясню это построчно, часть, где вы конвертируете только небольшую часть видео, является второй строкой и второй последней строкой: -ss 0означает поиск до 0 секунд перед тем, как начать декодирование ввода, и -t 120означает прекращение записи в вывод через 120 секунд. Вы также можете использовать форматы времени чч: мм: сс или чч: мм: сс.ссс.

Теперь построчно:

  1. -hide_bannerне позволяет FFmpegпоказывать информацию о сборке при запуске. Я просто не хочу видеть это, когда прокручиваю вверх в консоли;
  2. -ss 0ищет 0 секунд до начала декодирования ввода. Обратите внимание, что если этот параметр задан после входного файла и перед выходным файлом, он становится опцией вывода и указывает ffmpegдекодировать и игнорировать ввод до x секунд, а затем начать запись в вывод. Как вариант ввода он менее точен (поскольку поиск не точен в большинстве форматов контейнеров), но почти не занимает времени. Как вариант вывода, он очень точен, но занимает много времени для декодирования всего потока до указанного времени, и для целей тестирования вы не хотите тратить время;
  3. -i "INPUT.mkv": Укажите входной файл;
  4. -attach "COVER.jpg": Прикрепите обложку (миниатюру, плакат, что угодно) к выводу. Обложка обычно отображается в файлах;
  5. -map_metadata 0: Скопируйте все метаданные из ввода 0, который в данном примере является просто вводом;
  6. -map_chapters 0: Скопировать информацию главы (если имеется) со входа 0;
  7. -metadata title="TITLE": Установить заголовок видео;
  8. -map 0:0 ...: Сопоставить поток 0 ввода 0, что означает, что мы хотим, чтобы первый поток ввода был записан в вывод. Так как этот поток является видеопоток, это первый видео поток в выходе , следовательно , поток спецификатор :s:v:0. Установите его языковой тег на английский;
  9. -map 0:1 ...: Аналогично строке 8 сопоставьте второй поток (аудио DTS) и установите его язык и заголовок (для упрощения идентификации при выборе из проигрывателей);
  10. -map 0:2 ...: Аналогично строке 9, за исключением того, что этот поток является субтитром;
  11. -metadata:s:t:0 ...: Установить метаданные для обложки. Это требуется для формата контейнера mkv;
  12. -c:v libx265 ...: Параметры видео кодека. Это так долго, что я разбил его на две строки. Эта настройка хороша для высококачественного синего видео (1080p) с минимальной полосой в градиенте (что при х265 хреново). Скорее всего, это перебор для DVD, телешоу и телефонных видео. Этот параметр в основном украден из этого поста в Doom9 ;
  13. crf=22:...: Продолжение параметров видеокодека. Смотрите сообщение на форуме, упомянутое выше;
  14. -c:a copy: Скопировать аудио;
  15. -c:s copy: Копировать субтитры;
  16. -t 120: Прекратить запись на выход через 120 секунд, что дает нам 2-минутный клип для предварительного просмотра качества транскодирования;
  17. "OUTPUT.HEVC.DTS.Sample.mkv": Имя выходного файла. Я помечаю свои имена файлов видеокодеком и основным аудиокодеком.

Уф. Это мой первый ответ, поэтому, если я что-то пропустил, оставьте комментарий. Я не эксперт по производству видео, я просто парень, которому лень смотреть фильм, вставляя диск в плеер.

PS. Возможно, этот вопрос относится к чему-то другому, поскольку он не сильно связан с Unix и Linux.

Ифэн Му
источник
2
Именно то, что я искал! Приятное освещение вариантов. Знаете ли вы, если ffmpeg будет отказываться, c:s copyесли нет субтитров?
Старейшина Гик,
1
@ElderGeek Нет, ffmpeg скажет что-то, только если этот параметр имеет какой-либо эффект.
Ифэн Му
Эта опция генерирует наименьший возможный размер файла для действительно без потерь кодировки h265? Если нет, то есть ли способ сделать это?
Чтение буфера
1
@TheBitByte Не думаю, что в h265 есть уровень сжатия без потерь. Для варианта без сжатия это просто --lossless. Я тщетно искал преобразование без потерь из h264 в h265, и то, что я узнал, говорит мне, что это математически невозможно.
Ифэн Му
1
Вы действительно должны отредактировать команду, содержащую --losslessпереключатель, из этого ответа, потому что если вы поставите его как ответ на этот вопрос, это звучит так, как будто вы говорите, что это сжатие без потерь, которое вводит в заблуждение.
Хашим
8

Недавно я пережил проблему перекодировки всего моего видео каталога в HEVC. Я использую https://github.com/FallingSnow/h265ize со следующими настройками.

h265ize -v -m medium -q 20 -x --no-sao --aq-mode 3 - удалить --stats

-v - подробный вывод
-m средний - средняя скорость кодирования (меньшее, более высокое качество, все, что медленнее, на мой взгляд, не стоит времени / качества dif)
-q 20 - используемый CRF, 20 похож на 18 или около того в x264, но эй. Это для контента в формате 1080p (90% моего телевизора). Я обычно использую 22 для своих фильмов 4K
-x - Использовать централизованно определенные команды x265 - no
-sao выключает Sample Adaptive Offset (улучшает скорость кодирования)
--aq-mode 3 - использовать Adaptive Quantisation с автоматической дисперсией, помогает 8-битному кодированию, особенно в темных областях, останавливает большинство возможных полос (за счет времени кодирования)
--delete - заменить файл кодирования на закодированный файл (проверить перед использованием этого) )
--stats - Записать статистику в CSV-файл в корне пути, по которому вы бежали.

Скорость кодирования составляет около 30 кадров в секунду (для большинства материалов 1080p) на моей установке. Dual Xeon E5 2687W v2, но я заставляю процесс FFMPEG не использовать первую сторону одного из процессоров (это мой сервер Plex, поэтому необходимо убедиться, что при воспроизведении и т. Д. Требуются дополнительные затраты на перекодировку)

Да, потребовалось некоторое время, чтобы преобразовать большую часть этого, и теперь у меня есть запланированное задание, которое выполняется два раза в день, чтобы закодировать материал с того дня в x265.

Экономия пространства была огромной. Первоначально SAN использовался при 20 ТБ, сейчас - около 12, но, очевидно, он также был добавлен с дополнительным контентом на 6 месяцев.

Я также начал перекодировать все свои фильмы, но это непрерывный процесс, так как я должен идентифицировать уровни качества (к счастью Radarr, а потом хорошо), и использовать одну из трех настроек транскодирования:

-m slower -q 18 -x --no-sao --aq-mode 3для транскодов 720p
-m medium -q 20 -x --no-sao --aq-mode 3для 1080p
-m medium -q 22 -x --no-saoдля 2160p

Надеюсь, что это помогает некоторым людям. Кричите, если кому-то нужна рука, все настраивающее. И прежде чем кодировать все в x265, подумайте о воспроизведении. Если клиент не поддерживает родной x265, то транскадирование может быть дорогим с точки зрения процессора и качества.

Эшли-Пол Чарльзуорт
источник
С x265 2.4 и более поздними версиями (с новыми лямбда-таблицами, которые обеспечивают более четкое кодирование), SAO, как правило, является хорошим решением для качества на битрейт. Это все еще слегка смазывает, но уменьшает другие артефакты достаточно, чтобы стоить это.
Питер Кордес
-q 20это не CRF 20, это постоянная скорость контроля QP . Стандартный и рекомендуемый режим, CRF, повышает QP в сценах высокой сложности, поэтому он не тратит слишком много битов на сцены, которые слишком сложно кодировать. (Если вы хотите приблизиться к равномерному QP, поднимитесь qcompс 0,6 по умолчанию до 0,7 или 0,8. Ближе к 1,0 ближе к CQP.)
Питер Кордес
3

Правильный синтаксис для включения режима без потерь для кодера x265 в ffmpeg: -x265-params lossless=1(необходимо добавить =1).

Однако для кодирования без потерь существуют лучшие варианты кодеков. В ходе тестирования я обнаружил, что FFV1 сжимает намного лучше (размер файла = ~ 80% от x265), по крайней мере, для некоторых видов видео (если для обоих кодеков выбраны лучшие настройки). И это также работает быстрее, и (AFAIK) не обременен патентами. То есть он превосходит H.265 без потерь во всех отношениях для архивирования видео.

Сардж Борщ
источник