Video-Livestream mit Raspberry Pi und mediaMTX zu Janus WebRTC Server
Um das Arbeiten mit Photogrammetrie zu erleichtern, haben wir einen Drehteller (-tisch) konzipiert und gebaut, der von einem Schrittmotor angetrieben wird. Der Tisch steht in einer Ecke unseres Büros.
Ihr könnt den Tisch drehen und die Geschwindigkeit anpassen. Falls wir in der Nähe sind, setzten wir uns auch gerne mal drauf. 😵💫
Die Steuerung des Tisches erfolgt über Websockets. In diesem Beitrag wollen wir aber auf die Realisierung des Livestreams eingehen.
Im ersten Schritt erklären wir, wie man einen Raspberry Pi mit Kamera-Modul zum Streamen bringt. Im nächsten Schritt leiten wir den Videostream an einen WebRTC-Server (Janus Gateway) weiter, damit das Video von vielen Clients gleichzeitig gesehen werden kann.
Raspberry Pi Videostream
Wir verwenden für diese Anleitung einen Raspi 4 mit angeschlossenem Kameramodul und Raspberry Pi OS Debian version: 12 (Bookworm). Bei unserem Beispiel ist Raspi OS Lite Bookworm 64-bit im Einsatz.
Da GStreamer(rpicamsrc / raspivid) die neue libcamera nicht mehr unterstützt, kommt der sehr effiziente MediaMTX Server zum Einsatz.
Zuerst machen wir ein Update und installieren die benötigten Pakete:
sudo apt update && apt full-upgrade
sudo apt install libfreetype6 libcamera0
MediaMTX steht als 32- und 64-Bit Version zur Verfügung. Welches OS wir benutzen, kann mit:
uname -m
herausgefunden werden. armv7l = 32Bit, aarch64 = 64Bit.
Nun laden wir die entsprechende Version (Linux armv7 / arm64v8) von der Release-Seite des Projekts herunter und entpacken das Archiv nach /opt/mediamtx.
Bevor MediaMTX gestartet werden kann, müssen wir die Binary-Datei ausführbar machen:
sudo chmod +x /opt/mediamtx/mediamtx
In /opt/mediamtx/mediamtx.yml (ganz unten) ergänzen wir:
paths:
# example:
# my_camera:
# source: rtsp://my_camera
# Settings under path "all_others" are applied to all paths that
# do not match another entry.
all_others:
mit:
paths:
cam:
source: rpiCamera
all_others:
Achtung: in YAML-Dateien muss auf die Einrückung am Zeilenanfang geachtet werden!
In mediamtx.yml kann die Auflösung, Bitrate, Helligkeit, etc. der Raspi-Cam eingestellt werden. "cam:" definiert den jeweiligen Pfad, an dem unser Stream aufrufbar ist.
Jetzt ist es an der Zeit MediaMTX zu starten:
cd /opt/mediamtx
./mediamtx
Um den Videostream zu testen, öffnen wir auf einem anderen Rechner unseres Netzwerks den VLC-Mediaplayer. Medien -> Netzwerkstream öffnen. Als Netzwerkadresse geben wir: rtsp://{Raspi IP-Adresse}:8554/cam ein -> Wiedergabe. Das Live-Video unserer Raspi-Cam sollte nun zu sehen sein. 🤩
MediaMTX verfügt über eine eigene WebRTC-Implementierung. Das Öffnen von http://{Raspi IP-Adresse}:8889/cam in einem Browser sollte das Video ebenfalls wiedergeben. Auch HLS-Streams werden unter: http://{Raspi IP-Adresse}:8888/cam ausgeliefert. Nicht benötigte Protokolle, können in mediamtx.yml abgeschaltet werden.
Um MediaMTX nach einem Neustart des Raspis automatisch auszuführen, richten wir einen systemd-Service ein. Zuerst beenden wir MediaMTX mit Strg + C, dann legen wir die Datei /etc/systemd/system/mediamtx.service mit folgendem Inhalt an:
[Unit]
Wants=network.target
[Service]
ExecStart=/opt/mediamtx/mediamtx /opt/mediamtx/mediamtx.yml
[Install]
WantedBy=multi-user.target
Nun den Service aktivieren und starten:
sudo systemctl daemon-reload
sudo systemctl enable mediamtx
sudo systemctl start mediamtx
Nach Änderungen in der Konfiguration können wir MediaMTX jederzeit neu starten:
sudo systemctl restart mediamtx
Um den Videostream aus dem Internet zu erreichen, könnte nun DynDNS und ein Port-Forwarding im Router eingerichtet werden. Damit unser Stream von vielen Clients gleichzeitig gesehen werden kann, wollen wir im nächsten Abschnitt den Stream an Janus WebRTC Server weiterleiten.
Janus WebRTC Server
Janus WebRTC Server (oder Janus Gateway), ist ein Medien-Server von Meetecho. Mit seiner API ermöglicht er die Umsetzung umfangreicher WebRTC-Projekte wie Videokonferenzen, Streaming und Aufzeichnungen.
Wir wollen hier die absolute Minimalkonfiguration (nur Streaming-Plugin und Websocket-API) für die Verteilung unseres Raspi-Videostreams vorstellen. Voraussetzung ist ein Webserver mit SSL-Zertifikat (https), der über eine öffentliche IP-Adresse erreichbar ist. Für unser Beispiel verwenden wir Debian 12 mit dem Apache Webserver.
Zuerst installieren wir die benötigten Abhängigkeiten:
apt install libwebsockets-dev libjansson-dev libssl-dev libglib2.0-dev libsrtp2-dev libconfig-dev libnice-dev pkg-config git cmake libtool automake
Dann holen wir die Quellen und erzeugen das Konfigurationsscript.
git clone https://github.com/meetecho/janus-gateway.git
cd janus-gateway
sh autogen.sh
Minimalkonfiguration, nur Janus mit Streaming-Plugin und Websocket-API - ./configure --help listet alle Optionen - Doku:
./configure --prefix=/opt/janus --disable-all-plugins --disable-all-transports --disable-all-handlers --disable-all-loggers --enable-plugin-streaming --enable-websockets
Kompilieren:
make
make install
In /opt/janus/etc/janus befinden sich jetzt die Beispiel-Konfigurationsdateien. Wir entfernen jeweils '.sample' aus den Dateinamen. Hier die wichtigsten Einstellungen, manche Zeilen sind auszukommentieren (# entfernen):
janus.jcfg - generelle Konfiguration:
general: {
log_to_file = "/opt/janus/janus.log"
interface = "127.0.0.1"
}
nat: {
ignore_mdns = true
}
janus.transport.websockets.jcfg - Websocket-API (Server) - soll lokal an Port 8188 lauschen:
general: {
ws = true
ws_port = 8188
ws_ip = "127.0.0.1"
}
janus.plugin.streaming.jcfg - Streaming-Plugin Konfiguration - Wir können nach einem Backup den gesamten Inhalt der Datei mit Folgendem ersetzen:
h264Stream: {
type = "rtp"
id = 1
description = "Unser Raspi-Stream"
audio = false
data = false
video = true
videobufferkf = true
videoport = 8005
videopt = 96
videortpmap = "H264/90000"
videofmtp = "profile-level-id=42c01f;packetization-mode=1"
}
Diese Konfiguration ist unter Verwendung verschiedener Namen, id's und Ports um zusätzliche Streams erweiterbar. Auch gleichzeitige 'Multistreams' lassen sich realisieren.
Um die -bald- auf Port 8188 lauschende, interne Websocket-API erreichbar zu machen, aktivieren wir diese Apache Proxy-Module:
a2enmod proxy
a2enmod proxy_http
a2enmod proxy_wstunnel
Beispiel der Apache-Konfiguration:
<VirtualHost *:443>
ServerName domain.org
DocumentRoot /var/www/domain
ProxyPass /janus-ws ws://127.0.0.1:8188 retry=0
ProxyPassReverse /janus-ws ws://127.0.0.1:8188
SSLCertificateFile /pfad/fullchain.pem
SSLCertificateKeyFile /pfad/privkey.pem
</VirtualHost>
Websocket-Anfragen werden so von extern über https an die Janus-Websocket-Api durchgereicht und beantwortet.
Nach all der Konfiguration wird es Zeit, Apache neu zu starten:
systemctl restart apache2
Zurück zu unserem Raspi
Nun wollen wir den VideoStream von unserem Raspi an Janus senden.
Dazu installieren wir ffmpeg - DAS schweizer Taschenmesser rund um Video.
sudo apt install ffmpeg
In /opt/mediamtx/mediamtx.yml ergänzen wir die Zeilen 'runOnReady' und 'runOnReadyRestart'. '{Janus IP}' wird mit der IP-Adresse des Janus-Servers ersetzt. Das Port 8005 wurde in janus.plugin.streaming.jcfg unter 'videoport' festgelegt (siehe oben).
paths:
cam:
source: rpiCamera
runOnReady: ffmpeg -i rtsp://localhost:8554/cam -c copy -f rtp rtp://{Janus IP}:8005
runOnReadyRestart: yes
all_others:
ffmpeg nimmt den h264-Stream entgegen und leitet ihn an Janus weiter. Da keine Transkodierung stattfindet, bleibt die CPU-Last auf unserem PI erfreulich gering.
Da wir nur das rtsp-Protokoll nutzen, kann hls, webrtc, rtmp abgeschaltet werden.
Nach den Änderungen starten wir mediaMTX neu:
sudo systemctl restart mediamtx
Zurück zu Janus
Wir starten Janus:
cd /opt/janus/bin
./janus
In der Shell sollten wir nun '[h264Stream] New video stream!' lesen. Das ist unser Raspi-Stream! 🤗 Etwaige Warnungen können wir ignorieren.
Jetzt richten wir Janus als Service ein. Strg + C -> /etc/systemd/system/janus.service:
[Unit]
Description=Janus WebRTC Server
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/opt/janus/bin/janus -o
Restart=on-abnormal
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable janus
sudo systemctl start janus
Einbindung des Streams in eine Webseite:
Für die Einbindung sind zwei Javascript-Dateien erforderlich:
- adapter.js - sorgt für die Kompatibilität verschiedener WebRTC-Implementierungen in Browsern (shim). Link
- janus.js - stellt Funktionen bereit, um mit der Janus-API zu kommunizieren Doku. Wie die Datei erzeugt und als ES-Modul eingebunden werden kann, ist hier beschrieben. Der Einfachheit halber, haben wir das Script aus dem Github-Repository heruntergeladen.
Hier eine minimale Demo. Den kompletten Quelltext für die Janus Streaming Demo findet ihr hier.
Wir hoffen, die Anleitung war nützlich! Bei Anregungen und Fragen schreibt uns: office@fatvalley.at
Happy streaming!