You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Thomas Junginger 81fb4d6094 Initial release: Raspberry Pi NDI Gateway 3 days ago
README.md Initial release: Raspberry Pi NDI Gateway 3 days ago
install-trixie-ndi-pi.sh Initial release: Raspberry Pi NDI Gateway 3 days ago

README.md

Raspberry Pi NDI Gateway

Work in Progress – erste öffentliche Veröffentlichung

Ein Installationsskript für einen Raspberry Pi 4 (ARM64) mit Raspberry Pi OS / Debian 13 „Trixie“. Das Projekt richtet einen headless NDI-Gateway mit GStreamer ein:

  • USB-HDMI-Capture → NDI
  • NDI → HDMI über DRM/KMS
  • optionales Capture-Audio → NDI

Der aktuelle Stand ist ausdrücklich nicht als vollständig getestete oder produktionsreife Lösung zu verstehen. Siehe Bekannte Einschränkungen.

Funktionsumfang des aktuellen Skripts

Bereich Implementierter Stand
Betriebssystem Debian 13 / Raspberry Pi OS Trixie, ARM64
GStreamer Debian-/Raspberry-Pi-OS-Systempakete
NDI-Plugin gst-plugin-ndi aus gst-plugins-rs, standardmäßig Tag 0.14.5
NDI-Runtime Vorhandene NDI-6-Runtime wird gesucht; andernfalls wird ein SDK-Archiv benötigt
Capture-Video Automatische oder manuelle V4L2-Geräteauswahl
Capture-Formate MJPEG und YUYV, sofern vom Gerät angeboten
Capture-Audio Optional; automatische oder manuelle ALSA-Geräteauswahl
NDI-Empfang NDI-Quelle per Name oder direkter IP:Port-Adresse
HDMI-Video Direkte Ausgabe über kmssink / DRM-KMS, ohne Desktop
HDMI-Audio Noch nicht implementiert; empfangenes NDI-Audio wird aktuell verworfen
Dienste ndi-capture.service und ndi-display.service
Diagnose /opt/ndi-pi/bin/ndi-pi-diagnose

Architektur

Capture: USB-Capture → NDI

USB-HDMI-Capture
   ├── V4L2-Video
   │     ├── MJPEG → jpegdec ───────────┐
   │     └── YUYV → videoconvert ───────┤
   │                                    ▼
   │                              kurze Queue
   │                                    │
   └── USB-Audio → ALSA → convert/resample
                                        │
                                        ▼
                                ndisinkcombiner
                                        │
                                      ndisink
                                        │
                                     NDI OUT

Wenn kein passendes Capture-Audiogerät gefunden wird oder ENABLE_AUDIO=false gesetzt ist, wird eine Video-only-Pipeline gestartet. Die Audiozuordnung erfolgt anhand des USB-Gerätepfads; wenn keine eindeutige Übereinstimmung gefunden wird, kann derzeit ersatzweise das erste gefundene USB-Audiogerät gewählt werden.

Display: NDI → HDMI

NDI IN
   │
 ndisrc
   │
ndisrcdemux
   │
   ├── Video → queue → videoscale → kmssink → HDMI
   │
   └── Audio → queue → fakesink (wird verworfen)

Die Videoausgabe verwendet DRM/KMS und benötigt daher keine Desktop-Umgebung wie X11 oder Wayland. Wenn die Live-Pipeline beendet wird, versucht der Dienst einen schwarzen Standby-Bildschirm mit Statusanzeige zu starten und die NDI-Verbindung erneut aufzubauen.

Voraussetzungen

  • Raspberry Pi 4 mit 64-Bit-ARM-System
  • Raspberry Pi OS / Debian 13 „Trixie“
  • Netzwerkverbindung; Ethernet wird empfohlen
  • USB-HDMI-Capture-Gerät mit Linux-V4L2-Unterstützung
  • HDMI-Display am Pi für die lokale Ausgabe
  • NDI-kompatible Gegenstelle im Netzwerk
  • Root-/sudo-Rechte für die Installation

Das Skript prüft Architektur und Debian-Codename. Andere Raspberry-Pi-Modelle, Betriebssystemversionen oder 32-Bit-Systeme sind nicht als unterstützt anzusehen.

Installation

  1. Repository auf dem Raspberry Pi klonen.
  2. Ein offizielles NDI-SDK-Archiv lokal bereitstellen oder eine Download-URL angeben.
  3. Installationsskript mit Root-Rechten ausführen.

Beispiel mit lokal heruntergeladenem SDK-Archiv:

sudo NDI_SDK_TARBALL=/pfad/zum/ndi-sdk.tar.gz ./install-trixie-ndi-pi-v18.sh

Alternativ kann die URL über die Umgebungsvariable übergeben werden:

sudo NDI_SDK_URL="https://<NDI-SDK-Download-URL>" ./install-trixie-ndi-pi-v18.sh

<NDI-SDK-Download-URL> ist durch die aktuelle Download-URL des NDI-Herstellers zu ersetzen. Die URL ist absichtlich nicht im Skript fest hinterlegt.

Wenn die NDI-6-Runtime bereits an einem der vom Skript geprüften Orte installiert ist, wird kein SDK-Archiv benötigt:

  • /usr/local/lib
  • /usr/lib/aarch64-linux-gnu

Das Skript installiert Systemabhängigkeiten, baut das NDI-GStreamer-Plugin und legt Konfiguration, Hilfsskripte und systemd-Units an. Es aktiviert und startet anschließend beide Dienste.

Hinweis: Das Installationsskript sollte vor dem Einsatz geprüft werden. Es verändert Systempakete, installiert Bibliotheken und schreibt Dateien unter /opt/ndi-pi, /etc und /etc/systemd/system.

Warum GStreamer aus den Distributionspaketen kommt

GStreamer selbst wird nicht aus einem Git-Repository gebaut. Das Skript installiert die GStreamer-Komponenten aus den Debian-/Raspberry-Pi-OS-Paketen. Das zusätzliche NDI-Plugin wird separat aus gst-plugins-rs gebaut.

Standardmäßig verwendet das Skript den Tag 0.14.5:

Debian / Raspberry Pi OS GStreamer
             │
             └── gst-plugin-ndi (gst-plugins-rs 0.14.5)
                         │
                         └── NDI 6 Runtime

Der Plugin-Tag kann über NDI_GST_TAG überschrieben werden:

sudo NDI_GST_TAG=0.14.5 NDI_SDK_TARBALL=/pfad/zum/ndi-sdk.tar.gz ./install-trixie-ndi-pi-v18.sh

Konfiguration

Die zentrale Konfigurationsdatei lautet:

/etc/ndi-pi.conf

Eine neue Installation legt sie mit folgenden wesentlichen Standardwerten an:

PI_NAME=<HOSTNAME>
NDI_CAPTURE_NAME=<HOSTNAME>-Capture
NDI_DISPLAY_SOURCE=PC01-Capture
NDI_DISPLAY_ADDRESS=auto
NDI_USE_DIRECT_ADDRESS=true

CAPTURE_DEVICE=auto
CAPTURE_WIDTH=1920
CAPTURE_HEIGHT=1080
CAPTURE_FPS=30
CAPTURE_FORMAT=MJPEG
CAPTURE_AUTO_FALLBACK=true
CAPTURE_QUEUE_BUFFERS=2

ENABLE_AUDIO=true
CAPTURE_AUDIO_DEVICE=auto
CAPTURE_AUDIO_RATE=48000
CAPTURE_AUDIO_CHANNELS=2

ENABLE_HDMI_AUDIO=false
HDMI_AUDIO_DEVICE=auto
KMS_DRIVER=vc4
KMS_CONNECTOR_ID=auto

NDI_MAX_QUEUE=0
DISPLAY_WIDTH=1920
DISPLAY_HEIGHT=1080
DISPLAY_FPS=60

<HOSTNAME> steht hier nur als Platzhalter für den vom Installer ermittelten Hostnamen. Die tatsächliche Datei enthält konkrete Werte.

Wichtige Einstellungen

Einstellung Bedeutung
NDI_CAPTURE_NAME Name der vom Pi gesendeten NDI-Quelle
NDI_DISPLAY_SOURCE Name der NDI-Quelle, die der Pi empfangen soll
NDI_DISPLAY_ADDRESS auto für mDNS-Auflösung oder feste Adresse im Format IP:Port
NDI_USE_DIRECT_ADDRESS Bei true wird die aufgelöste bzw. konfigurierte IP:Port-Adresse für ndisrc verwendet
CAPTURE_DEVICE auto oder ein konkreter V4L2-Gerätepfad
CAPTURE_WIDTH, CAPTURE_HEIGHT, CAPTURE_FPS Bevorzugter Capture-Modus
CAPTURE_FORMAT MJPEG, YUYV oder auto
CAPTURE_AUTO_FALLBACK Erlaubt die Suche nach einem anderen unterstützten Modus
CAPTURE_QUEUE_BUFFERS Anzahl der Videobuffer in der Capture-Queue
ENABLE_AUDIO Aktiviert/deaktiviert Capture-Audio → NDI
CAPTURE_AUDIO_DEVICE auto oder ALSA-Gerät, z. B. plughw:2,0
KMS_DRIVER DRM/KMS-Treiber, Standard vc4
KMS_CONNECTOR_ID auto oder eine feste DRM-Connector-ID
DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_FPS Auflösung und Framerate des Standby-Bildes
NDI_MAX_QUEUE NDI-Empfangsqueue; Standardwert 0

ENABLE_HDMI_AUDIO und HDMI_AUDIO_DEVICE sind derzeit vorbereitete Konfigurationswerte, werden von der aktuellen Display-Pipeline aber noch nicht umgesetzt. Sie einzuschalten aktiviert daher keine HDMI-Audioausgabe.

Bestehende Konfigurationen werden vom Installer ergänzt, ohne vorhandene Werte generell zu überschreiben. Bei älteren Konfigurationsdateien sollten die benötigten Capture-Werte kontrolliert und gegebenenfalls ergänzt werden.

Capture-Geräteauswahl und Videoformate

Mit:

CAPTURE_DEVICE=auto

untersucht das Skript /dev/video* und berücksichtigt Geräte mit V4L2-Video-Capture-Funktion und einem unterstützten Modus.

Für eine feste Installation kann ein konkreter Pfad eingetragen werden, vorzugsweise ein stabiler Symlink:

CAPTURE_DEVICE=/dev/v4l/by-id/<GERAETEPFAD>

Die Modusauswahl berücksichtigt die tatsächlich vom Gerät gemeldeten Formate. Die gewünschte Kombination aus Auflösung und Framerate wird zuerst versucht. Wenn CAPTURE_AUTO_FALLBACK=true gesetzt ist, folgt eine festgelegte Fallback-Liste.

Wichtig zur Formatpriorität: Bei CAPTURE_FORMAT=auto ist die aktuelle Fallback-Reihenfolge YUYV vor MJPEG. Auch die Gerätebewertung bevorzugt YUYV. Das unterscheidet sich von einer MJPEG-first-Strategie. Bei einer neuen Installation steht CAPTURE_FORMAT=MJPEG als Standard in der Konfiguration; damit wird die Auswahl auf MJPEG beschränkt, sofern ein passender Modus vorhanden ist und ein Fallback nicht durch die Formatvorgabe ausgeschlossen wird.

MJPEG wird mit jpegdec dekodiert. Der aktuelle Code verwendet bewusst nicht v4l2jpegdec. YUYV wird über videoconvert in UYVY konvertiert, bevor es an den NDI-Sink geht.

Audio

Capture-Audio → NDI

Bei ENABLE_AUDIO=true versucht das Skript, ein ALSA-Gerät zu finden, das zum ausgewählten USB-Capture-Gerät gehört. Alternativ kann ein ALSA-Gerät fest vorgegeben werden:

CAPTURE_AUDIO_DEVICE=plughw:2,0

Die automatische Zuordnung ist heuristisch und sollte mit der konkreten Capture-Hardware überprüft werden. Wird kein Gerät gefunden, startet die Capture-Pipeline als Video-only.

NDI-Audio → HDMI

Diese Richtung ist im aktuellen Skript noch nicht implementiert. Der Audio-Pad von ndisrcdemux wird derzeit an fakesink angeschlossen und damit verworfen. Es gibt aktuell keine ALSA-Wiedergabepipeline für den NDI-Ton.

NDI-Discovery und Netzwerk

Der Display-Dienst verwendet standardmäßig:

NDI_DISPLAY_SOURCE=PC01-Capture
NDI_DISPLAY_ADDRESS=auto
NDI_USE_DIRECT_ADDRESS=true

Bei auto versucht das Skript, den NDI-Dienst über Avahi/mDNS (_ndi._tcp) aufzulösen und die ermittelte IP-Adresse samt Port an ndisrc zu übergeben. Eine feste Adresse kann so angegeben werden:

NDI_DISPLAY_ADDRESS=192.168.1.50:5961

Der tatsächliche Port ist abhängig von der NDI-Quelle und muss passend ermittelt werden. Wenn keine direkte Adresse verfügbar ist, verwendet der initiale Start ndi-name als Fallback. Die Wiederverbindungslogik ist derzeit noch eingeschränkt; siehe Bekannte Einschränkungen.

Für Discovery über VLAN- oder Subnetzgrenzen hinweg kann eine gesonderte NDI-Discovery-Server-Konfiguration erforderlich sein. Das wird vom Installationsskript nicht eingerichtet.

systemd-Dienste und Logs

Es werden zwei getrennte Dienste angelegt:

ndi-capture.service
ndi-display.service

Status prüfen:

systemctl status ndi-capture
systemctl status ndi-display

Logs verfolgen:

journalctl -u ndi-capture -f
journalctl -u ndi-display -f

Beide Dienste verwenden Restart=always und aktuell RestartSec=1.

Nach einer Änderung an /etc/ndi-pi.conf:

sudo systemctl restart ndi-capture ndi-display

Diagnose

Das Diagnoseprogramm liegt unter:

sudo /opt/ndi-pi/bin/ndi-pi-diagnose

Es sammelt unter anderem:

  • Kernel- und Betriebssysteminformationen
  • GStreamer-Version und ausgewählte Plugin-Informationen
  • V4L2-Geräte und gemeldete Capture-Formate
  • ALSA-Aufnahme- und Wiedergabegeräte
  • DRM-Geräte und Connector-Status
  • NDI-Konfiguration und NDI/mDNS-Discovery
  • systemd-Status und letzte Service-Logs

Für Fehlerberichte ist die vollständige Ausgabe hilfreich. Zugangsdaten oder andere private Netzwerkinformationen sollten vor dem Veröffentlichen entfernt werden.

Bekannte Einschränkungen

Der folgende Abschnitt beschreibt bewusst den Stand des aktuellen Skripts und ist Teil der WIP-Kennzeichnung.

  1. NDI-Audio wird am HDMI-Ausgang nicht wiedergegeben. Der Empfangs-Audiozweig endet aktuell in fakesink.
  2. Automatische USB-Audiozuordnung ist nicht garantiert. Wenn die Zuordnung zum Video-Gerät nicht gelingt, kann ein anderes erstes USB-Audiogerät als Fallback ausgewählt werden.
  3. Wiederverbindung nach NDI-Ausfall ist eingeschränkt. Die Standby-Schleife prüft eine direkte IP:Port-Adresse. Wenn nur der Namens-Fallback aktiv ist oder mDNS die Quelle nicht auflösen kann, wird die Quelle nicht in allen Fällen erneut gefunden.
  4. Signalbehandlung des Display-Helfers muss weiter getestet werden. Das aktuelle Trap räumt den Standby-Prozess auf; das Verhalten beim Beenden durch systemd sollte auf dem Zielgerät überprüft werden.
  5. Ältere Konfigurationsdateien benötigen Prüfung. Die Migration ergänzt einige Schlüssel, aber nicht alle möglichen Capture-Parameter. Fehlende Werte wie CAPTURE_WIDTH oder CAPTURE_FPS können bei älteren Konfigurationen problematisch sein.
  6. NDI-Runtime-Pfad in systemd: Der Installer erkennt die Runtime auch unter /usr/lib/aarch64-linux-gnu; die erzeugten systemd-Units setzen aktuell jedoch fest NDI_RUNTIME_DIR_V6=/usr/local/lib. Bei einer Runtime-Installation im Multiarch-Verzeichnis muss das geprüft werden.
  7. Keine vollständige Hardware-/Laufzeitvalidierung durch Syntaxprüfung: Ein erfolgreicher Bash-Syntaxcheck bestätigt weder GStreamer-Pipeline-Negotiation noch NDI-Discovery, DRM/KMS-Ausgabe oder das Verhalten einer konkreten Capture-Karte.

Weitere bekannte Entwicklungsaufgaben sind eine umfassendere Plugin-Prüfung, robustere Installer-Rollback-Strategien und eine Prüfung des SDK-Archivs anhand eines verifizierten Hashes bzw. einer Signatur.

Sicherheit und Lizenzhinweise

Das NDI SDK bzw. die NDI-Runtime wird vom NDI-Hersteller bereitgestellt und unterliegt dessen Lizenz- und Distributionsbedingungen. Das SDK-Archiv und die Runtime-Bibliotheken sollten nicht ohne Prüfung dieser Bedingungen in ein öffentliches Repository eingecheckt oder weiterverteilt werden.

Das Repository enthält das Installationsskript und die Projektdateien; Nutzer müssen die NDI-Runtime entsprechend den geltenden Herstellerbedingungen selbst beziehen bzw. bereitstellen.

Das Installationsskript entpackt ein bereitgestelltes SDK-Archiv mit Root-Rechten. Verwende nur ein vertrauenswürdiges Archiv aus einer offiziellen Quelle. Eine automatisierte Hash-/Signaturprüfung des Archivs ist im aktuellen Skript noch nicht implementiert.

Projektstatus

Dieses Projekt wird aktiv entwickelt. Hardwarekombinationen, Capture-Modi, NDI-Versionen und HDMI-Ausgabeverhalten können sich unterscheiden. Rückmeldungen mit Diagnoseausgabe, Pi-Modell, OS-Version und genauer Capture-Hardware sind willkommen.

Vor einem produktiven Einsatz sind Tests mit der eigenen Hardware und Netzwerkinfrastruktur erforderlich.