Как принудительно синхронизировать аудио/видео с помощью mkvmerge и внешних тайм-кодов?

Задний план

Я работаю над проектом, в котором видео и аудио являются алгоритмическими интерпретациями исходного файла MKV, где я использую ffmpeg -ss и -t для извлечения определенной области аудио и видео в отдельные файлы. Я использую смену сцен в видео в звуковом процессе (т. е. звуковые изменения при смене сцены в видео), поэтому синхронизация имеет решающее значение.

Звук 48 кГц, с использованием 512 блоков сэмплов. Видео 23.976fps (пробовал и 24).

Я сохраняю начало кадра sceneChanges в файле с точки зрения кумулятивных блоков:

blocksPerFrame = (48000 / 512) / 23.976
sceneOnsetBlock = sceneOnsetFrame*blocksPerFrame

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

Когда я снова объединяю аудио и видео (в настоящее время использую ffmpeg для генерации mp4 (v) mp3 (a) в контейнере MKV), аудио и видео начинают синхронизироваться, но все больше дрейфуют, пока не заканчиваются ~ 35 секунд. Хуже всего то, что задержка звука нелинейна! Под нелинейностью я подразумеваю, что если я нанесу отставание в зависимости от местоположения этого отставания во времени, я получу не линию, а то, что вы видите на изображении ниже). Я не могу просто сдвигать или масштабировать звук, чтобы он соответствовал видео, из-за этой нелинейности. Я не могу понять причину этой нелинейно увеличивающейся задержки звука; Я дважды и трижды проверил свою математику.

Суммарное отставание от времени

Поскольку я знаю точное время смены сцены, я должен иметь возможность генерировать «внешние временные коды» (из блоков выше) для mkvmerge, чтобы идеально синхронизировать вывод!

Подвопросы:

  1. Является ли это лучшим подходом (кроме попыток выяснить, что пошло не так в первую очередь)? Поскольку я использую свои видеокадры в качестве эталона, если я использую изменения сцены в качестве временных кодов для звука, будет ли это заставлять видео соответствовать звуку или наоборот? Меня гораздо меньше беспокоит продолжительность, чем синхронизация. Видео было гораздо более трудоемким в производстве, поэтому я бы предпочел потерять немного звука, чем несколько кадров.

  2. Я не понимаю, какие числа использовать в файле временных кодов. Согласно документации mkvmerge "Для видео это ровно один кадр, для аудио это представляет собой один пакет определенного аудиотипа». Поскольку я использую MP3, каков размер пакета? В идеале я мог бы указать размер пакета (в аудиокодировщике?), который соответствует моему размеру блока (512), чтобы все было последовательно и просто. Могу ли я сделать это с помощью ffmpeg?

Спасибо!


person b..    schedule 12.04.2017    source источник
comment
Являются ли скорости (частота кадров, битрейт) постоянными или переменными? Не то, чтобы фактическая синхронизация была нелинейной, но, может быть, это могло бы сбить график?   -  person AkselA    schedule 12.04.2017


Ответы (1)


В итоге я решил причину проблемы в своем коде, поэтому мне не нужно было доводить до конца свою мысль выше. В обсуждении с автором mkvmerge я определил следующие ответы:

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

  2. Для аудио не существует единого размера пакета. Размер пакета зависит от кодировщика и даже может быть разным в разных частях потока. Нужно было бы извлечь количество выборок в каждом пакете из заголовка MKV и использовать его для расчета продолжительности каждого пакета для создания временных меток.

person b..    schedule 19.04.2017