Перекодирование звука 5.1 в ffmpeg приводит к неправильному отображению звука на выходе

Мне нужно перекодировать некоторые видео с высоким разрешением (файлы prores или dnxhd с несжатым звуком 48 кГц 5.1 в контейнере MOV) в h264 с низким разрешением, при этом AAC сохраняет звук в формате 5.1, сохраняя их сопоставление каналов.

Для этого я попытался использовать эту команду:

ffmpeg -y -i input.mov -c:v libx264 -preset ultrafast -b:v 10000k -c:a libfdk_aac -afterburner 1 -cutoff 20000 -filter:v "scale=-1:720" output.mp4

Версия, которую я использую, ffmpeg version N-87584-g47d6b02f6c-Reinoдовольно новая.

Что происходит, так это то, что даже если обработка видео в порядке, для аудио части мои каналы отображаются неправильно ... чтобы лучше объяснить, что происходит, я сделал скриншот до и после волновых форм в Adobe Audition.

Это форма входного файла:

волны в моем исходном видео

Вместо этого это формы сигналов перекодированного файла:

формы сигналов изменились после перекодирования

Снова позвольте мне опубликовать части ffprobe, связанные со звуком:

входной файл:

Stream #0:1(eng): Audio: pcm_s24le (lpcm / 0x6D63706C), 48000 Hz, 5.1, s32 (24 bit), 6912 kb/s (default)
Metadata:
  creation_time   : 2018-01-02T09:48:58.000000Z
  handler_name    : Apple Alias Data Handler
  timecode        : 00:00:00:00

перекодированный файл:

Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, 5.1, fltp, 488 kb/s (default)
Metadata:
  handler_name    : SoundHandler

и для финиша MediaInfo Lite

исходный файл:

Audio
ID                          : 2
Format                      : PCM
Format settings             : Little / Signed
Format settings, Endianness : Little
Format settings, Sign       : Signed
Codec ID                    : lpcm
Duration                    : 1 h 30 min
Bit rate mode               : Constant
Bit rate                    : 6 912 kb/s
Channel(s)                  : 6 channels
Channel positions           : Front: L C R, Back: L R, LFE
Sampling rate               : 48.0 kHz
Bit depth                   : 24 bits
Stream size                 : 4.35 GiB (5%)
Language                    : English
Encoded date                : UTC 2018-01-02 09:48:58
Tagged date                 : UTC 2018-01-02 10:16:46

перекодированный файл:

Audio
ID                          : 2
Format                      : AAC
Format/Info                 : Advanced Audio Codec
Format profile              : LC
Codec ID                    : mp4a-40-2
Duration                    : 1 h 30 min
Duration_LastFrame          : -8 ms
Bit rate mode               : Constant
Bit rate                    : 489 kb/s
Channel(s)                  : 2 channels
Channel(s)_Original         : 6 channels
Channel positions           : Front: L C R, Side: L R, LFE
Sampling rate               : 48.0 kHz
Frame rate                  : 46.875 FPS (1024 SPF)
Compression mode            : Lossy
Stream size                 : 315 MiB (5%)
Language                    : English
Default                     : Yes
Alternate group             : 1

Если вы воспроизводите файл mp4 с помощью VLC, вы ясно слышите, что что-то поменялось местами неправильно.

Я открыт для решения ;)

Ответы (1)

FFmpeg предполагает, что отображение канала 5.1 на входе такое же, как и используемое. Чтобы исправить это, используйте фильтр карты каналов для переназначения, добавьте:

-af "channelmap=4|0|1|2|3|5:5.1"

(Я основывался на метках каналов справа на ваших изображениях)

Я обнаружил, что для моих целей работает: -af "channelmap=0|1|4|5|2|3:5.1"
Просто вопрос, который меня интересует. Почему с ffmpeg я должен указывать порядок каналов вручную, когда вместо этого такой проигрыватель, как VLC, основанный на libavcodec, может определить его автоматически? Разве ffmpeg не должен делать то же самое? Я могу понять указание вручную 5.1-канального варианта для вывода, но не для ввода.
Раскладка канала передается демультиплексором декодеру, и VLC использует свою собственную. В ffmpeg демультиплексор QT распознает макет в вашем MOV, но ffmpeg внутри имеет единственное обозначение для 5.1, поэтому он не меняет порядок при отправке кодировщику.
Я вижу, это имеет смысл. Нет никакого способа автоматически назначить их так? Или, по крайней мере, команду с ffprobe для чтения внутреннего макета канала, чтобы я мог сделать многопроходный скрипт?