Ein 24/7-Stream ohne Reconnect zwischen Videos: ein ffmpeg, das über eine Pipe gespeist wird
Video
Ein Live-Kanal, der fertige Videos rund um die Uhr abspielt, hat zwei einfache Designs, und beide haben einen Haken. Ein Neustart von ffmpeg für jedes Video trennt die RTMP-Verbindung bei jedem Wechsel. Eine Concat-Playlist wird nur beim Start eingelesen, sodass ein neues Video auf den nächsten Neustart wartet.
Das Design
Jedes Video wird einmal in MPEG-TS in der Größe und Bildrate des Streams konvertiert; ein vertikales Video liegt auf einer unscharfen Kopie seiner selbst statt auf schwarzen Balken. Ein ffmpeg-Prozess liest MPEG-TS von seinem Standard-Input und kodiert mit konstanter Bitrate und einem Keyframe alle zwei Sekunden, wie es Live-Ingest erwartet. Ein kleiner Feeder schreibt die vorbereiteten Dateien nacheinander in diese Pipe, in Echtzeit-Tempo, und wählt bei jedem Wechsel die nächste Datei: zuerst noch nie gespielte Videos, dann die am längsten zurückliegenden. Der MPEG-TS-Reader von ffmpeg erkennt, dass die Zeitstempel jeder Datei von vorn beginnen, und verschiebt sie, sodass die Ausgabe ohne Unterbrechung weiterläuft.
Detail eins: Tempo ab dem ersten Byte
Unsere erste Version startete ihre Uhr, wenn ffmpeg startete. Die Vorbereitung der ersten Datei dauerte neun Sekunden, also glaubte der Feeder, er sei neun Sekunden im Rückstand, und schickte alles auf einmal. Der Start der Uhr beim ersten geschriebenen Byte löste das Problem: Ein 53-Sekunden-Lauf erzeugte 53 Sekunden Stream.
Detail zwei: Der Audio-Übergang
Beim Wechsel begann das Audio der nächsten Datei 17 Millisekunden, bevor das Audio der vorherigen Datei endete. Der Encoder warnte, dass sein Input „zeitlich rückwärts“ laufe, und der Muxer korrigierte einen Zeitstempel. Resampling mit aresample=async=1:min_hard_comp=0.01:first_pts=0 schneidet solche Überlappungen zu oder füllt sie auf, bevor der Encoder sie sieht. In einem Lauf von knapp über einer Minute mit fünf Wechseln stiegen alle Audio- und Video-Zeitstempel im empfangenen Stream, und der Stream wurde ohne einen einzigen Fehler dekodiert.
Detail drei: Manche Warnungen sind normal
Jede Datei setzt ihre MPEG-TS-Zähler und ihre Uhr zurück, daher meldet ffmpeg bei jedem Wechsel „Packet corrupt“ und „timestamp discontinuity“. Diese Zeilen sind erwartet, und wir halten sie aus dem Log heraus, damit echte Fehler hervorstechen.
Der Watchdog
Wenn ffmpeg beendet wird oder sein Fortschritt eine Minute lang stillsteht, startet der Stream mit zunehmenden Pausen neu und sendet nach wiederholten Fehlversuchen eine Nachricht. In unserem Test haben wir den Encoder manuell beendet; der Stream war sieben Sekunden später wieder da, und ein während des Laufs hinzugefügtes Video wurde ohne erneute Verbindung in die Rotation aufgenommen. Ein Neustart ist eine kurze erneute Verbindung, daher sollten Sie den YouTube-Broadcast so einstellen, dass er automatisch startet und nicht automatisch stoppt. Der Stream-Key wird in jeder Protokollzeile maskiert, auch in den von ffmpeg selbst erzeugten. Studio liefert diesen Live-Kanal als systemd-Dienst aus.