Nginx RTMP ffmpeg Streamweiterleitung funktioniert nicht

SirLoading

Ensign
Registriert
Dez. 2021
Beiträge
227
Hallo zusammen,

ich möchte gerne meinen OBS Stream an einen "Streaming-Server" senden und dieser soll das an mehrere Plattformen weiterleiten.
2x Weiterleitung (Funktioniert)
2x via ffmpeg umcodieren auf 720p30 (das funktioniert nicht)

ich habe den ganzen Tag gesucht und nichts hat geholfen.
Eventuell kann mir jemand helfen.

Das ganze läuft auf einem ARM64 Server. (auch auf x86 Server ohne Erfolg getestet)

rtmp {
server {
listen 1935;
chunk_size 4096;
max_message 5M;

application live {
live on;
record off;
meta copy;

push rtmp://localhost/live2/$name;

exec ffmpeg -i rtmp://localhost/live/$name -vcodec libx264 -preset veryfast -x264opts nal-hrd=cbr:force-cfr=1:keyint=60 -b:v 3500k -maxrate 3500k -bufsize 3000k -s 1280x720 -sws_flags lanczos -acodec copy -f flv rtmp://localhost/live3/$name;

}

application live2 {
live on;
record off;
meta copy;

push 1;
push 2;
}

application live3 {
live on;
record off;
meta copy;

push 3;
push 4;
}
}
}

ffmpeg -version:
ffmpeg version 5.1.4-0+deb12u1 Copyright (c) 2000-2023 the FFmpeg developers
built with gcc 12 (Debian 12.2.0-14)
configuration: --prefix=/usr --extra-version=0+deb12u1 --toolchain=hardened --libdir=/usr/lib/aarch64-linux-gnu --incdir=/usr/include/aarch64-linux-gnu --arch=arm64 --enable-gpl --disable-stripping --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libdav1d --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libglslang --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librabbitmq --enable-librist --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libssh --enable-libsvtav1 --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzimg --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --disable-sndio --enable-libjxl --enable-pocketsphinx --enable-librsvg --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libx264 --enable-libplacebo --enable-librav1e --enable-shared
libavutil 57. 28.100 / 57. 28.100
libavcodec 59. 37.100 / 59. 37.100
libavformat 59. 27.100 / 59. 27.100
libavdevice 59. 7.100 / 59. 7.100
libavfilter 8. 44.100 / 8. 44.100
libswscale 6. 7.100 / 6. 7.100
libswresample 4. 7.100 / 4. 7.100
libpostproc 56. 6.100 / 56. 6.100


Vielen Dank
Grüße
SirLoading
 
wie hüpft das von live/ über live2/ nach live3/ ?

kann man push und exec überhaupt zusammen verwenden?

in der doku steht "full path to the binary should be provided" du schreibst aber nur ffmpeg - ist PATH gesetzt?

fehler mitprotokollieren? laut doku 2>>/tmp/ffmpeg-$name.log an den befehl dranhängen
 
GTrash81 schrieb:
en Stream in eine Datei schreiben lässt,
Geht auch nicht.
Wenn ich aber die Quelle ändere auf ein Testbild, dann geht es.

kieleich schrieb:
Wenn ich den Push nach live2 raus mache, ändert sich auch nichts.
Wenn ich das ffmpeg nur als Push mache, dann sendet live nach live2 und live3.

kieleich schrieb:
push und exec überhaupt zusammen verwenden
Ja, laut dem was ich gelesen habe schon.
Hatte das vor 6 Jahren mal auf einer Workstation laufen. (Hab die config leider nicht mehr)

kieleich schrieb:
ist PATH gesetzt?
Ja, hatte es aber auch schon mit gesamten Pfad versucht.

kieleich schrieb:
fehler mitprotokollieren?
Wollte ich heute noch machen.

jb_alvarado schrieb:
Nginx RTMP ist zwar sehr beliebt
Und man hat eine zusätzliche Latenz von ca 2 bis 3 Sekunden.
Bei Restreamer habe ich ca. 24 Sekunden wenn das auf der letztendlichen Plattform landet.
Direkt von OBS sind es ca 5 bis 6 Sekunden.
Bei Nginx RTMP sind es 6 bis 7 Sekunden.

Zudem bricht die Verbindung zwischen OBS und Restreamer immer ab, wenn das Bild aufwendig wird.
Gleiches Problem hatte ich auch bei Nginx RTMP, "max_message 5M" hat das behoben.

SRS müsste ich mir Mal anschauen.
 
Wenn du SRS mal testen willst könnte eine Config in etwa so aufgebaut sein:

NGINX:
listen              1935;
max_connections     200;
daemon              off;
pid                 /usr/local/srs/objs/srs.pid;
srs_log_tank        console;
srs_log_file        /var/log/srs.log;
ff_log_dir          /tmp;

# can be: verbose, info, trace, warn, error
srs_log_level       error;

stats {
    network         0;
    disk            sda vda xvda xvdb;
}

vhost __defaultVhost__ {
    enabled             on;
    mix_correct         on;

    # für low latency: https://ossrs.io/lts/en-us/docs/v5/doc/low-latency
    # ffmpeg für low latency optimieren: https://stackoverflow.com/questions/16658873/how-to-minimize-the-delay-in-a-live-streaming-with-ffmpeg

    forward {
        enabled on;
        destination 10.10.0.2:1935 10.10.0.3:1935;
    }

    transcode live/stream {
        enabled     on;
        ffmpeg      /usr/bin/ffmpeg;
        engine local_network {
            enabled         on;
            iformat         live_flv;
            vfilter {
                v           error;
            }

            vcodec          libx264;
            vprofile        main;
            vpreset         faster;

            vparams {
                level       3.1;
                pix_fmt     yuv420p;
                crf         21;
                x264-params keyint=50:min-keyint=25:scenecut=-1;
                maxrate     3400k;
                bufsize     6800k;
                tune        zerolatency;
            }

            acodec          libfdk_aac;
            abitrate        128;
            asample_rate    44100;
            oformat         flv;
            output          rtmp://10.10.0.4/live/stream;
        }

        engine youtube {
            enabled         off;
            iformat         live_flv;
            vfilter {
                v           error;
            }

            vcodec          copy;
            acodec          copy;
            oformat         flv;
            output          rtmp://a.rtmp.youtube.com/live2/secret;
        }

        engine record {
            enabled         on;
            iformat         live_flv;
            vfilter {
                v           quiet;
            }
            vcodec          libx264;
            vfps            25;
            vwidth          480;
            vheight         270;
            vthreads        1;
            vprofile        main;
            vpreset         faster;
            vparams {
                crf                 33;
                reset_timestamps    1;
                segment_time        21600;
                strftime            1;
                }
            acodec          libfdk_aac;
            abitrate        26;
            asample_rate    44100;
            achannels       1;
            aparams {
                profile:a   aac_low;
            }
            oformat         segment;
            output          /opt/tmp/[stream]_%Y-%m-%d_%H-%M-%S.mkv;
        }

    }
}

Spezielle low latency Einstellungen habe ich da noch nicht drin, da würde ich mich an die einzelnen Parameter herantasten. Finde da nicht alle immer geeignet, kommt auf die Situation an.

Gerade wenn ffmpeg zwei mal um konvertieren soll, unbedingt die Systemauslastung im Auge behalten. Vielleicht kommen auch daher die Abbrüche.

Ab version 5 gibt es auch dynamische Forward, das verwenden wir und ist um einiges flexibler. Allerdings habe wir uns dazu die API angepasst um on the fly die Zieladressen ändern zu können, ist vielleicht nichts für jedermann.
 
Zuletzt bearbeitet:
Hört sich für mich dann so an, als ob die Quelle das Problem ist.
In anderen Tutorials sehe ich die Option "-re".
Probier es daher mal mit diesem Kommando:
exec ffmpeg -re -i rtmp://localhost/live/$name -vcodec libx264 -preset veryfast -x264opts nal-hrd=cbr:force-cfr=1:keyint=60 -b:v 3500k -maxrate 3500k -bufsize 3000k -s 1280x720 -sws_flags lanczos -acodec copy -f flv rtmp://localhost/live3/$name;
 
Wenn die Quelle schon realtime ist, und das ist sie von OBS aus schon, macht -re eigentlich keinen Sinn. Der Parameter stellt nur sicher, dass eine Quelle in realtime gelesen wird, und nicht schneller. Also wenn die Quelle 25 FPS hat werden auch genau 25 Frames in einer Sekunde gelesen.
 
jb_alvarado schrieb:
wenn ffmpeg zwei mal um konvertieren soll
Deshalb hatte ich bei RTMP die konvertierung 1x gemacht und dann auf die app geleitet, da dann auf X-Streams.
Ja, das geht. :)

jb_alvarado schrieb:
unbedingt die Systemauslastung im Auge behalten
Was würdest du für einen Server empfehlen? (Hoster im Internet)
Hab das spaßeshalber mal auf meinem ODroid H3 (SmartHome / Daily Server) getestet mit Restreamer.
Nutzt ihn komplett aus bei 1440p zu 720p, aber funktioniert.

Hätte bei Netcup einen Root genommen.

Naja, zur Not könnte ich auch einen 1440p60 und einen 720p30 Stream von mir auf den Server senden und der verteilt das weier.

jb_alvarado schrieb:
Ist quasi wie RTMP nur neuer / besser?
Kann SRS auch mit AV1 Codec umgehen?
Also einen AV1 Stream zum Server, der leitet das zu YT weiter und dann wird in 264 konvertiert für die anderen Plattformen?

Derzeit bekommt YT den Stream als AV1, weniger Bitrate und meine GPU macht das Problemlos.

jb_alvarado schrieb:
Ab version 5 gibt es auch dynamische Forward, das verwenden wir und ist um einiges flexibler.
Das brauche ich nicht, aber gut zu wissen. :)

GTrash81 schrieb:
In anderen Tutorials sehe ich die Option "-re".
Habe ich schon versucht, hat nichts geändert.

Was mir aufgeallen ist mit "htop":
Wenn ich ein Testbild starte, dann werden X Instanzen gestartet.
Wenn ich den Stream starte, dann nur 1.
 
SirLoading schrieb:
Was würdest du für einen Server empfehlen? (Hoster im Internet)
Hab das spaßeshalber mal auf meinem ODroid H3 (SmartHome / Daily Server) getestet mit Restreamer.
Nutzt ihn komplett aus bei 1440p zu 720p, aber funktioniert.

Hätte bei Netcup einen Root genommen.
Das ist schwer zu beantworten, weil das von verschiedenen Faktoren abhängt.

Wenn du einen Server hast, dessen Traffic nicht sonderlich ausgelastet ist und du nur zu Streamingplattformen senden würdest, spielt die Bitrate keine so große Rolle. Dann könnte man ein ffmpeg preset wie superfast nehmen (x264). Dafür braucht man nicht viel Rechenleistung. Willst du aber direkt für Clients mehrere Auflösungen komprimieren, möchtest du auch eine geringere Bitrate haben und dementsprechend brauchst du dann mehr Rechenleistung.

Wir haben ein Internet TV welches 24/7 läuft und ab und zu haben wir Live Events die dann eingespeist werden. Dazu nutzen wir 2 VMs, eine nur zum Weiterleiten, weil wir manchmal auf mehrere Plattformen gleichzeitig streamen, die braucht kaum Leistung (1 Kern würde locker reichen). Die andere die das TV streamt, konvertiert in 4 Auflösungen, plus eine ffmpeg Intanz die auf Live Events wartet. Die hat 8 Threads die zu ~60% ausgelastet ist.

Allerdings laufen unserer VMs auf eigenen Root Servern bei Hetzner. Wenn du keinen Rootserver hast, sollten die VMs zumindest garantierte CPU Leistung haben.

SirLoading schrieb:
Naja, zur Not könnte ich auch einen 1440p60 und einen 720p30 Stream von mir auf den Server senden und der verteilt das weier.
Wäre eine Möglichkeit, wenn deine Internetleitung stabil ist. Dann berauchst auf jeden Fall nicht so leistungsfähige VMs.

SirLoading schrieb:
Ist quasi wie RTMP nur neuer / besser?
Besser ist relativ, kommt auf die Bedürfnisse an. Bei Nginx RTMP habe ich den Eindruck, dass das nicht mehr weiter entwickelt wird, das Github Repo hatte das letzte Update vor 2 Jahren. SRS hingegen schon, hat auch mehr Funktionen.
SirLoading schrieb:
Kann SRS auch mit AV1 Codec umgehen?
Ja kann es. Es könnte auch SRT.
SirLoading schrieb:
Also einen AV1 Stream zum Server, der leitet das zu YT weiter und dann wird in 264 konvertiert für die anderen Plattformen?
Würde ich persönlich von abraten, wenn nicht gute Gründe vorliegen. Ich würde das Format wählen welches die meisten Plattformen unterstützen und nur das umkonvertieren was wirklich nötig ist. YT profitiert nicht von AV1, da war sogar lange h264 am besten. AV1 macht da Sinn, wo die Leitung nicht mehr hergibt.

SirLoading schrieb:
Das brauche ich nicht, aber gut zu wissen. :)
Das ist leider etwas blöde gelöst, Weiterleiten geht standardmäßig nur zu Adressen, Streamschlüssel kann dabei nicht geändert werden. Um z.B. zu Youtube weiterzuleiten brauchst es den Backend-Parameter und das geht, soviel ich weiß, nur mit einen separaten API Server. Könnte dir unsere angepasste Version geben, wenn Interesse besteht. Ist eine Go-App und wird per SystemD gestartet.

Was auch recht gut geht, ist eine weitere ffmpeg Instanz in SRS zu startet, aber mit -c copy, braucht auch nicht viel Leistung:

NGINX:
engine youtube_live {
    enabled         on;
    vcodec          copy;
    acodec          copy;
    output          rtmp://a.rtmp.youtube.com/live2/qwqm-f1sf-9g1m-868s;
}

SirLoading schrieb:
Was mir aufgeallen ist mit "htop":
Wenn ich ein Testbild starte, dann werden X Instanzen gestartet.
Wenn ich den Stream starte, dann nur 1.
Ich stelle in HTOP die userland process threads immer aus. Finde das mehr verwirrend, als hilfreich.
 
Zuletzt bearbeitet:
jb_alvarado schrieb:
Wenn du einen Server hast
Würde mir einen bei netcup holen, der 6 Kerne hat.
Meine alte Workbench hatte 6C/12T und war zu 40 % ausgelastet.

Leider bin ich Gesundheitlich eine längere Zeit ausgefallen und habe auf Twitch meinen Account verloren, da ich keinen Zugriff mehr auf die E-Mail-Adresse habe. (Domain gekündigt um Geld zu sparen...)
Twitch-Support war leider keine Hilfe. ;)
Da mittlerweile als Twitch-Partner Multistreaming erlaubt ist, muss ich mit dem neuen Account nur den Partnerstatus bekommen, dann fällt das Kodieren weg.

jb_alvarado schrieb:
wenn deine Internetleitung stabil ist
175/40 reichen, nur bei Online-Games ist das immer mit erhörten Ping etwas nachteilig.
Aktuell Streame ich nur auf YT und Twitch, eben wegen der Leitung. (Möchte aber wieder andere Plattformen rein nehmen.

jb_alvarado schrieb:
Würde ich persönlich von abraten
AV1 @ Bitrate: 18000 ergibt bei mir vergleichbare Qualität wie h264 @ 22000.
Wenn eben nur ein Stream raus geht, dann wäre das kein Problem mit h264 @ 22000.

jb_alvarado schrieb:
Weiterleiten geht standardmäßig nur zu Adresse, Streamschlüssel kann dabei nicht geämndert werden.
Das Betrifft ja nur, wenn man diesen ändern möchte?
Leider hat das FAQ bei den Bildern keine DE / EN Schriften... xD

Nur noch mal für mein Verständnis:
Wenn ich meinen Stream von OBS an den Server sende, dann kann ich den direkt ohne kodieren an YT usw. weiterleiten?
Dann einmal Auflösung und Bitrate für Twitch usw. auf 720p30 machen und verteilen?

Wenn das geht, dann werde ich es mir auf jeden Fall anschauen.

Danke.
Ergänzung ()

Du hast in deinem Edit den Streamschlüssel drin!!!!!!!
 
SirLoading schrieb:
AV1 @ Bitrate: 18000 ergibt bei mir vergleichbare Qualität wie h264 @ 22000.
Wenn eben nur ein Stream raus geht, dann wäre das kein Problem mit h264 @ 22000.
Ok, wenn du nebenbei noch spielst und deine Leitung dafür braucht kann AV1 schon Sinn machen.
SirLoading schrieb:
Wenn ich meinen Stream von OBS an den Server sende, dann kann ich den direkt ohne kodieren an YT usw. weiterleiten?
Dann einmal Auflösung und Bitrate für Twitch usw. auf 720p30 machen und verteilen?
Ja das geht. Der einfachste Weg ohne backend forward Einstellung würde dann in etwa so aussehen:

NGINX:
listen              1935;
max_connections     200;
daemon              off;
pid                 /usr/local/srs/objs/srs.pid;
srs_log_tank        console;
srs_log_file        /var/log/srs.log;
ff_log_dir          /tmp;

# can be: verbose, info, trace, warn, error
srs_log_level       error;

stats {
    network         0;
    disk            sda vda xvda xvdb;
}

vhost __defaultVhost__ {
    enabled             on;
    mix_correct         on;

    # für low latency: https://ossrs.io/lts/en-us/docs/v5/doc/low-latency
    # ffmpeg für low latency optimieren: https://stackoverflow.com/questions/16658873/how-to-minimize-the-delay-in-a-live-streaming-with-ffmpeg

    transcode live/stream {
        enabled     on;
        ffmpeg      /usr/bin/ffmpeg;
        engine youtube {
            enabled         on;
            vcodec          copy;
            acodec          copy;
            oformat         flv;
            output          rtmp://a.rtmp.youtube.com/live2/secret;
        }

        engine convert {
            enabled         on;
            iformat         live_flv;
            vfilter {
                v           quiet;
            }
            vcodec          libx264;
            vfps            30;
            vwidth          1280;
            vheight         720;
            vpreset         veryfast;
            vparams {
                crf                 22;
                }
            acodec          aac;
            abitrate        128;
            asample_rate    44100;
            oformat         flv;
            output          rtmp://stream.local/live/forward;
        }
    }
}

vhost stream.local {
    enabled             on;

    transcode live/forward {
        enabled     on;
        ffmpeg      /usr/bin/ffmpeg;
        engine twich {
            enabled         on;
            vcodec          copy;
            acodec          copy;
            oformat         flv;
            output          rtmp://twitch.../live/secret;
        }

        engine other {
            enabled         on;
            vcodec          copy;
            acodec          copy;
            oformat         flv;
            output          rtmp://other.../live/secret;
        }
    }
}

Mit backend forward:

NGINX:
listen              1935;
max_connections     200;
daemon              off;
pid                 /usr/local/srs/objs/srs.pid;
srs_log_tank        console; # file;
srs_log_file        /var/log/srs.log;
ff_log_dir          /dev/null;

# can be: verbose, info, trace, warn, error
srs_log_level       error;

vhost __defaultVhost__ {
    enabled             on;

    publish {
        # kann Sinn machen, um Übertragunsabbrüche abzufangen.
        normal_timeout      10000;
    }

    play {
        time_jitter     full;
        mix_correct     on;
    }

    forward {
        enabled on;
        backend http://127.0.0.1:8085/api/v1/forward; # hier wird dann zu youtube weitergeleitet
    }

    transcode live/stream {
        enabled     on;
        ffmpeg      /usr/bin/ffmpeg;
        engine record {
            enabled         on;
            iformat         live_flv;
            vfilter {
                v           quiet;
            }
            vcodec          libx264;
            vfps            30;
            vwidth          1280;
            vheight         720;
            vpreset         veryfast;
            vparams {
                crf                 22;
                }
            acodec          aac;
            abitrate        128;
            asample_rate    44100;
            oformat         flv;
            output          rtmp://stream.local/live/forward;
        }
    }
}

vhost stream.local {
    enabled             on;

    forward {
        enabled on;
        backend http://127.0.0.1:8085/api/v1/forward; # hier wird zu allen anderen PLattformen weitergeleitet
    }
}

In beiden Fällen muss die /etc/hosts erweiter werden mit: 127.0.0.1 stream.local
SirLoading schrieb:
Du hast in deinem Edit den Streamschlüssel drin!!!!!!!
Kein Problem, ist nicht meiner :-). hatte das aus der Doku.

Nachtrag:

Vielleicht kann man sich den internen Stream zu stream.local sparen und den tee pseudo muxer von ffmpeg nehmen. Damit kann man den gleichen Output zu mehreren Quellen schicken. Habe das aber noch nicht mit SRS zusammen getestet.
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: SirLoading
Okay, schaue ich mir nachher an, Danke.

Wie sieht das zwecks Sicherheit aus?
Kann hier ein Token gesetzt werden, der Missbrauch verhindert?
 
Und du hast es in VM oder Docker laufen?h würde es in Docker laufen lassen.
 
Habe das jetzt mal lokal im Docker.
Wo finde ich die Config?
Steht bei ossrs nichts dazu?
 
Ich komme leider mit SRS nicht klar.
Ich weiß nicht wo ich da was bearbeiten muss.
 
Zurück
Oben