Я пытаюсь объединить (бок о бок) два живых видеопотока, поступающих через RTMP, используя следующую команду ffmpeg:
ffmpeg -i "rtmp://first" -i "rtmp://first" -filter_complex "[0v][1v]xstack=inputs=2:layout=0_0|1920_0[stacked]" -map "[stacked]" -preset ultrafast -vcodec libx264 -tune zerolatency -an -f flv output.flv
В этом примере я фактически использую один и тот же входной поток два раза, потому что так проблема более заметна. И проблема в том, что два потока на выходе рассинхронизированы примерно на 2-3 секунды. То есть - я ожидаю (поскольку у меня два одинаковых входа), чтобы на выходе были точно такие же левая и правая стороны. Вместо этого левая сторона отстает от правой на 2-3 секунды.
Я считаю, что происходит то, что ffmpeg подключается к входам по порядку (я вижу это в журнале вывода), и подключение к каждому из них занимает 2-3 секунды (возможно, он ждет I-кадр, эти потоки имеют интервал I-кадра 3 секунды) . Затем, вероятно, он буферизует кадры, полученные с первого (уже подключенного) входа, при подключении ко второму. Когда подключен второй и кадры с обоих входов готовы к прохождению через фильтр - буфер первого входа уже содержит 2-3 секунды видео - и результат рассинхронизирован.
Опять же, это только мои предположения. Итак, как я могу достичь своей цели? В основном я хочу, чтобы ffmpeg отбрасывал все «старые» кадры, полученные до того, как ОБА входа будут подключены ИЛИ каким-то образом поместили «пустые» (черные?) кадры для второго ввода, ожидая, пока этот второй ввод станет доступным. Пробовал играть с разными флажками, с PTS (фильтр настроек), но безрезультатно.
Я заработал, добавив -fflags nobuffer -flags low_delay -strict experimental
перед всеми входами. Помогло прочитать эту тему
-vsync
параметр
Метод синхронизации видео.
0
: каждый кадр передается с отметкой времени от демультиплексора к мультиплексору.1
: Кадры будут дублироваться и отбрасываться для достижения требуемой постоянной частоты кадров.2
: кадры передаются с отметкой времени или отбрасываются, чтобы не допустить, чтобы 2 кадра имели одну и ту же отметку времени.-1
: Выбор между 1 и 2 в зависимости от возможностей мультиплексора. Это метод по умолчанию.С помощью -map
вы можете выбрать, из какого потока следует брать метки времени. Вы можете оставить видео или аудио без изменений и синхронизировать оставшиеся потоки с неизмененным.
-async samples_per_second
Метод синхронизации звука. «Растягивает/сжимает» аудиопоток, чтобы он соответствовал временным меткам, параметр — максимальное количество отсчетов в секунду, на которое изменяется звук. -async 1
является особым случаем, когда корректируется только начало аудиопотока без какой-либо последующей коррекции.
-copyts
Копировать временные метки с входа на выход.
Гьян
Эвк
IpsRich
-vsync
, и-max_delay
, но пока не удалось синхронизировать два моих прямых потока.-copyts
-start_at_zero
Эвк