6. Experiment 6: [Finden einer alternative zu Discord’s Streaming Feature]
Datum: [13.06.2024] Thema: [Finden einer alternative zu Discord’s Streaming Feature]
6.1. Was sind Discord Streams?
Ist man in Discord mit einem Sprachkanal verbunden, so kann man entweder seinen kompletten Bildschirm oder ein einzelnes Fenster an andere Teilnehmer übertragen. Anzumerken ist hier die Einfachheit wie Bild und Ton in wenigen Klicks übertragen werden können.
6.2. Was sind die Nachteile
In der freien Version, nur 720p in 30 fps
Closed-Source implementierung (bedenklich beim teilen des kompletten Bildschirms)
Mehrere Bugs (Unendliches Laden, Gelber Rahmen um gesamten Bildschirm, etc.)
Miserable Linux Implementation (Hohe Last, Kein Wayland Support)
Wenig Kontrolle über fortgeschrittene Einstellungen
6.3. Was muss eine Alternative leisten
Schnelles Starten und Beitreten in einen Stream
Gute Stream und Audio Qualität
Wenig Latenz
Privatsphäre
Einfaches Aufsetzen
Implementation von nur dem Nötigsten
Open-Source
Eigens gehostet
6.4. Offensichtliche Alternativen
Meeting Software wie Jitsi oder Meetzi erfüllen zwar viele dieser Ansprüche fallen aber im Sinne der Simplizität flach. Unser Ziel ist es lediglich den Streaming Teil von Discord zu ersetzen, nicht die komplette Dokumentation. Zoom und Teams/Skype fallen aus den selben gründen weg, zusätzlich zu deren Closed-Source Natur.
6.5. Streaming Server Implementation
Die vielversprechendste Lösung sind Implementierung von Servern für die verschiedene Protokolle.
RTMP - Real-Time Messaging Protocol - Benutzt von unter anderem Twitch
SRT - Secure Reliable Transport - Open-Source
WebRTC - Web Real-Time Communication - Open-Source
6.6. Server
6.6.1. nginx
Es ist möglich einen vollständigen RTMP-Server mit nginx umzusetzen. Dies ist allerdings mit technischen Wissen verbunden und erfordert ein eigenes Konfigurieren von nginx und ffmpeg. Idealerweise würden wir uns eine etwas umfangreichere implementierung wünschen
6.6.2. Owncast
Owncast ist eine Open-Source Alternative zu Twitch. Im Gegensatz zu diesem, ist es aber möglich seinen eigenen Server zu hosten und sogar im Fediverse freizugeben. Es implementiert eine vollständige Umgebung zum Streamen von Inhalten und Interaktion mit Zuschauern durch einen Live Chat. Man kann verschiedene Nutzer erstellen und somit auch Kollegen das Streamen ermöglichen. Trotz der einfachen Installation und guten Konfigurationsmöglichkeiten, ist das ganze System leider ein wenig zu Umfangreich und sprengt unsere Anforderung an eine simple Software.
6.6.3. Galéne
Galéne ist ein Videokonferenz Server welche für Vorlesungen an der Universität Paris und der Sorbonne Universität entwickelt wurde. Es ist in Go geschrieben und benutzt WebRTC für die Übertragung. Im Gegensatz zu Owncast ist es deutlich leichtgewichtiger und einfacher. Erneut stört aber trotzdem die (für unsere Zwecke) unnötige Implementierung von Text- und Voicechat. Desweiteren ist dieses Programm nicht allzu einfach in der Installation und im Aufsetzen des Servers.
6.6.4. MediaMTX
MediaMTX ist ein Open-Source Medien Server und Proxy der über eine Vielzahl an Protokollen transformieren und weiterleiten kann. Es wird als einzelne Executable vertrieben und besitzt somit keine Abhängigkeiten. Die verschiedenen Protokolle können alle über ein simples Config File angepasst werden. Das aufsetzen eines brauchbaren Servers ist somit extem simpel und schnell gemacht. Ein weiterer Vorteil an MediaMTX ist wie ein Source-Stream von einem Protokoll automatisch an alle weiteren Protokolle weitergeleitet wird. So kann man zum Beispiel seinen Bildschirm über RTMP streamen, diesen aber als Zuschauer über SRT oder WebRTC sehen. Durch die weitere anbindung an ffmpeg sind hierbei auch deutlich komplexere Umwandlungen und Konfigurationen möglich, sollten die Basis-Einstellungen nicht ausreichen. MediaMTX erfüllt somit alle unseren gesetzten Anforderungen und eignet sich für unsere weiteren Experimente.
6.7. Streaming Setup
Nachdem wir nun wissen welchen Server wir benutzen werden, gilt es nun ein geeignetes Setup zu finden, um vollen gebrauch von diesem zu machen.
6.7.1. Open Broadcaster Software
Eine der besten und weit verbreitesten Streaming Studios ist OBS.
Mit diesem ist es möglich verschiedenste Bereiche seines Bildschirms, Kamera, und Audio aufzuzeichnen und bei Bedarf direkt an einen Media Server zu streamen.
Oftmals wird diese Software benutzt um Video für Youtube aufzunehmen, oder auf Twitch zu streamen. Es ist allerdings auch möglich eigene Zieladressen zu definieren.
Glücklicherweise handelt es sich hierbei um Open-Source Projekt und passt somit auch sauber in unsere Anforderungen.
Sobald man eine Scene erstellt und eine Videoquelle konfiguriert hat, so kann man in den Einstellungen unter Stream, als Platform „Benutzerdefiniert…“ auswählen.
In den zwei erscheinenden Textfeldern müssen nun die Serverinformationen und der Pfad eingetragen werden. Die Art und Weise wie diese aussehen wird in der ReadMe von MediaMTX ausführlich erklärt.
Empfohlen wird das Streamen über das RTMP Protokoll
Hierfür müssen folgende Daten eingegeben werden:
- Server: rtmp://<server-ip>
- Streamschlüssel: <pfad>
Die Server IP ist hierbei die IP des MediaMTX Servers und der Pfad ist ein selbst gewählter Name um den Stream später zu referenzieren.
Somit wäre die Streamer Seite fürs erste aufgesetzt. Jetzt müssen wir uns noch den Zuschauern widmen.
6.7.2. VLC Media Player
Der VLC Media Player ist ein Open-Source Multimediaplayer welcher mit einer unglaublichen Menge an Videoformaten umgehen kann. Darunter auch gestreamte Daten über beispielsweise RTMP oder SRT. In unseren Tests lieferte SRT tendenziell die bessere Leistung.
Um nun den Stream zu empfangen müsen wir dessen Quelle angeben. Dafür navigieren wir unter „Medien“ zu „Netzwerkstream öffnen…“
Hier öffnet sich ein Fenster in welchen wir eine Netzwerkadresse eingeben können. Auch hier entnehmen wir diese wieder aus der ReadMe von MediaMTX:
srt://<server-ip>:8890?streamid=read:<pfad>
Server IP und Pfad sollten hier die selben sein wie die vorher definierten in OBS.
Nach dem Bestätigen sollte nach ein paar Sekunden der Stream im Fenster auftauchen.
Somit haben wir unser Ziel theoretisch erreicht, allerdings gibt es noch ein paar Verbesserungen die wir vornehmen können.
6.7.3. WebRTC über MediaMTX
Auch wenn das eben beschriebene Setup vollständig funktioniert, ist es dennoch ein wenig unhandlich für nicht allzu technisch begabte. Viele müssen sich den VLC Media Player erst herunterladen und sich dann durch diesen mühevoll durchclicken nur um einen Stream beizutreten. Mit der Einfachheit von Discord kann dies leider nicht mithalten.
Viel eleganter ist es hier den WebRTC Client von MediaMTX zu benutzen. Dieser kann einfach über einen Hyperlink in jedem Browser geöffnet werden und ist somit fast genauso schnell geöffnet wie ein Discord Stream.
Wenn wir uns auf die Adresse http://<server-ip>:8889/<pfad>/
begeben so sollte sogar direkt unser Stream angezeigt werden.
Leider müssen wir feststellen dass unser Ton nicht übertragen wird. Dies liegt daran dass OBS standardmäßig über den MPEG-4 Audiocodec streamt, welcher aktuell inkompatibel mit WebRTC scheint. Glücklicherweise wird in der ReadMe von MediaTMX bereits eine Lösung angeboten, bei der man statt direkt einen Stream eine Aufnahme auf ein Stream starten. Hierbei kann man nun den gewünschten Audiocodec auswählen.
Nach einiger Recherche sind wir jedoch auf eine elegantere Methode gestoßen.
Es ist möglich in der Konfiguration von MediaMTX extra Pfade zu definieren. Im Endeffekt sind wir auf diese Konfiguration gekommen:
# ...
paths:
rtc:
stream:
# ...
Die paths
Sektion sollte bereits vorhanden sein. Die weiteren Aspekte dieses Blocks werden im folgenden erklärt.
rtc
: Dies ist ein selbst gewählter Name für unseren Ziel Pfad. Dieser musste nur definiert werden und benötigt keine weitere konfiguration.
stream
: Dies ist der selbst gewählte Name für den Pfad auf den wir in OBS streamen. Da wir diesen modifizieren wollen sind hier weitere Konfigurationen gelistet.
runOnReady
: Der folgende Command wird ausgeführt sobald dieser Pfad aktiv wird.
runOnReadyRestart
: Boolscher Wert der bestimmt ob der runOnReady-Command nach Abschluss neugestartet werden soll.
Nun schauen wir uns den runOnReady-Command genauer an:
ffmpeg -i rtsp://localhost:$RTSP_PORT/stream -vcodec copy -c:a libopus -b:a 64k -async 50 -f rtsp rtsp://localhost:$RTSP_PORT/rtc
FFmpeg ist eine vollständige Lösung um Audio und Video aufzunehmen, umzuwandeln oder zu streamen. Mit Hilfe der verschieden Flags und Optionen. Die hier benutzten werden erklärt:
-i
: Definiert den Input-Dateiname. In diesem Fall ist das die RTSP Adresse zu dem Pfad ‚stream‘, auf welchen wir von OBS aus streamen
-vcodec
: Definiert den zu verwendenden Videocodec. In diesem Fall geben wir Copy an, da wir diesen nicht ändern wollen.
-c:a
: Definiert den zu verwendenden Audiocodec. Dies ist die ausschlaggebene Option. Hier definieren wir libopus, welcher es uns erlaubt
-b:a
: Definiert die Audiobitrate. Hier stellen wir diese auf 64 kbits/s um eine gute Qualität zu erhalten.
-async
: Definiert die Anzahl der Samples pro Sekunde. Dies ist notwendig um das Audio mit dem Video zu syncen. Lässt man diese Option weg so kann es zu lückenhaften Ton kommen. Für den exakten Wert muss man hier ein wenig experimentieren.
-f
: Definiert das Zielformat. Nachdem MediaMTX den Stream ohnehin in alle aktivierten Protokolle umwandelt können wir hier einfach das selbe Protokoll wie den input verwenden.
rtsp://localhost:$RTSP_PORT/rtc
: Das letzte Argument definiert den Output. Hier geben wir wieder die interne Adresse an, diesmal aber mit dem uns vorhin definierten Pfad „rtc“.
Ab sofort ist es möglich über die WebRTC Adressen Bild und Ton in guter Qualität zu empfangen.