Update Oktober 2025: FullHD-Livestreaming mit Audio vom Raspberry Pi Zero 2 W: Eine Deep Dive Anleitung

🚀 RPiCam-Apps v1.9.1: Der Durchbruch für stabiles Raspberry Pi Livestreaming Die Suche nach einer verlässlichen Lösung für das Livestreaming von einem Raspberry Pi zu einem zentralen Server war lange von Hürden geprägt. Doch mit der

🚀 RPiCam-Apps v1.9.1: Der Durchbruch für stabiles Raspberry Pi Livestreaming

Die Suche nach einer verlässlichen Lösung für das Livestreaming von einem Raspberry Pi zu einem zentralen Server war lange von Hürden geprägt. Doch mit der rpicam-apps Version v1.9.1 erleben wir endlich den entscheidenden Fortschritt!

Diese Version bringt nach intensiven Fehlerbehebungen die notwendige Stabilität und funktioniert nun fehlerfrei sowohl unter Raspberry Pi OS Bookworm (Debian 12) als auch unter dem neueren Raspi Trixie (Debian 13). Insbesondere die kritischen Speicherzugriffsfehler unter Trixie sind mit diesem Update endlich behoben.

Falls die neue Version noch nicht über den Paketmanager apt verfügbar ist, besteht kein Grund zur Sorge: Die rpicam-apps lassen sich relativ simpel per Git klonen und selbst kompilieren.


💡 Die Herausforderung: FullHD-Streaming mit 30 FPS und Audio vom Raspberry Pi Zero 2 W

Unser Ziel ist klar: Wir wollen Livestreams in FullHD (1080p) und 30 FPS mit Audio von einem kompakten Raspberry Pi Zero 2 W auf einen zentralen Server senden.

Um dieses anspruchsvolle Vorhaben auf dem kleinen Rechner zu realisieren, muss eine Vielzahl von Faktoren beachtet und optimiert werden:

  • Hardware-Ressourcen: CPU-Leistung, RAM und die Geschwindigkeit der SD-Karte.
  • Kritische Dienste: Laufende Prozesse wie Fenstermanager und grafische Oberflächen.
  • Konnektivität: Stabile Netzwerkgeschwindigkeit über WLAN.
  • Media-Komponenten: Optimale Kamera-Einstellungen sowie die Konfiguration von Mikrofon und Audio-Managern wie ALSA oder PulseAudio.

Die richtige Zusammenstellung all dieser Komponenten zu finden, ist eine komplexe Aufgabe. Es ist nicht leicht, alle Komponenten in Einklang zu bringen und dabei die möglichen Flaschenhälse im Zusammenspiel des Stream-Aufbaus zu identifizieren.

Nach intensiven Tests und detaillierten Analysen haben wir die Schlüssel zu einem stabilen Stream gefunden. Hier präsentieren wir unsere Überlegungen und die daraus resultierenden Ergebnisse in aller Kürze:

➡️ Wichtige Vorbemerkung zur Software: Wir setzen auf die rpicam-apps in Version v1.9.1 oder neuer. Diese Version behebt kritische Speicherzugriffsfehler unter Raspberry Pi OS Bookworm (Debian 12) und Trixie (Debian 13) und ist somit die Basis für ein stabiles System. Falls noch nicht per apt verfügbar, kann die Kompilierung über Git erfolgen.


1. 🛑 Swap oder Nicht-Swap? Der Speicher-Flaschenhals

Unsere umfangreichen Tests rund um die Speicherverwaltung – inklusive Experimenten mit verschiedenen Swap-Größen, der swappiness und komprimiertem ZRAM-Swap – führten uns zu einem klaren und kritischen Ergebnis:

  • Das Problem: Wird im System geswappt, entzieht dies anderen Prozessen systemweit Rechen- und Schreibleistung. Unabhängig davon, ob der Swap komprimiert ist oder nicht, stellt das Auslagern eine enorme Fehlerquelle dar, die die Stabilität des Livestreams massiv gefährden kann.
  • Das Fazit: Swapping muss minimiert oder idealerweise komplett eliminiert werden.

🖥️ Optimale Konfiguration für stabile Streams

Um dies zu erreichen, streben wir zwei Szenarien an:

  1. System ohne GUI (Best Practice): Wenn Sie ohne eine grafische Oberfläche (Fenstermanager) auskommen, ist dies der größte Vorteil. Sie können in diesem Fall meist komplett auf Swap-Speicher verzichten. Dadurch eliminieren Sie speicher- und rechenintensive Prozesse und stellen die maximale Leistung für den Stream-Aufbau sicher.
  2. System mit GUI (Der Kompromiss): Sollte dennoch eine grafische Oberfläche benötigt werden (z. B. für eine Anzeige von Messwerten wie Temperatur, Datum und Uhrzeit in einem Pygame-Fenster), ist Folgendes zu beachten:
    • Stellen Sie sicher, dass der verbleibende freie RAM ausreichend groß ist. Testen Sie dies am besten während der Laufzeit mit Analyse-Tools wie btop oder bpytop.
    • Setzen Sie die swappiness auf einen Wert zwischen 1 und 10. Ein niedriger Wert sorgt dafür, dass das System nur im äußersten Notfall mit der Auslagerung beginnt und diese nicht permanent die Systemressourcen blockiert.

Ziel ist immer: Mehr RAM-Nutzung, weniger Festplattenzugriff – der Schlüssel zur Eliminierung von Verzögerungen und Stream-Abbrüchen.


2. ⚡ CPU-Taktung und Governance: Sparen, wo es geht

Die gute Nachricht zuerst: Unsere Tests ergaben, dass der eigentliche FullHD-Stream mit Video und Audio nur 15% bis 25% der Rechenleistung des Raspberry Pi Zero 2 W beansprucht. Das ist deutlich weniger als oft angenommen.

  • Energie sparen: Da der Grundbedarf gering ist, können wir die CPU-Taktfrequenz reduzieren. Im Grunde kommen wir mit 600 MHz und einer powersave oder ondemand Governor-Einstellung aus. Dies spart Strom und reduziert den Bedarf an aktiver Kühlung.
  • Wärmeentwicklung und Kühlung: Trotz der geringen CPU-Auslastung ist passive Kühlung dennoch dringend empfohlen. Streaming beansprucht auch die GPU (für das H.264-Encoding) und das Netzwerk, was zu einer generellen Temperaturerhöhung führt. Mit passiven Kühlkörpern pendelt sich die Temperatur meist bei etwa 60 Grad Celsius ein.
  • Fehlerbehebung bei Instabilität: Sollten Sie dennoch Stream-Abbrüche oder kritische Alsa Buffer Xruns (Audiofehler) feststellen, kann die Ursache manchmal doch in der Rechenleistung liegen. Hier empfiehlt sich, testweise auf den performance Governor umzustellen. Dies kann eventuelle Engpässe beseitigen.

Ein simples Shell-Skript (cpu-settings.sh) zum einfachen Auslesen und Setzen des Governors finden Sie im Anhang dieses Beitrags.


3. Netzwerk: Der Kritische Flaschenhals

Das WLAN ist die häufigste Ursache für Stream-Abbrüche und Alsa Buffer Xrun Fehler, und gleichzeitig die große Unbekannte mit oft erratischem Verhalten.

Obwohl der Zero 2 W Linkqualitäten von 60-80% und über 30 Mbit Bruttogeschwindigkeit anzeigte (was für einen 4 Mbit Stream theoretisch reichen sollte), war die Verbindung instabil.

  • Das entscheidende Finding: Stabile Streams über Stunden und Tage wurden nur mit einer Linkqualität zwischen 90% und 100% und stabilen 72 Mbit in Sende- (TX) und Empfangsrichtung (RX) erreicht.
  • Analyse-Tool: Nutzen Sie wavemon (apt install wavemon) auf dem Raspberry Pi, um die exakte Netzwerklage einzusehen und die Stabilität abzuschätzen.
  • Lösung: Gehen Sie diesen Aufwand ein! Eine Umpositionierung von Pi oder Router oder der Einsatz eines Repeaters ist nötig, um diese Werte zu erreichen. Die Netzwerkleistung ist die entscheidende Größe für Langzeitstabilität.

4. 📸 Kamera- und Mikrofon-Settings: Qualität und Effizienz

Mit den richtigen Einstellungen liefert der kleine Raspberry Pi Zero 2 W FullHD-Streams von beeindruckender Qualität, die oft besser sind als die Ergebnisse kommerzieller Überwachungskameras – vorausgesetzt, Sie achten auf ausreichend Licht und ein gutes Mikrofon.

Video: GPU-Encoding und Bildeinstellungen

Um die knappen Ressourcen optimal zu nutzen, setzen wir auf Hardware-Beschleunigung:

  • GPU-Nutzung: Wir nutzen die GPU des Raspberry Pi für die H.264-Erzeugung. Dies entlastet die CPU massiv.
  • Sensor-Optimierung: Für den kleinen IMX-Sensor stellen wir Belichtung (exposure), White Balance (awb), Sättigung (saturation), Kontrast (contrast) und Schärfe (sharpness) auf brauchbare Werte ein.
  • HDR-Option: Bei Bedarf können Sie mit wenig Aufwand HDR-Streams (High Dynamic Range) produzieren. HDR hellt dunkle Bildbereiche auf und dunkelt helle ab. Für authentischere Streams belassen wir es jedoch meist bei der Deaktivierung von HDR.

Audio: ALSA als beste Wahl

Für die Audio-Einstellungen empfehlen wir dringend, auf die ALSA-Struktur zu setzen.

  • Prozess-Minimierung: Audio-Manager wie Pipewire und PulseAudio legen zusätzliche laufende Prozesse auf das System und sind im Hintergrund trotzdem auf ALSA angewiesen. Nach dem Motto “Je weniger, desto besser” verzichten wir auf diese zusätzlichen Ebenen.
  • Root-Kompatibilität: Wichtig für den Betrieb als Systemdienst: PulseAudio lässt sich nicht als Root-User ausführen. Da der System-Stream oft unter Root-Rechten läuft, ist ALSA hier die praktikabelste Lösung.

Mikrofon-Konfiguration

Lautstärkeeinstellung: Die Mikrofonlautstärke stellen Sie über das Tool alsamixer ein. Achten Sie darauf, die gewünschte Lautstärke zu erreichen, ohne dabei zu übersteuern. Fast alle günstigen USB-Mikrofone haben sich in unseren Tests bewährt.

Geräte-Auswahl: Mit dem Befehl arecord -l listen Sie die verfügbaren Audio-Karten und -Devices auf.

Stream-Einbindung: Das korrekte Device setzen Sie dann im Stream-Kommando mit der Option --audio-device hw:0,0 (wobei 0,0 durch Ihre ermittelten Werte ersetzt werden muss).


5. Das Perfekte Stream-Kommando und seine Parameter

Dieses Kommando nutzt rpicam-vid und sendet einen H.264 Video- und AAC Audio-Stream im FLV-Format an einen Nginx-RTMP Server.

Wichtig: Ersetzen Sie 192.168.x.y durch die tatsächliche IP Ihres RTMP-Servers.

Bash

#!/bin/bash
nice -n -19 rpicam-vid -t 0 --width 1920 --height 1080 \
--nopreview 1 --low-latency 1 --hdr off --flush 1 \
--buffer-count 6 --exposure long --sharpness 1.1 --contrast 1.2 \
--brightness 0.0 --saturation 1.0 --ev +1.0 --awb auto \
--profile high --level 4.2 --codec libav --libav-audio 1 \
--audio-source alsa --audio-device hw:0,0 --audio-channels 1 \
--audio-codec aac \
--audio-samplerate 48000 --audio-bitrate 128000 --libav-format flv \
-n --framerate 30 -b 4500000 --autofocus-mode manual --lens-position 0.8 \
--denoise auto --autofocus-window 0.25,0.25,0.5,0.5 --inline 1 \
-o "rtmp://192.168.x.y/zero/test"

📋 Detaillierte Erklärung der Optionen

OptionWertErklärung
nice -n -19Priorisierung des Stream-Prozesses. -19 ist die höchste Priorität und sichert die Rechenleistung.
-t 0Unendliche Aufnahmezeit (0 Millisekunden), d.h., der Stream läuft, bis er gestoppt wird.
--width, --height1920, 1080Setzt die FullHD-Auflösung (1080p).
--nopreview 1Deaktiviert die lokale Bildvorschau, spart Ressourcen.
--low-latency 1Wichtig für geringe Verzögerungen im Stream.
--hdr offHigh Dynamic Range (HDR) ist deaktiviert, um einen authentischeren Look zu gewährleisten.
--flush 1Erhöht die Reaktionsfähigkeit und reduziert die Pufferung.
--buffer-count 6Anzahl der Puffer, die für die Video-Frames verwendet werden. Optimiert für den Stream.
--exposure longBelichtungszeit auf ‘lang’ gesetzt, oft gut für Innenräume/wenig Licht.
--sharpness 1.1, --contrast 1.2Anpassung der Bildeigenschaften (hier leicht erhöht).
--codec libavVerwendet die Libav-Bibliothek für Encoding und Streaming.
--libav-audio 1Aktiviert die Audio-Verarbeitung durch Libav.
--audio-source alsaDefiniert ALSA als Audio-Quelle, um Pulse/Pipewire zu umgehen.
--audio-device hw:0,0Das spezifische Audio-Gerät (Karte 0, Gerät 0), ermittelt durch arecord -l.
--audio-codec aacAudio-Codec AAC (Advanced Audio Coding), Standard für Streaming.
--audio-samplerate 48000Samplerate für die Audioaufnahme (48 kHz).
--audio-bitrate 128000Audio-Bitrate von 128 kbps.
--libav-format flvContainerformat FLV (Flash Video), Standard für RTMP-Streaming.
-nDeaktiviert das Speichern in einer lokalen Datei.
--framerate 30Die gewünschte Bildrate pro Sekunde.
-b 4500000Video-Bitrate von 4.5 Mbit/s (4500000 Bits pro Sekunde).
--autofocus-mode manualAutofokus ist manuell eingestellt.
--lens-position 0.8Manuelle Einstellung der Fokusposition für eine feste Schärfe.
--inline 1Fügt SPS/PPS-Header in den Stream ein (wichtig für die Dekodierung).
-o "rtmp://..."Die Ausgabe-URL an den Nginx-RTMP Server.

6. Automatischer Start: Stream als Systemdienst

Für den automatischen Start des Streams beim Booten erstellen wir einen Systemdienst (Service-Unit).

1. Dienstdatei erstellen:

    nano /lib/systemd/system/stream.service

    2. Inhalt stream.service:

    [Unit] Description=ZeroCam stream service 
    After=network.target 
    Wants=network-online.target 
    StartLimitIntervalSec=3 
    StartLimitBurst=5 
    
    [Service] 
    Type=simple ExecStartPre=/bin/sleep 1 
    Nice=-12 
    Restart=always 
    RestartSec=5 
    User=root 
    WorkingDirectory=/home/axel 
    ExecStart=/usr/bin/streamfull # Das streamfull.sh Skript wurde hier ohne .sh nach /usr/bin/ kopiert. 
    [Install] WantedBy=multi-user.target
    

    3. Dienst aktivieren und starten:

    systemctl enable stream.service 
    systemctl start stream.service 

    Der Stream sollte nun automatisch bei jedem Systemstart laufen.


    7. Überwachung und Fehlerbehebung

    Zur Überwachung der Stabilität dient das System-Journal, insbesondere, wenn der Stream als Dienst läuft.

    🔍 Journal-Überwachung

    Bash

    journalctl -u stream.service -f

    🟢 Stabile Stream-Ausgabe

    Ein stabiler Stream zeigt erfolgreiche Initialisierungen und eine fortlaufende Audio-/Videokette:

    root@zero:/home/axel# journalctl -u stream.service -f
    Okt 18 09:00:17 zero.jerabek.fi streamfull[1440]: [h264_v4l2m2m @ 0x55c1978350] <<< v4l2_encode_init: fmt=179/0
    Okt 18 09:00:17 zero.jerabek.fi streamfull[1440]: [h264_v4l2m2m @ 0x55c1978350] Using device /dev/video11
    Okt 18 09:00:17 zero.jerabek.fi streamfull[1440]: [h264_v4l2m2m @ 0x55c1978350] driver 'bcm2835-codec' on card 'bcm2835-codec-encode' in mplane mode
    Okt 18 09:00:17 zero.jerabek.fi streamfull[1440]: [h264_v4l2m2m @ 0x55c1978350] requesting formats: output=YU12 capture=H264
    Okt 18 09:00:17 zero.jerabek.fi streamfull[1440]: Input #0, alsa, from 'hw:0,0':
    Okt 18 09:00:17 zero.jerabek.fi streamfull[1440]: Duration: N/A, start: 1760770817.363771, bitrate: 768 kb/s
    Okt 18 09:00:17 zero.jerabek.fi streamfull[1440]: Stream #0:0: Audio: pcm_s16le, 48000 Hz, 1 channels, s16, 768 kb/s
    Okt 18 09:00:17 zero.jerabek.fi streamfull[1440]: Output #0, flv, to 'rtmp://192.168.178.25/zero/test':
    Okt 18 09:00:17 zero.jerabek.fi streamfull[1440]: Stream #0:0: Video: h264 (High), drm_prime(tv, bt709), 1920x1080, q=2-31, 4500 kb/s, 30 fps, 30 tbr, 1000k tbn
    Okt 18 09:00:17 zero.jerabek.fi streamfull[1440]: Stream #0:1: Audio: aac (LC), 48000 Hz, mono, fltp, 128 kb/s

    🔴 Tracking-Fehler (Instabiler Stream)

    Pkt tracking failure deutet auf eine Instabilität im Stream hin, der neu eingestellt und neu gestartet werden muss:

    Oct 18 09:10:55 zero3 streamfull[2322]: [h264_v4l2m2m @ 0x55a1a21480] Pkt tracking failure: pts=101818, track[58]=101946

    🔊 Audio Buffer Xruns (Typischer Fehler)

    Audio Buffer Xruns gehören zu den häufigsten Fehlern in unseren Stream-Protokollen. Sie sind ein deutliches Anzeichen dafür, dass es zu Paketierfehlern zwischen Video und Audio kommt. Im Kern signalisieren sie eine Überlastung des Systems oder des Übertragungswegs.

    Die Echte Ursache: Meistens das WLAN

    Obwohl Xruns auf überlastete Hardware hindeuten können, war in unserem Fall die Ursache sehr oft “lediglich” die instabile WLAN-Verbindung zwischen dem Raspberry Pi und dem Nginx-RTMP Server (bzw. dem Router/der Fritzbox).

    root@zero3:/home/axel# journalctl -u stream.service -f
    Oct 18 15:39:50 zero3 streamfull[7439]: SRGGB10_CSI2P,1640x1232/41.8515 - Score: 1000
    Oct 18 15:39:50 zero3 streamfull[7439]: SRGGB10_CSI2P,1920x1080/47.5737 - Score: 1541.48
    Oct 18 15:39:50 zero3 streamfull[7439]: SRGGB10_CSI2P,3280x2464/21.1941 - Score: 19329.9
    Oct 18 15:39:50 zero3 streamfull[7439]: SRGGB8,640x480/103.327 - Score: 5504.81
    Oct 18 15:39:50 zero3 streamfull[7439]: SRGGB8,1640x1232/41.8515 - Score: 2000
    Oct 18 15:39:50 zero3 streamfull[7439]: SRGGB8,1920x1080/47.5737 - Score: 2541.48
    Oct 18 15:39:50 zero3 streamfull[7439]: SRGGB8,3280x2464/21.1941 - Score: 20329.9
    Oct 18 15:39:50 zero3 streamfull[7439]: Stream configuration adjusted
    Oct 18 15:39:50 zero3 streamfull[7439]: [7:41:07.117053737] [7439] INFO Camera camera.cpp:1215 configuring streams: (0) 1640x1232-YUV420/Rec709 (1) 1640x1232-SRGGB10_CSI2P/RAW
    Oct 18 15:39:50 zero3 streamfull[7439]: [7:41:07.117807228] [7442] INFO RPI vc4.cpp:615 Sensor: /base/soc/i2c0mux/i2c@1/imx219@10 - Selected sensor format: 1640x1232-SRGGB10_1X10/RAW - Selected unicam format: 1640x1232-pRAA/RAW
    Oct 18 15:39:57 zero3 streamfull[7439]: [h264_v4l2m2m @ 0x55682da480] <<< v4l2_encode_init: fmt=179/0
    Oct 18 15:39:57 zero3 streamfull[7439]: [h264_v4l2m2m @ 0x55682da480] Using device /dev/video11
    Oct 18 15:39:57 zero3 streamfull[7439]: [h264_v4l2m2m @ 0x55682da480] driver 'bcm2835-codec' on card 'bcm2835-codec-encode' in mplane mode
    Oct 18 15:39:57 zero3 streamfull[7439]: [h264_v4l2m2m @ 0x55682da480] requesting formats: output=YU12 capture=H264
    Oct 18 15:39:57 zero3 streamfull[7439]: Input #0, alsa, from 'hw:0,0':
    Oct 18 15:39:57 zero3 streamfull[7439]: Duration: N/A, start: 1760794797.840298, bitrate: 768 kb/s
    Oct 18 15:39:57 zero3 streamfull[7439]: Stream #0:0: Audio: pcm_s16le, 48000 Hz, 1 channels, s16, 768 kb/s
    Oct 18 15:39:57 zero3 streamfull[7439]: Output #0, flv, to 'rtmp://192.168.178.25/zero3/test':
    Oct 18 15:39:57 zero3 streamfull[7439]: Stream #0:0: Video: h264 (Main), drm_prime(tv, bt709), 1640x1232, q=2-31, 3500 kb/s, 30 fps, 30 tbr, 1000k tbn
    Oct 18 15:39:57 zero3 streamfull[7439]: Stream #0:1: Audio: aac (LC), 48000 Hz, mono, fltp, 64 kb/s
    Oct 18 15:40:02 zero3 streamfull[7439]: [alsa @ 0x55682e1e30] ALSA buffer xrun.
    Oct 18 15:40:04 zero3 streamfull[7439]: [alsa @ 0x55682e1e30] ALSA buffer xrun.
    Oct 18 15:40:08 zero3 streamfull[7439]: [alsa @ 0x55682e1e30] ALSA buffer xrun.
    Oct 18 15:40:13 zero3 streamfull[7439]: [alsa @ 0x55682e1e30] ALSA buffer xrun.
    Oct 18 15:40:18 zero3 streamfull[7439]: [alsa @ 0x55682e1e30] ALSA buffer xrun.
    Oct 18 15:40:23 zero3 streamfull[7439]: [alsa @ 0x55682e1e30] ALSA buffer xrun.
    Oct 18 15:40:27 zero3 streamfull[7439]: [alsa @ 0x55682e1e30] ALSA buffer xrun.
    Oct 18 15:40:29 zero3 streamfull[7439]: [alsa @ 0x55682e1e30] ALSA buffer xrun.

    🛠️ Lösung und Strategie

    1. Bitrate reduzieren: Sollte es Ihnen trotz aller Bemühungen nicht gelingen, eine stabile 100-Prozent-Verbindung zum Router herzustellen, versuchen Sie, die Datenraten von Video und/oder Audio etwas herunterzuschrauben. Dadurch verringert sich die Datenlast pro Sekunde.
    2. Netzwerkproblem fundamental lösen: Treten die Xruns danach immer noch auf, ist eine reine Reduzierung der Bitrate nicht ausreichend. In diesem Fall muss das WLAN/WiFi-Problem grundsätzlich angegangen werden: Optimale Umpositionierung des Raspberry Pi und/oder des Routers oder der Einsatz eines WLAN-Repeaters sind die einzig dauerhaften Lösungen.

    Xruns sind ein kritischer Indikator. Ignorieren Sie sie nicht, denn sie bedeuten, dass Ihr Stream nicht robust genug für den Langzeitbetrieb ist.

    8. 🛡️ Automatisierte Überwachung: Den Stream am Laufen halten

    Selbst bei optimaler Konfiguration können externe Faktoren (wie kurzzeitige WLAN-Schwankungen) zu ALSA Buffer Xruns führen. Bevor diese Fehler den Stream komplett unbrauchbar machen und er nicht mehr vom Nginx-RTMP-Server abgerufen werden kann, sollte proaktiv gehandelt werden.

    Wir richten einen dedizierten Systemd-Überwachungsdienst ein, der das Log des eigentlichen Streams (stream.service) permanent ausliest und bei Erkennung des Schlüsselworts “ALSA buffer xrun” sofort einen Neustart auslöst.

    Schritt 1: Das Überwachungs-Skript erstellen

    Erstellen Sie das Shell-Skript, das das journalctl-Log überwacht und den Neustart durchführt.

    nano /home/pi/scripts/monitor_stream_single.sh

    Inhalt monitor_stream_single.sh:

    #!/bin/bash
    
    SERVICE_NAME="stream.service"
    LOG_FILE="/var/log/buffer_xrun_restart.log"
    
    # Das Skript benötigt Lesezugriff auf das Journal.
    # Es liest das Log des Stream-Dienstes (-u) im Follow-Modus (-f).
    journalctl -u "$SERVICE_NAME" -f | while read -r line; do
        # Prüft, ob die kritische Fehlermeldung auftritt
        if echo "$line" | grep -q "ALSA buffer xrun"; then
            timestamp=$(date '+%Y-%m-%d %H:%M:%S')
            
            # Protokolliert den Neustart in einer separaten Log-Datei
            echo "[$timestamp] Detected buffer xrun. Restarting $SERVICE_NAME" >> "$LOG_FILE"
            
            # Führt den Neustart des Stream-Dienstes aus
            systemctl restart "$SERVICE_NAME"
        fi
    done

    Stellen Sie sicher, dass das Skript ausführbar ist:

    chmod +x /home/pi/scripts/monitor_stream_single.sh

    Schritt 2: Den Systemd-Monitor-Dienst erstellen

    Erstellen Sie die Unit-Datei für den Überwachungsdienst.

    nano /etc/systemd/system/stream-monitor.service

    Inhalt stream-monitor.service:

    [Unit]
    Description=Monitor stream.service for ALSA buffer xrun and restart on error
    After=network.target
    
    [Service]
    ExecStart=/home/pi/scripts/monitor_stream_single.sh
    Restart=always
    RestartSec=5
    StandardOutput=null
    StandardError=journal
    User=root
    
    [Install]
    WantedBy=multi-user.target

    ParameterErklärung:
    ExecStartStartet das erstellte Überwachungs-Skript.
    Restart=alwaysStellt sicher, dass der Monitor selbst immer läuft, auch wenn er abstürzt.
    StandardOutput=nullVerhindert, dass das Skript unnötige Ausgaben ins Journal schreibt.
    User=root
    Wichtig, da das Skript journalctl lesen und systemctl restart ausführen muss.

    Schritt 3: Dienst aktivieren und starten

    Laden Sie die Konfiguration neu, aktivieren und starten Sie den Dienst:

    systemctl daemon-reload
    systemctl enable stream-monitor.service
    systemctl start stream-monitor.service

    Ihr Raspberry Pi Zero 2 W überwacht nun proaktiv seine eigene Stream-Stabilität. Tritt ein ALSA buffer xrun auf, wird der Stream innerhalb weniger Sekunden neu gestartet, was die Verfügbarkeit drastisch erhöht.

    🏁 Fazit: Die Lektion des Zero 2 W und der Wunsch an die Entwickler

    Die Reise zum stabilen FullHD-Livestream vom Raspberry Pi Zero 2 W war eine Lektion in Geduld und Systemverständnis. Die wichtigste Erkenntnis ist, dass wir es hier mit einem System zu tun haben, das kaum Puffer für Mikrounterbrechungen im Datenfluss toleriert.

    Die größten Frustrationen entstehen dadurch, dass die Fehlerquellen nicht offensichtlich sind. Das beste Beispiel ist die WLAN-Geschwindigkeit: Rechnerisch sollten 30 Mbit/s für einen 4 Mbit Stream mehr als ausreichen. In der Praxis zeigte sich jedoch, dass ohne eine stabile 72 Mbit-Verbindung der Stream unweigerlich kippt – ein rechnerischer Trugschluss, der zu stundenlanger Fehlersuche an der falschen Stelle führen kann (z. B. CPU oder Swap).

    Anfangs machten alle latenten Fehlerquellen zusammen den Stream instabil. Nur durch die konsequente Optimierung jedes einzelnen Glieds der Kette – von der Eliminierung des Swaps über die korrekte Governor-Einstellung bis hin zur kompromisslosen Netzwerkleistung – konnten wir einen robusten 24/7-Betrieb erreichen. Der kleine Pi Zero 2 W erholt sich bei kurzen Aussetzern im WLAN meist nicht mehr; der Stream ist dann unwiderruflich kaputt.

    Abschließend bleibt nur ein Wunsch, der die Streams noch zuverlässiger machen würde:

    Wir wünschen uns vom rpicam-apps Team, dass endlich eine vernünftige Methode zur Synchronisation bezüglich des Video- und Audio-Sync bei der Initialisierung des Streams integriert wird!

    Bis dahin hoffen wir, dass unsere gesammelten Erfahrungen Ihnen helfen, Ihren perfekten Livestream auf dem Raspberry Pi Zero 2 W schnell und stabil einzurichten.


    Anhang: CPU-Governor Shell-Skript (cpu-settings.sh)

    Bash

    #!/bin/bash
    # Pfad zum CPU-Governor-Verzeichnis
    GOVERNOR_PATH="/sys/devices/system/cpu/cpufreq/policy0/scaling_governor"
    
    # Funktion, um den aktuellen Governor anzuzeigen
    show_governor() {
        if [ -f "$GOVERNOR_PATH" ]; then
            current_governor=$(cat "$GOVERNOR_PATH")
            echo "Aktueller CPU-Governor: $current_governor"
        else
            echo "Fehler: Konnte den Pfad zum Governor-Verzeichnis nicht finden."
            exit 1
        fi
    }
    
    # Funktion, um den Governor zu ändern
    set_governor() {
        local new_governor=$1
        echo "Ändere Governor zu '$new_governor'..."
        if [ -f "$GOVERNOR_PATH" ]; then
            echo "$new_governor" | sudo tee "$GOVERNOR_PATH" > /dev/null
            if [ $? -eq 0 ]; then
                echo "Erfolgreich geändert."
            else
                echo "Fehler: Konnte den Governor nicht ändern. Möglicherweise fehlen root-Rechte."
            fi
        else
            echo "Fehler: Konnte den Pfad zum Governor-Verzeichnis nicht finden."
            exit 1
        fi
    }
    
    # Hauptlogik des Skripts
    case "$1" in
        "status")
            show_governor
            ;;
        "ondemand")
            set_governor "ondemand"
            ;;
        "performance")
            set_governor "performance"
            ;;
        "powersave")
            set_governor "powersave"
            ;;
        "schedutil")
            set_governor "schedutil"
            ;;
        *)
            echo "Verwendung: $0 [status|ondemand|performance|powersave|schedutil]"
            echo "   status: Zeigt den aktuellen Governor an."
            echo " ondemand: Stellt den Governor auf 'ondemand'."
            echo "performance: Stellt den Governor auf 'performance'."
            echo "powersave: Stellt den Governor auf 'powersave'."
            echo "schedutil: Stellt den Governor auf 'schedutil'."
            ;;
    esac

    Anhang 2 – Nginx-RTMP Server Beispiel-config: (mit gleichzeitigem HLS Stream)

    user www-data;
    worker_processes auto;
    worker_rlimit_nofile 65535;
    pid /run/nginx.pid;
    include /etc/nginx/modules-enabled/*.conf;
    
    events {
        worker_connections 1024;
        multi_accept on;
        use epoll;
    }
    
    http {
        sendfile on;
        tcp_nopush on;
        types_hash_max_size 2048;
        include /etc/nginx/mime.types;
        default_type application/octet-stream;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
        ssl_prefer_server_ciphers on;
        access_log /var/log/nginx/access.log;
        error_log /var/log/nginx/error.log;
        gzip on;
        gzip_types text/plain application/json application/javascript text/css application/xml text/javascript;
        include /etc/nginx/conf.d/*.conf;
        include /etc/nginx/sites-enabled/*;
    
        server {
            listen 9090;
    
            location / {
                root /var/www/html;
                index index.html;
            }
    
            # HLS Streams für mevo
            location /hlsmevo/ {
                root /var/hls;
                types {
                    application/vnd.apple.mpegurl m3u8;
                    video/mp2t ts;
                }
                add_header Cache-Control no-cache;
            }
    
            # HLS Streams für pi
            location /hlspi/ {
                root /var/hls;
                types {
                    application/vnd.apple.mpegurl m3u8;
                    video/mp2t ts;
                }
                add_header Cache-Control no-cache;
            }
    
            # HLS Streams für zero
            location /hlszero/ {
                root /var/hls;
                types {
                    application/vnd.apple.mpegurl m3u8;
                    video/mp2t ts;
                }
                add_header Cache-Control no-cache;
            }
    
            # HLS Streams für zero2
            location /hlszero2/ {
                root /var/hls;
                types {
                    application/vnd.apple.mpegurl m3u8;
                    video/mp2t ts;
                }
                add_header Cache-Control no-cache;
            }
    
            # HLS Streams für zero3
            location /hlszero3/ {
                root /var/hls;
                types {
                    application/vnd.apple.mpegurl m3u8;
                    video/mp2t ts;
                }
                add_header Cache-Control no-cache;
            }
    
            access_log /var/log/nginx/access.log;
            error_log /var/log/nginx/error.log;
        }
    }
    
    rtmp {
        server {
            listen 1935;
            timeout 30s;
            chunk_size 4096;
            allow publish all;
            allow play all;
            play_restart on;
            idle_streams off;
            drop_idle_publisher 60s;
            max_message 8M;
            max_connections 512;
            respawn on;
    
            application mevo {
                live on;
                record off;
    
                hls on;
                hls_path /var/hls/hlsmevo;
                hls_fragment 8;
                hls_playlist_length 16;
                hls_type live;
                sync 100ms;
                hls_cleanup on;
            }
    
            application pi {
                live on;
                record off;
    
                hls on;
                hls_path /var/hls/hlspi;
                hls_fragment 8;
                hls_playlist_length 16;
                hls_type live;
                sync 100ms;
                hls_cleanup on;
            }
    
            application zero {
                live on;
                record off;
    
                hls on;
                hls_path /var/hls/hlszero;
                hls_fragment 8;
                hls_playlist_length 16;
                hls_type live;
                sync 100ms;
                hls_cleanup on;
    
            }
    
            application zero2 {
                live on;
                record off;
    
                hls on;
                hls_path /var/hls/hlszero2;
                hls_fragment 8;
                hls_playlist_length 16;
                hls_type live;
                sync 100ms;
                hls_cleanup on;
            }
    
            application zero3 {
                live on;
                record off;
    
                hls on;
                hls_path /var/hls/hlszero3;
                hls_fragment 8;
                hls_playlist_length 16;
                hls_type live;
                sync 100ms;
                hls_cleanup on;
            }
        }
    }
    
    

    Leave a Reply

    Your email address will not be published. Required fields are marked *

    wetransco.de
    Privacy Overview

    This website uses cookies so that we can provide you with the best user experience possible. Cookie information is stored in your browser and performs functions such as recognising you when you return to our website and helping our team to understand which sections of the website you find most interesting and useful.