Kombinieren von zwei Live-RTMP-Streams zu einem anderen RTMP-Stream, Synchronisationsprobleme (mit FFMPEG)

Ich versuche (nebeneinander) zwei Live-Videostreams zu kombinieren, die über RTMP kommen, indem ich den folgenden ffmpeg-Befehl verwende:

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

In diesem Beispiel verwende ich tatsächlich zweimal denselben Eingabestream, da das Problem auf diese Weise besser sichtbar ist. Und das Problem ist, dass in der Ausgabe zwei Streams um etwa 2-3 Sekunden nicht synchron sind. Das heißt - ich erwarte (da ich zwei identische Eingaben habe), genau die gleiche linke und rechte Seite in der Ausgabe zu haben. Stattdessen ist die linke Seite 2-3 Sekunden hinter der rechten Seite.

Was meiner Meinung nach passiert, ist, dass ffmpeg der Reihe nach eine Verbindung zu den Eingängen herstellt (ich sehe dies im Ausgabeprotokoll) und die Verbindung zu jedem einzelnen 2-3 Sekunden dauert (vielleicht wartet es auf I-Frame, diese Streams haben ein I-Frame-Intervall von 3 Sekunden). . Dann puffert es wahrscheinlich Frames, die vom ersten (bereits verbundenen) Eingang empfangen wurden, während es sich mit dem zweiten verbindet. Wenn der zweite verbunden ist und Frames von beiden Eingängen bereit sind, durch den Filter geleitet zu werden – der erste Eingangspuffer enthält bereits 2-3 Sekunden Video – und das Ergebnis ist nicht synchron.

Auch das sind nur meine Vermutungen. Also, wie kann ich mein Ziel erreichen? Was ich im Grunde möchte, ist, dass ffmpeg alle "alten" Frames verwirft, die empfangen werden, bevor BEIDE Eingänge verbunden sind, ODER irgendwie "leere" (schwarze?) Frames für die zweite Eingabe platziert, während ich darauf warte, dass diese zweite Eingabe verfügbar wird. Ich habe versucht, mit verschiedenen Flaggen zu spielen, mit PTS (Setpts-Filter), aber ohne Erfolg.

Können Sie eine dieser URLs veröffentlichen oder teilen?
@Gyan Ich kann eine solche URL nicht freigeben, aber sie wird erzeugt, indem mein Desktop über OBS Studio zum rtmp-Endpunkt auf dem Server gestreamt wird (der privat ist, daher kann ich ihn nicht freigeben) und dieser Endpunkt verbraucht wird. Der Server verarbeitet diesen RTMP-Stream nicht, daher denke ich, dass er reproduziert werden kann. Dasselbe passiert, wenn ich meine Kamera (oder eine andere "Live"-Quelle) streame. Ich verbrauche in meinem fraglichen Beispiel zweimal denselben Stream, sodass das Synchronisationsproblem sehr sichtbar ist.
Ich versuche etwas Ähnliches zu tun und habe verschiedene Kombinationen von -vsync, , und ausprobiert -max_delay, aber es noch nicht geschafft, meine beiden Live-Streams zu synchronisieren. -copyts-start_at_zero
@RichardWiseman ja, ich habe das aufgegeben und musste Frames manuell mit C++ mischen (immer noch mit Hilfe von ffmpeg, aber nicht mit dem Befehlszeilenprogramm).

Antworten (2)

Ich habe es zum Laufen gebracht, indem ich -fflags nobuffer -flags low_delay -strict experimentalvor allen Eingängen hinzugefügt habe. Mir wurde beim Lesen dieses Threads geholfen

-vsyncParameter

Videosynchronisierungsmethode.

  • 0: Jeder Rahmen wird mit seinem Zeitstempel vom Demuxer zum Muxer geleitet
  • 1: Frames werden dupliziert und verworfen, um genau die angeforderte konstante Framerate zu erreichen.
  • 2: Frames werden mit ihrem Zeitstempel durchgereicht oder verworfen, um zu verhindern, dass 2 Frames den gleichen Zeitstempel haben
  • -1: Wählt je nach Muxer-Fähigkeiten zwischen 1 und 2. Dies ist die Standardmethode.

Mit -mapkönnen Sie auswählen, aus welchem ​​Stream die Zeitstempel genommen werden sollen. Sie können entweder Video oder Audio unverändert lassen und den/die verbleibenden Stream(s) mit dem unveränderten synchronisieren.

-async samples_per_second

Audio-Sync-Methode. „Dehnt/staucht“ den Audiostream, um ihn an die Zeitstempel anzupassen, der Parameter ist die maximale Anzahl von Samples pro Sekunde, um die das Audio geändert wird. -async 1ist ein Sonderfall, bei dem nur der Anfang des Audiostreams ohne nachträgliche Korrektur korrigiert wird.

-copyts

Kopieren Sie Zeitstempel von der Eingabe zur Ausgabe.