
Я конвертирую сжатые без потерь видео и аудио файлы (Utvideo/LCPM) в кодеки FFV1/FLAC, используя MKV в качестве контейнера для экономии места на диске без ущерба качеству. Я использую функции framemd5 ffmpeg, чтобы гарантировать, что каждое преобразование будет 1:1 с исходным захватом с точки зрения вывода.
Пакетный скрипт выглядит следующим образом:
for %%a in ("*.avi") do ffmpeg -i "%%a" -f framemd5 "%%~na.framemd5"
Однако при использовании FLAC в качестве аудиокодека аудиочасть выходных данных framemd5 перестает совпадать.
Вот первые 1001 строка framemd5 примера записи:
https://pastebin.com/axcf3f0aоригинальный LPCM
https://pastebin.com/3n75YTMjКонвертация FLAC
Проблема, кажется, в том, чтоFLAC добавляет дополнительные метаданные и собственную контрольную сумму, так что хотя аудио предположительно 1:1, framemd5 не распознает его как таковой. Я не очень хорошо разбираюсь в файловой структуре FLAC, поэтому не могу проверить это сам или придумать обходной путь.
Можно ли как-то это согласовать? Могу ли я создать файлы framemd5, которые будут проверять контрольные суммы видео и аудио между Utvideo/LPCM и FFV1/FLAC как 1:1?
Это невероятно раздражает. Я хочу использовать FLAC для сжатия аудио, так как я и так пытаюсь сэкономить как можно больше места.
решение1
Это не имеет никакого отношения к метаданным потока FLAC.
ffmpeg-all
на фреймхэше(framemd5 — это вариант framehash):
По умолчанию аудиокадры преобразуются в подписанный 16-битный необработанный звук, а видеокадры — в необработанное видео перед вычислением хэша.
(ПРИМЕЧАНИЕ: в случае более высокой битовой глубины вам необходимо будет указать соответствующуюкодер, например-c:a pcm_s24le
после -f framemd5
(В обоих случаях «A» и «B» для предотвращения вычисления контрольной суммы на «усеченных» аудиокадрах.)
Таким образом, контрольная сумма всегда выполняется для декодированных (а затем кодированных, несколько «фиктивным» способом, как в случаях PCM или нет) кадров, если только вы не указали что-то вроде -c copy
. Таким образом, метаданные не будут «мешать» хешированию здесь.
Настоящая причина проблемы здесь в том, что в отличие от случая с видео, «кадр» в данном случае при применении к аудиопотоку относится не к одному сэмплу, а к сэмплам в целом, которые были сгруппированы в пакет. Пакеты могут иметь разные размеры (количество сэмплов) в зависимости от кодировщика/мультиплексора (значения по умолчанию в их коде) и, возможно, настроек пользователя.
Как видно из выходных строк, каждый пакет во входном аудиопотоке содержит 1024 сэмпла в случае PCM, тогда как в случае FLAC каждый пакет содержит 4608 сэмплов.
TL;DR. Решением здесь будет добавление -frame_size 1024
после -c:a flac
того, как вы кодируете «сжатую версию».
PS Я понятия не имею, вызовет ли изменение размера кадра/пакета потока FLAC какие-либо проблемы (например, при воспроизведении) / нежелательные побочные эффекты, и вы можете задаться вопросом, можно ли вместо этого изменить размер кадра/пакета потока PCM. Все, что я могу сказать, это то, что в случае PCM это будет на уровне мультиплексора, а не на уровне кодировщика, как в случае FLAC, что более или менее подразумевает, что это вряд ли будет настраиваемым пользователем .
Хотя это может помочь, а может и нет, вы всегда можете попробовать выполнить мультиплексирование (из файлов необработанного потока или файлов WAVE/AIFF, если это PCM, вместо повторного мультиплексирования файла Matroska, поскольку задействованный процесс может отличаться) с другим мультиплексором Matroska в случае, если размер пакета/кадра PCM-in-Matroksa (т. е. 1024
) в ffmpeg не работает должным образом при использовании для FLAC.
ОБНОВЛЕНИЕ: Очевидно, если вы используете WAVE-файл в качестве входных данных, вы можете использовать-max_size
демультиплексоропция (WAVE dexmuer) для определения размера каждого пакета, когда поток подается в Matrokska muxer. Обратите внимание, что -max_size
это байты, а не образцы. Так что в этом случае вы можете использовать что-то вроде ffmpeg ... -max_size 9216 -i path/to/input.wav ...
(убедитесь, что у вас есть-max_size
до -i
). Кажется, я не вижу подобной опции в демультиплексорах raw PCM (например s16le
), поэтому вам сначала нужно будет сделать входной аудиофайл WAVE-файлом, если вы хотите использовать его.
Ссылка (расположение в коде значений по умолчанию):
https://github.com/FFmpeg/FFmpeg/blob/n5.1.2/libavcodec/flacenc.c#L314
https://github.com/FFmpeg/FFmpeg/blob/n5.1.2/libavformat/pcm.c#L27
https://github.com/FFmpeg/FFmpeg/blob/n5.1.2/libavformat/wavdec.c#L76