Пакетное преобразование H.265 MKV в H.264 с ffmpeg, чтобы сделать файлы совместимыми для перекодирования

31

У меня есть файлы с кодировкой H.265, которые настолько ресурсоемки, что не воспроизводятся хорошо, и мое программное обеспечение для конвертации (mencoder) (в настоящее время) не поддерживает формат H.265. Могу ли я преобразовать их в H.264 в командном файле командной строки, чтобы быстро преобразовать файлы для повторного сжатия, используя Devede / OGMrip? После поиска на этом сайте я не нашел его обсуждаемым, поэтому я опубликую полезный вопрос и ответ на него.

TheMegolith
источник

Ответы:

37

Да, используя ffmpeg.

Откройте терминал и направьте его в каталог, содержащий файлы в кодировке H.265, при условии, что у вас установлены ffmpegи установлены соответствующие библиотеки, и при условии, что они в формате MKV, скопируйте и вставьте следующую команду в окно терминала.

INPUT="$1"
for i in *.mkv ; do
    ffmpeg -i "$i" -bsf:v h264_mp4toannexb -sn -map 0:0 -map 0:1 -vcodec libx264 "$i.ts"
    mv "$i.ts" "$i.mpg"
    sleep 3
done

Там у вас есть это. Это преобразует в h.264 в контейнере MPG в том же каталоге.

Объяснение команды переключателей:

  • for i in *.mkv ; do ... done

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

  • ffmpeg -i "$i" Запускает программу ffmpeg и вызывает файлы для обработки.

    • -bsf:v активирует фильтр видеопотока, который будет использоваться.

    • h264_mp4toannexb - Фильтр потока битов, который активирован.

      Преобразовать поток битов H.264 из режима с префиксом длины в режим с префиксом кода (как определено в Приложении B спецификации ITU-T H.264).

      Это требуется для некоторых потоковых форматов, обычно для этого требуется формат транспортного потока MPEG-2 mpegts(), который требуется для обработки MKV h.264 (в настоящее время), если он не включен, в окне терминала появится сообщение об ошибке, указывающее, что его следует использовать.

    • -sn останавливает потоковую передачу потоков субтитров (для тех, кому не нужны субтитры в их видео). Это необязательно и может быть удалено.

    • -map 0:0 -map 0:1Сообщает ffmpeg обрабатывать только первые два потока файла ( 0:0это видео поток, 0:1это первый аудио поток файла). Это делает две вещи, удаляет лишние аудиопотоки, обычно первый аудиопоток - английский, но не всегда. Другие потоки, такие как встроенные субтитры, удаляются, уменьшая размер файла. Это также необязательная строка. Вы можете использовать ffprobeдля просмотра потоков, доступных в файле. -mapне является обязательным и может быть удален из команды.

    • -vcodec libx264 Это говорит ffmpeg кодировать вывод в H.264

    • "$i.ts" Сохраняет вывод в формате .ts, это полезно, чтобы не перезаписывать исходные файлы.

  • mv "$i.ts" "$i.mpg"Преобразует расширение файла в MPG в том же каталоге. Это можно настроить для отправки в любой каталог, который вам нравится.

  • sleep 3 - позволяет процессу отдыхать, давая ffmpeg время поставить в очередь следующий файл

TheMegolith
источник
3
Превосходно! Теперь мы можем удалить комментарии под вопросом. Я бы сказал, что sleep 3это не нужно (но возможно полезно для завершения цикла) и не INPUT=$1имеет смысла, так как вы запускаете это непосредственно в интерактивной оболочке.
Муру
11
Рассмотрим потоковое копирование аудио -c:a copyвместо перекодирования. Кроме того, 0:0не всегда может относиться к видео, и 0:1не всегда может относиться к аудио. Вы можете использовать спецификатор потока, чтобы избежать потенциальных проблем: -map 0:v -map 0:aесли вы хотите, чтобы все видео и аудио потоки были с входа 0, или -map 0:v:0 -map 0:a:0если вы хотите, чтобы только первые видео и аудио потоки были с входа 0. Если вы хотите только английский аудио поток: -map 0:m:language:eng(при условии, что это помечен).
Llogan
1
@LordNeckbeard Я буду голосовать за вас, чтобы написать полный ответ.
Фран Марзоа
1
@Fran Не заметил, что было так много голосов против этого комментария. Я добавил ответ, используя более простые, менее подверженные ошибкам и более эффективные методы.
Llogan
1
Я бы просто пошел с просто ffmpeg -i $INPUT -vcodec h264 -acodec copy $OUTPUT. Что-то, что я использую каждый день и могу запомнить на самом деле в отличие от того множества бессмысленных флагов, которые так печально известны каждому ответу ffmpeg.
Бен Синклер
20

Пакетное преобразование H.265 в H.264

Эти примеры были написаны за последние ffmpeg. Избавьте себя от проблем и загрузите последнюю версию. Затем поместите ffmpegдвоичный файл в ~/binили /usr/local/bin(может потребоваться выйти из системы, а затем войти в систему, чтобы ее заметили).

Матроска выходной

mkdir h264vids
for f in *.mp4; do ffmpeg -i "$f" -map 0 -c copy -c:v libx264 -crf 23 -preset medium h264vids/"${f%.*}.mkv"; done
  • Этот пример будет выводить в каталог с именем h264vids.

  • В этом примере предполагается, что ваши входные данные .mp4. Если нет, измените .mp4экземпляр в примере на ваш тип входного файла или просто используйте жадные *алгоритмы.

  • Настройте -crfкачество и -presetскорость / эффективность кодирования. Или просто удалите эти параметры и используйте значения по умолчанию, которые являются довольно хорошими и должны быть достаточными для большинства (в примере используются значения по умолчанию для этих параметров). См. FFmpeg Wiki: H.264 для получения дополнительной информации об этих параметрах.

Выход MP4

Этот немного сложнее. Это будет выполнять условное кодирование в зависимости от того, является ли входной звук AAC или нет. Если входной аудиосигнал имеет формат AAC, тогда аудиосигнал будет скопирован в потоковом режиме (переделан заново) как есть, и ненужное перекодирование будет исключено. Если входной звук не AAC, то он будет перекодирован в AAC.

Вот простой скрипт, демонстрирующий, как сделать это, используя ffprobeи ffmpeg. Скопируйте и сохраните его в каталог, содержащий ваши видео для конвертации, дайте ему разрешение на выполнение с помощью chmod +x yourscriptname, а затем запустите его с ./yourscriptname.

#!/bin/bash

mkdir h264vids

for f in *.mkv
do
  audioformat=$(ffprobe -loglevel error -select_streams a:0 -show_entries stream=codec_name -of default=nw=1:nk=1 "$f")
  if [ "$audioformat" = "aac" ]; then
    ffmpeg -i "$f" -c:v libx264 -crf 23 -preset medium -c:a copy -movflags +faststart h264vids/"${f%.*}.mp4"
  else
    ffmpeg -i "$f" -c:v libx264 -crf 23 -preset medium -c:a aac -movflags +faststart h264vids/"${f%.*}.mp4"
  fi
done
  • Этот пример будет выводить в каталог с именем h264vids.

  • В этом примере предполагается, что ваши входные данные .mkv. Если нет, измените .mkvэкземпляр в примере на ваш тип входного файла или просто используйте жадные *алгоритмы.

  • См. Примечание выше относительно -crfи -preset.

  • Вы можете приостановить кодирование с помощью ctrl+ zи продолжить с помощью fg.

llogan
источник
1

Учитывая предыдущие ответы, я придумал следующее:

for file in *265.mkv; do nice -n19 ffmpeg -i $file -c copy -c:v libx264 ${file/%265.mkv/264.mkv}; done

Это предполагает, что файлы всегда имеют имя, оканчивающееся на 265.mkv. Это окончание будет заменено на 264.mkv.

Если ваше имя файла отличается, вам нужно соответствующим образом адаптировать команду.

kerner1000
источник
Это отличный ответ, который, я думаю, должен быть оценен выше, потому что в нем используется подстановка параметров Bash.
Sysinfo.io