Combinar dos transmisiones RTMP en vivo en otra transmisión RTMP, problemas de sincronización (con FFMPEG)

Estoy tratando de combinar (uno al lado del otro) dos transmisiones de video en vivo que vienen a través de RTMP, usando el siguiente comando 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

En este ejemplo, en realidad uso el mismo flujo de entrada dos veces, porque el problema es más visible de esta manera. Y el problema está en la salida, dos flujos no están sincronizados por unos 2-3 segundos. Es decir, espero (ya que tengo dos entradas idénticas) tener exactamente los mismos lados izquierdo y derecho en la salida. En cambio, el lado izquierdo está detrás del lado derecho por 2-3 segundos.

Lo que creo que está sucediendo es que ffmpeg se conecta a las entradas en orden (veo esto en el registro de salida) y la conexión a cada una toma de 2 a 3 segundos (tal vez espera I-frame, esas transmisiones tienen un intervalo de I-frame de 3 segundos) . Entonces, probablemente, almacena en búfer los marcos recibidos de la primera entrada (ya conectada), mientras se conecta a la segunda. Cuando el segundo está conectado y los cuadros de ambas entradas están listos para pasar por el filtro, el primer búfer de entrada ya contiene 2-3 segundos de video, y el resultado no está sincronizado.

Una vez más, eso es sólo mis suposiciones. Entonces, ¿cómo puedo lograr mi objetivo? Básicamente, lo que quiero es que ffmpeg descarte todos los cuadros "antiguos" recibidos antes de que AMBAS entradas estén conectadas O de alguna manera coloque cuadros "vacíos" (¿negros?) Para la segunda entrada, mientras espera que esa segunda entrada esté disponible. Intenté jugar con varias banderas, con PTS (setpts filter), pero fue en vano.

¿Puede exponer o compartir una de estas URL?
@Gyan No puedo compartir dicha URL, pero se produce al transmitir mi escritorio a través de OBS Studio al punto final rtmp en el servidor (que es privado, por lo que no puedo compartirlo) y consumir ese punto final. El servidor no realiza ningún procesamiento de ese flujo RTMP, por lo que creo que se puede reproducir. Lo mismo sucede cuando transmito mi cámara (o cualquier otra fuente "en vivo"). Consumo la misma transmisión 2 veces en mi ejemplo en cuestión, por lo que el problema de sincronización es muy visible.
Estoy tratando de hacer algo similar y probé varias combinaciones de -vsync, y pero aún no logré sincronizar mis dos transmisiones en vivo -max_delay.-copyts-start_at_zero
@RichardWiseman sí, me di por vencido y tuve que mezclar fotogramas manualmente usando C ++ (todavía con la ayuda de ffmpeg, pero no con la utilidad de línea de comandos).

Respuestas (2)

Lo hice funcionar agregando -fflags nobuffer -flags low_delay -strict experimentalantes de todas las entradas. Me ayudaron a leer este hilo

-vsyncparámetro

Método de sincronización de vídeo.

  • 0: Cada cuadro se pasa con su marca de tiempo del demuxer al muxer
  • 1: Los fotogramas se duplicarán y eliminarán para lograr exactamente la frecuencia de fotogramas constante solicitada.
  • 2: Los fotogramas se pasan con su marca de tiempo o se eliminan para evitar que 2 fotogramas tengan la misma marca de tiempo
  • -1: elige entre 1 y 2 dependiendo de las capacidades muxer. Este es el método por defecto.

Con -mappuede seleccionar de qué transmisión se deben tomar las marcas de tiempo. Puede dejar el video o el audio sin cambios y sincronizar las transmisiones restantes con la transmisión sin cambios.

-async samples_per_second

Método de sincronización de audio. "Estira/aprieta" el flujo de audio para que coincida con las marcas de tiempo, el parámetro son las muestras máximas por segundo por las que se cambia el audio. -async 1es un caso especial en el que solo se corrige el inicio del flujo de audio sin ninguna corrección posterior.

-copyts

Copie las marcas de tiempo de la entrada a la salida.