Lokales Heimüberwachungssystem ohne Cloud Anbieter – Raspberry Pi Zero 2W – FullHD-Streaming mit libcamera für Nginx/RTMP Server und Motion(optimierte Version – Jan 2025)

FullHD Livestream auf 64bit Raspberry Pi Zero 2W Bookworm Der Raspberry Pi Zero 2W ist eine kompakte, leistungsstarke Lösung für viele IoT- und Streaming-Projekte. In diesem Beitrag zeigen wir, wie man mit libcamera ein FullHD-Streaming-Setup

FullHD Livestream auf 64bit Raspberry Pi Zero 2W Bookworm

Der Raspberry Pi Zero 2W ist eine kompakte, leistungsstarke Lösung für viele IoT- und Streaming-Projekte. In diesem Beitrag zeigen wir, wie man mit libcamera ein FullHD-Streaming-Setup optimiert, das stabil auf einem RTMP-Server läuft. Durch gezielte Optimierungen wie Overclocking, zram-Swap und Systemanpassungen lässt sich die Performance erheblich steigern. Zusätzlich gehen wir auf die Herausforderungen mit USB-Audio und sporadischen Alsa-Buffer-Xruns ein.

1. Übersicht: Wie funktioniert das System?

Das System besteht aus mehreren Komponenten:

  1. Raspberry Pi mit Kamera als Streaming-Client
    • Erfassen von Video (Kamera) und Audio (Mikrofon)
    • Kodierung in H.264 (Video) und AAC (Audio)
    • Streaming via RTMP (Real-Time Messaging Protocol) an den Server
  2. NGINX RTMP-Server als zentraler Streaming-Hub
    • Empfängt die Streams von einem oder mehreren Raspberry Pis
    • Bietet die Streams über RTMP, HLS oder WebRTC zur Weiterverarbeitung an
  3. Motion (Heimüberwachungssoftware)
    • Analysiert die RTMP-Streams in Echtzeit
    • Erkennt Bewegung und speichert Ereignisse als Bilder/Videos
    • Sendet bei Bewegung Benachrichtigungen

2. Installation des RTMP-Servers mit NGINX

Der NGINX RTMP-Server läuft am besten auf einem leistungsstarken Rechner im Netzwerk (z. B. Raspberry Pi 4, Mini-PC oder NAS).

Schritt 1: Installation von NGINX mit RTMP-Modul

Auf dem Server führst du aus:

sudo apt update
sudo apt install -y nginx libnginx-mod-rtmp

Schritt 2: Konfiguration des RTMP-Servers

Die Konfigurationsdatei von NGINX befindet sich unter:
/etc/nginx/nginx.conf

Ersetze den Inhalt oder erweitere ihn um folgende RTMP-Einstellungen:

rtmp {
    server {
        listen 1935; # Standard RTMP-Port

        application live {
            live on;
            record off;
            push rtmp://127.0.0.1:1935/motion; # Leitet Stream an Motion weiter
        }
        
        application motion {
            live on;
            record off;
        }
    }
}

Danach NGINX neustarten:

sudo systemctl restart nginx

Jetzt läuft dein RTMP-Server und ist bereit, Streams von den Raspberry Pis zu empfangen.


Raspberry Pi als RTMP-Streaming-Client einrichten

1. Hardware- und Softwareanforderungen

1.1 Benötigte Hardware

  • Raspberry Pi Zero 2W
  • Raspberry Pi Camera Module 3 (mit HDR-Support)
  • MicroSD-Karte (mind. 32 GB, vorzugsweise mit hoher Schreibgeschwindigkeit und/oder High Endurance)
  • USB-Netzteil mit mindestens 5V/2A
  • Kühlung (optional, aber empfohlen)
  • Netzwerkanbindung (WLAN oder Ethernet-Adapter für stabilere Verbindungen)

1.2 Installierte Software

  • Raspberry Pi OS (Lite empfohlen): Da wir keinen Desktop benötigen, spart dies Ressourcen.
  • libcamera: Ermöglicht moderne Kamera-Steuerung.
  • ffmpeg & rpicam-vid: Für die Verarbeitung und das Streaming.
  • zram: Reduziert SD-Kartenverschleiß und verbessert das Speichermanagement.

2. Installation der benötigten Pakete

2.1 System aktualisieren

Bevor wir mit der Installation beginnen, aktualisieren wir das System:

sudo apt update && sudo apt upgrade -y

2.2 Installation von libcamera und ffmpeg

Libcamera und ffmpeg sind notwendig für das Streaming:

sudo apt install -y rpicam-apps ffmpeg

2.3 Wechsel zu PipeWire für bessere Audio-Latenz

PipeWire ist eine modernere Alternative zu PulseAudio und verbessert die Latenz:

sudo apt install -y pipewire pipewire-pulse pipewire-audio-client-libraries

Nach der Installation setzen wir PipeWire als Standard:

systemctl --user enable pipewire pipewire-pulse
systemctl --user start pipewire pipewire-pulse

Überprüfen, ob PipeWire läuft:

pactl info | grep "Server Name"

Falls dort PipeWire steht, wurde der Wechsel erfolgreich durchgeführt.

2. Systemoptimierung für stabiles Streaming


2.1 Deaktivierung von unnötigen Diensten

Da der Zero 2W wenig RAM hat, sollten wir alle nicht benötigten Dienste deaktivieren:

sudo systemctl disable --now lightdm
sudo systemctl disable --now hciuart
sudo systemctl disable --now avahi-daemon
sudo systemctl disable --now triggerhappy

2.2 Optimierte Speicherverwaltung mit zram

ZRAM als Swap-Speicher auf dem Raspberry Pi einrichten

ZRAM ist eine Technik, die komprimierten Swap-Speicher im RAM anlegt. Dadurch kann der Raspberry Pi mehr Daten speichern, ohne ständig auf die SD-Karte zu schreiben. Dies verbessert nicht nur die Performance, sondern reduziert auch den Verschleiß der SD-Karte.


Vorteile von ZRAM auf dem Raspberry Pi

Schneller als herkömmlicher Swap – Da der Swap-Speicher im RAM liegt, sind die Lese- und Schreibgeschwindigkeiten wesentlich höher.
Weniger Verschleiß der SD-Karte – Normale Swap-Dateien auf der SD-Karte erzeugen viele Schreibzugriffe und verringern die Lebensdauer.
Effizientere Speichernutzung – Die Daten im ZRAM-Swap werden komprimiert gespeichert, wodurch effektiv mehr Platz zur Verfügung steht.


Installation von ZRAM-Swap auf dem Raspberry Pi

Die Einrichtung von ZRAM ist einfach und benötigt ein kleines Installationsskript aus einem GitHub-Repository.

Schritt 1: Git installieren

Falls Git noch nicht installiert ist, kannst du es mit folgendem Befehl nachinstallieren:

sudo apt update
sudo apt install git -y

Schritt 2: ZRAM-Swap-Repository klonen

Lade das ZRAM-Swap-Skript von GitHub herunter:

git clone https://github.com/foundObjects/zram-swap

Schritt 3: In das Verzeichnis wechseln und installieren

Nun in den Ordner wechseln und das Installationsskript ausführen:

cd zram-swap/
sudo ./install.sh

Das Skript konfiguriert ZRAM automatisch mit der optimalen LZ4-Komprimierung für den Raspberry Pi.


Funktionsweise von ZRAM-Swap

  • Ersetzt die Hälfte des physischen Speichers mit komprimiertem Swap-Speicher.
  • Verwendet standardmäßig LZ4-Kompression, da sie eine hohe Geschwindigkeit bietet.
  • Schreibt Swap-Daten nicht auf die SD-Karte, sondern speichert sie komprimiert im RAM.

Falls du die Einstellungen anpassen möchtest, kannst du die Datei zram-swap.sh bearbeiten:

sudo nano /usr/local/bin/zram-swap.sh

Dort findest du Kommentare, die die einzelnen Parameter gut dokumentieren.


ZRAM-Swap testen und überwachen

Nach der Installation kannst du den aktuellen ZRAM-Status mit folgendem Befehl überprüfen:

zramctl

Dieser zeigt die Größe des ZRAM-Speichers, die aktuelle Nutzung und den Komprimierungsgrad.

Falls du sehen möchtest, ob Swap benutzt wird, kannst du Folgendes ausführen:

free -h

Hier solltest du unter Swap sehen, dass ZRAM als Swap genutzt wird.


Mit ZRAM kann der Raspberry Pi effizienter mit seinem Arbeitsspeicher umgehen, insbesondere bei Systemen mit wenig RAM (z. B. Raspberry Pi 3 oder Zero). Dadurch läuft das System flüssiger und es gibt weniger Probleme mit Speicherüberlastung. 🚀

2.3 Optimierung des Dateisystems

Änderungen in /etc/fstab reduzieren Schreibzugriffe und optimieren das Dateisystem:

PARTUUID=82df2a3b-02  /  ext4  defaults,noatime,commit=600  0 1

3. Overclocking für bessere Leistung

Mit “nano /boot/config.txt” oder “nano /boot/firmware/config.txt” die Zeilen hinzufügen und den Raspberry neu starten. Hier wird auf jeden Fall ein aktiver Kühlkörper und/oder Lüfter empfohlen, obwohl meine Taktraten auch auf 800 MHz fallen und die Temperatur die 50 ° Grad Celsius Marke selten überschreitet.

Mit diesen Overclocking-Einstellungen verbessern wir die Performance des Pi Zero 2W:

arm_boost=1
arm_freq=1200
core_freq=400
over_voltage=3
gpu_freq=500
sdram_freq=400
temp_limit=80
gpu_mem=76

Die GPU wird gezielt optimiert, da das Encoding direkt darauf läuft.


4. Streaming mit libcamera und rpicam-vid

Das folgende Skript (/usr/bin/streamfull) streamt in FullHD mit niedriger Latenz:

#!/bin/bash
nice -16 rpicam-vid -t 0 --width 1920 --height 1080 --nopreview --low-latency 1 --flush --buffer-count 2 --hdr sensor --metadata - \
--profile high --level 4.2 --codec libav --libav-audio --audio-source alsa --audio-device hw:0,0 --audio-channels 1 --audio-codec aac -g 16 \
--audio-samplerate 48000 --audio-bitrate 64000 --libav-video-codec h264_v4l2m2m --libav-video-codec-opts "num_output_buffers=2;num_capture_buffers=8;strict=-2" \
--libav-format flv -n --framerate 30 -b 4800000 --autofocus-mode manual --lens-position 0.75 --av-sync 0 \
--denoise cdn_hq --autofocus-window 0.25,0.25,0.5,0.5 --inline 1 -o "rtmp://<IP-Adresse-des-Nginx--Servers>/zero/test"

4.1 Erklärung der wichtigsten Parameter

  • --low-latency 1: Reduziert die Latenz für Echtzeit-Streaming.
  • --buffer-count 2: Minimiert Puffer-Lags.
  • --hdr sensor: Nutzt den HDR-Modus des Kamera-Moduls 3.
  • --autofocus-mode manual: Fixiert den Fokus auf 0.75 für schärfere Aufnahmen.
  • --av-sync 0: Minimiert Audio-Video-Drift. (bitte hier selbst Werte im negativen oder positiven Bereich einstellen)
  • --denoise cdn_hq: Bessere Bildqualität mit hardwareseitigem Denoising.

Und hier die Optionen im Detail erklärt:

Allgemeine Einstellungen

  • #!/bin/bash
    → Definiert die Skriptsprache als Bash.
  • nice -16
    → Setzt die Priorität des Prozesses auf -16, wodurch er eine höhere CPU-Priorität erhält.

Videoaufnahme mit rpicam-vid

  • rpicam-vid
    → Startet das Libcamera-Videotool für den Raspberry Pi.
  • -t 0
    → Unbegrenzte Aufnahmezeit (0 bedeutet “unendlich”).
  • --width 1920 --height 1080
    → Setzt die Videoauflösung auf 1920×1080 (Full HD).
  • --nopreview
    → Deaktiviert die Vorschau auf dem Display, um Ressourcen zu sparen.
  • --low-latency 1
    → Aktiviert einen Low-Latency-Streaming-Modus für minimale Verzögerung.
  • --flush
    → Erzwingt das sofortige Senden der Videodaten, ohne auf volle Puffer zu warten.
  • --buffer-count 2
    → Setzt die Anzahl der Videopuffer auf 2, um Verzögerungen zu minimieren.
  • --hdr sensor
    → Aktiviert den HDR-Modus des Kamerasensors für besseren Dynamikumfang.
  • --metadata -
    → Sendet Metadaten (wie Belichtungszeit oder ISO) an die Standardausgabe.

Video-Encoding & Streaming

  • --profile high --level 4.2
    H.264 Encoding-Profil:
    • High: Beste Qualität
    • Level 4.2: Unterstützt Full HD @ 30 fps
  • --codec libav
    → Nutzt Libav als Videocodec-Framework.
  • --libav-video-codec h264_v4l2m2m
    → Verwendet den H.264 Hardware-Encoder (v4l2m2m), um die CPU zu entlasten.
  • --libav-video-codec-opts "num_output_buffers=2;num_capture_buffers=8;strict=-2"
    → Feineinstellungen für den Encoder:
    • num_output_buffers=2 → Minimale Wartezeit
    • num_capture_buffers=8 → Mehr Speicher für Decoding
    • strict=-2 → Erlaubt nicht standardisierte Parameter
  • --libav-format flv
    → Speichert/streamt das Video im FLV-Format, das für RTMP-Streaming optimiert ist.
  • -n
    Kein Standard-Output, verhindert unnötige Ausgaben.
  • --framerate 30
    → Setzt die Bildrate auf 30 fps.
  • -b 4800000
    Bitrate 4.8 Mbps, sorgt für hohe Qualität.

Audio-Einstellungen

  • --libav-audio
    → Aktiviert die Audioaufnahme über Libav.
  • --audio-source alsa
    → Nutzt ALSA als Audioquelle.
  • --audio-device hw:0,0
    → Setzt das Audio-Gerät auf ALSA-Device hw:0,0.
  • --audio-channels 1
    Mono-Audio, um Bandbreite zu sparen.
  • --audio-codec aac
    → Kodiert den Audio-Stream mit AAC.
  • --audio-samplerate 48000
    → Setzt die Abtastrate auf 48 kHz (Broadcast-Standard).
  • --audio-bitrate 64000
    → Setzt die Audio-Bitrate auf 64 kbps (kompromiss zwischen Qualität und Bandbreite).

Autofokus & Bildqualität

  • --autofocus-mode manual
    → Deaktiviert den Autofokus, setzt stattdessen einen festen Fokus.
  • --lens-position 0.75
    → Setzt den Fokus der Kamera auf 75% der maximalen Entfernung.
  • --autofocus-window 0.25,0.25,0.5,0.5
    → Definiert einen Autofokus-Bereich in der Mitte des Bildes.
  • --denoise cdn_hq
    → Aktiviert High-Quality Denoising (cdn_hq) für klarere Bilder.
  • --inline 1
    Alle Frames enthalten SPS/PPS Header, wichtig für flüssiges Streaming.

Streaming-Output

Stream-Name: zero/test.

-o "rtmp://192.168.178.25/zero/test"
Stream-Ziel:

Sendet das Video an den lokalen RTMP-Server unter 192.168.178.25.


5. USB-Audio-Probleme mit ALSA und XRuns

Ein bekanntes Problem ist, dass USB-Audio auf dem Raspberry Pi sporadische Buffer XRuns verursacht. Diese Fehler können zu kurzen Aussetzern führen, die aber im finalen Stream oft nicht wahrnehmbar sind. Folgende Maßnahmen können helfen:

echo "defaults.pcm.dmix.rate 48000" >> /etc/asound.conf
echo "defaults.pcm.dmix.period_time 100000" >> /etc/asound.conf

Zusätzlich kann rtprio in /etc/security/limits.conf angepasst werden:

@audio - rtprio 95
@audio - memlock unlimited

Damit erhält der Audiotreiber höhere Priorität.


Durch diese Optimierungen lässt sich ein FullHD-Stream mit dem Raspberry Pi Zero 2W erstaunlich stabil realisieren. Trotz der geringen Hardware-Ressourcen funktioniert das System mit der richtigen Konfiguration zuverlässig und ohne sichtbare Lags.

Das selbe Setup funktioniert auf einem Raspberry Pi4 und Pi5 auch ohne die Optimierungen an Zram, Dateisystem und anderen Stellen. Diese sind nur für den Pi Zero 2W nötig, wobei der geringe Speicher von nur 512 MB das Bottleneck darstellt.

Für die Alsa Buffer xruns (over und underruns) teste ich in Zukunft noch weitere Microphone, eventuell haben diese stabiliere und kleinere Audiopakete. Bislang fallen diese Fehler aber in den Streams nicht auf.

Falls Du Fragen oder weitere Optimierungsideen hast, hinterlasse einen Kommentar!

Auf dem Pi Zero 2W habe ich diese Fehler im Stream behoben:

[mp4 @ 0x1692c10] Encoder did not produce proper pts, making some up.
[h264_v4l2m2m @ 0x1692830] Pkt tracking failure: pts=105, track[105]=233
[h264_v4l2m2m @ 0x1692830] Pkt tracking failure: pts=106, track[106]=234
[h264_v4l2m2m @ 0x1692830] Pkt tracking failure: pts=107, track[107]=235
[h264_v4l2m2m @ 0x1692830] Pkt tracking failure: pts=108, track[108]=236
[h264_v4l2m2m @ 0x1692830] Pkt tracking failure: pts=109, track[109]=237
[h264_v4l2m2m @ 0x1692830] Pkt tracking failure: pts=110, track[110]=238
[h264_v4l2m2m @ 0x1692830] Pkt tracking failure: pts=111, track[111]=239
[h264_v4l2m2m @ 0x1692830] Pkt tracking failure: pts=116, track[116]=244
[h264_v4l2m2m @ 0x1692830] Pkt tracking failure: pts=117, track[117]=245
[h264_v4l2m2m @ 0x1692830] Pkt tracking failure: pts=118, track[118]=246
[h264_v4l2m2m @ 0x1692830] Pkt tracking failure: pts=119, track[119]=247
[h264_v4l2m2m @ 0x1692830] Pkt tracking failure: pts=120, track[120]=248

Und auch die ALSA-Buffer-xrun-Fehler größtenteils. (aber sie beeinträchtigen den Stream im Allgemeinen nicht).

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.