nginx-rtmp mit Standby-Bild wenn kein Publisher verbunden ist

Im Beitrag „Lokal von OBS zu OBS streamen mittels nginx-basiertem RTMP-Server“ zeigte ich, wie man zwischen OBS-Instanzen in einem Netzwerk streamen kann. Das ursprüngliche Streaming-Projekt ist längst abgeschlossen, jedoch bin ich retrospektiv nochmal alle Verbesserungsvorschläge und -möglichkeiten durchgegangen.

Hierbei wurde auch klar, dass ein direkter Stream über eine teils instabile Verbindung insbesondere beim Streaming zu YouTube nicht unproblematisch ist. Um beim Streaming zu YouTube zu vermeiden, dass der Stream entgültig und unwiederbringlich beendet wird (beispielsweise passiert das durch Beendigung des Streams in OBS oder bei einem Verbindungsabbruch, wenn der Stream nicht innerhalb kurzer Zeit wieder gestartet wird) empfiehlt es sich, einen Streaming-Proxy zu verwenden.

Ansich wäre ein kurzer Ausfall kein Problem, jedoch führt der zuvor beschriebene Zustand zwangsläufig dazu, dass ein neuer Stream mit neuer YouTube-URL angelegt werden muss. Unschön, wenn ein Link bereits in sozialen Netzwerken geteilt wurde, aber nur noch auf eine teilweise Aufnahme verweist, statt auf den Livestream selbst.

Dieser wird auf einem Server mit stabiler Internetverbindung, zum Beispiel auf einem virtuellen Server bei einem Serveranbieter, aufgesetzt und übernimmt hier die Aufgabe, den Stream welchen wir übertragen wollen, entgegenzunehmen und diesen weiterzuleiten. Senden wir keinen Stream, hält der Proxy dennoch die Verbindung offen. So die Theorie. In der Praxis lässt sich ein solches Konstrukt mit relativ wenig Konfigurationsaufwand mittels nginx-rtmp realisieren. Komplizierter wird es, möchte man Audio, Video oder Standbilder einblenden lassen, wenn kein Publisher verbunden ist. (Im Normalfall wäre der Stream einfach schwarz, solange niemand einen Stream sendet.)

Nach der folgenden Konfiguration habe ich einige Zeit gesucht, in Google Groups habe ich sie gefunden. Anzupassen sind lediglich:

  • Das Standbild (/tmp/bild.jpg im Beispiel)
  • Installation von curl und ffmpeg
  • YouTube-Streaming-URL (rtmp://a.rtmp.youtube.com/live2/REPLACE_WITH_KEY im Beispiel)

Diese Konfiguration wird in /etc/nginx/nginx.conf hinterlegt:

user www-data;
worker_processes 1;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

error_log /var/log/nginx/error_log info;

events {
        worker_connections 1024;
        use epoll;
}

http {
        include /etc/nginx/mime.types;
        default_type application/octet-stream;

        log_format main
                '$remote_addr - $remote_user [$time_local] '
                '"$request" $status $bytes_sent '
                '"$http_referer" "$http_user_agent" '
                '"$gzip_ratio"';

        ignore_invalid_headers on;

        server {
                listen 0.0.0.0;
                server_name stream;

                access_log /var/log/nginx/stream.access_log main;
                error_log /var/log/nginx/stream.error_log info;

                root /tmp;

                location /control {
                        rtmp_control all;
                }
        }
}

rtmp {
        server {
                listen 1935;
                ping 30s;
                notify_method get;

                application program {
                        live on;

                        pull rtmp://127.0.0.1/switcher/offline name=livefeed static;
                        push rtmp://a.rtmp.youtube.com/live2/REPLACE_WITH_KEY;
                }

                application switcher {
                        live on;

                        pull rtmp://127.0.0.1/stillstore/image1 name=offline;
                        pull rtmp://127.0.0.1/publish/camera1 name=online;
                }

                application stillstore {
                        live on;
                        wait_video on;
                        wait_key on;
                        exec_options on;

                        exec_pull ffmpeg -f image2 -loop 1 -re -r 25 -i /tmp/bild.jpg -f lavfi -re -i anullsrc=sample_rate=48000 -map 0:v -map 1:a -c:v libx264 -g 31 -pix_fmt yuv420p -s 1920x1080 -aspect 16:9 -f flv -rtmp_live live rtmp://127.0.0.1/stillstore/image1 name=image1;

                }

                application publish {
                        live on;
                        wait_video on;
                        wait_key on;
                        exec_options on;

                        exec_publish curl "http://127.0.0.1/control/redirect/subscriber?app=switcher&newname=online";
                        exec_publish_done curl "http://127.0.0.1/control/redirect/subscriber?app=switcher&newname=offline";
               }
        }
}

Anschließend kann der Stream unter „rtmp://127.0.0.1/program/livefeed“ abgerufen werden. An „rtmp://127.0.0.1/publish/camera1“ wird der Stream (z. B. aus OBS) gesendet. Bei korrekter YouTube-Streaming-URL-Konfiguration wird nach einem Neustart von Nginx der Stream auch an YouTube übertragen.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert