← Alle Beiträge

AAA-Gaming auf einem Raspberry Pi im Wohnzimmer

Wie ein alter Raspberry Pi 3+ mit Kodi, Jellyfin und Moonlight den Linux-Gaming-PC im Keller auf den Fernseher bringt.

  • Raspberry Pi
  • Moonlight
  • Sunshine
  • Kodi
  • Linux
  • Game Streaming

Der Raspberry Pi 3+ startet natürlich kein modernes AAA-Spiel. Er übernimmt die viel leichtere Aufgabe: einen Videostream zu decodieren, während das Monster im Keller die eigentliche Arbeit erledigt.

Genau das war das Ziel. Der vorhandene Gaming-PC sollte im Keller bleiben, aber seine Spiele sollten sich am Samsung-TV im Wohnzimmer so unkompliziert anfühlen wie auf einer Konsole. Ohne zweiten Gaming-PC, ohne zusätzliche Konsole und möglichst auch ohne Tastatur und Maus.

Gaming-PC im Keller
Linux Mint 22.3
Ryzen 9 3900X
Radeon RX 9070 XT
Sunshine
        |
        | 5-GHz-WLAN
        v
Raspberry Pi 3+
Raspberry Pi OS Lite
Kodi + Jellyfin + Moonlight
        |
        v
Samsung-TV + Controller

Der Gewinn dahinter ist schnell erzählt: Statt eines lauten, sperrigen Gaming-Turms mitten im Wohnzimmer steht dort nur noch ein Pi, unsichtbar hinter dem Fernseher versteckt. Kein Kabelsalat quer durch den Raum, kein Lüftergeräusch neben der Couch, kein Gerät, das überhaupt als Gaming-PC erkennbar wäre. Weil Sunshine ganz normal im Netzwerk läuft, lässt sich derselbe Gaming-PC im Keller später auch von anderen Geräten aus ansteuern, mit etwas mehr Aufwand bei Portweiterleitung und Absicherung sogar von unterwegs über das Internet. Das ist aber ein eigenes Thema für einen anderen Beitrag und bleibt hier bewusst außen vor.

Der Plan klang zunächst einfach: Sunshine auf dem Gaming-PC, Moonlight auf dem Pi und dazwischen eine Netzwerkverbindung. Der interessante Teil begann dort, wo aus einem funktionierenden Stream ein wohnzimmertaugliches System werden sollte.

Der Gaming-PC wird zum Streaming-Host

Auf dem Rechner läuft Linux Mint 22.3. Er bleibt ein normaler Gaming-PC und übernimmt zusätzlich die Rolle des Sunshine-Hosts. Eine besondere Serverinstallation, Windows oder irgendeine Cloud-Infrastruktur sind dafür nicht nötig.

Nach der Installation von Sunshine werden dessen Weboberfläche eingerichtet, der Host mit einem Moonlight-Client gekoppelt und der Desktop beziehungsweise die gewünschten Anwendungen freigegeben. Bevor der Raspberry Pi ins Spiel kommt, sollte diese Verbindung mit einem anderen Moonlight-Client funktionieren.

Diese Reihenfolge spart später viel Zeit: Läuft Sunshine noch nicht zuverlässig, vermischen sich Host-Probleme mit Fehlern auf dem Pi. Ein erfolgreicher Test mit einem normalen Client schafft eine bekannte, funktionierende Ausgangsbasis.

Automatisch starten reicht noch nicht

Der Rechner im Keller soll nach dem Einschalten ohne Tastatur, Maus oder einen Gang durchs Treppenhaus erreichbar sein:

Einschalten
    |
    v
Linux Mint
    |
    v
automatische Anmeldung
    |
    v
Sunshine startet
    |
    v
Moonlight kann sich verbinden

Sunshine startet deshalb über die Autostart-Funktion von Linux Mint. Ein Versuch mit systemctl --user führte hier nicht zum Ziel, weil keine passende Sunshine-User-Unit vorhanden war. Autostart war für diesen Desktop-Rechner der direktere Weg.

Damit war der unbeaufsichtigte Start allerdings noch nicht fertig. Mint meldete den Benutzer zwar automatisch an, zeigte anschließend aber den Passwortdialog des GNOME-Keyrings. Direkt vor dem PC wäre das harmlos. Vom Wohnzimmer aus endet die vermeintliche Spielekonsole dagegen an einer Aufforderung, die ohne Tastatur nicht beantwortet werden kann.

Der Login-Keyring wurde deshalb so konfiguriert, dass nach der automatischen Anmeldung keine weitere Eingabe erforderlich ist. In diesem Setup bedeutete das, sein Passwort zu entfernen.

Dieser Komfort hat einen Preis: Die im Keyring gespeicherten Geheimnisse werden dann nicht mehr durch ein zusätzliches Keyring-Passwort geschützt. Ob dieser Kompromiss vertretbar ist, hängt davon ab, was der Benutzeraccount sonst noch speichert und wer physischen Zugriff auf den Rechner hat.

Game Streaming ist nicht fertig, sobald das Bild ankommt. Es ist fertig, wenn der Host unbeaufsichtigt starten kann.

Wake-on-LAN dauerhaft aktivieren

Der Gaming-PC soll nicht rund um die Uhr laufen. Wake-on-LAN, kurz WoL, erlaubt es, ihn bei Bedarf mit einem sogenannten Magic Packet über das Netzwerk aufzuwecken.

Das Ethernet-Interface des Rechners heißt enp39s0. Sein Zustand lässt sich mit ethtool kontrollieren:

sudo ethtool enp39s0 | grep -i wake

Entscheidend ist diese Ausgabe:

Wake-on: g

Das g steht für das Aufwecken durch ein Magic Packet. Eine einmalige Änderung mit ethtool kann nach dem nächsten Neustart allerdings wieder verschwunden sein. Dauerhaft wird die Einstellung deshalb im verwendeten NetworkManager-Profil hinterlegt:

sudo nmcli connection modify \
  "Kabelgebundene Verbindung 1" \
  802-3-ethernet.wake-on-lan magic

Anschließend lässt sich der gespeicherte Wert prüfen:

nmcli connection show "Kabelgebundene Verbindung 1" | grep wake-on-lan

Auch das Mainboard muss mitspielen. Im BIOS beziehungsweise UEFI gehören Optionen wie Wake on LAN oder das Aufwecken über PCIe aktiviert. ErP beziehungsweise EuP muss häufig deaktiviert sein, damit die Netzwerkkarte im ausgeschalteten Zustand noch genug Strom erhält.

Die Namen der Verbindung und der BIOS-Einträge sind systemspezifisch. Sie sollten nicht blind aus diesem Beispiel übernommen werden.

Kein Strom, wenn niemand spielt

Nachdem der Gaming-PC in den Keller gewandert war, tauchten zwei weitere Probleme auf: Er sollte dort nicht unnötig Strom verbrauchen, wenn ihn gerade niemand nutzt. Und das Entfernen des physischen Monitors ließ Linux die komplette Display-Konfiguration verlieren.

Ein Wächter-Skript für den Leerlauf

Die normale Idle-Erkennung des Linux-Mint-Desktops reichte dafür nicht aus. Der Rechner ist längst kein reiner Desktop mehr: Sunshine kann gerade ein Spiel streamen, während der lokale Desktop scheinbar untätig ist, und auch KI-Workloads können die GPU beschäftigen, ohne dass Tastatur oder Maus benutzt werden.

Stattdessen übernimmt ein kleiner systemd-Timer die Kontrolle, der regelmäßig prüft, ob der Rechner tatsächlich etwas Sinnvolles tut. Als aktiv gilt der Host, wenn eine der folgenden Bedingungen zutrifft:

Sunshine-Client verbunden
        ODER
AMD-GPU-Auslastung >= Schwellenwert
        ODER
aktive interaktive SSH-Sitzung

Trifft eine dieser Bedingungen zu, wird ein Aktivitäts-Zeitstempel aktualisiert. War keine davon für 30 Minuten wahr, folgt:

systemctl poweroff

Ein systemd-Timer führt die Prüfung einmal pro Minute aus:

[Timer]
OnBootSec=5min
OnUnitActiveSec=1min

Ein wichtiges Detail war die Sunshine-Erkennung. Zu prüfen, ob der Prozess sunshine existiert, funktioniert nicht, weil Sunshine dauerhaft läuft. Stattdessen wertet das Skript das Sunshine-Log aus und schaut sich das jeweils letzte Ereignis an:

CLIENT CONNECTED
CLIENT DISCONNECTED

Die GPU-Auslastung lässt sich ganz ohne zusätzlichen Monitoring-Daemon auslesen:

cat /sys/class/drm/card*/device/gpu_busy_percent

Und auch bei SSH-Sitzungen ist Vorsicht geboten: Auf sshd selbst zu prüfen, liefert einen falschen Positivbefund, weil der SSH-Server ohnehin immer als lauschender Prozess läuft. Eine tatsächliche interaktive Remote-Sitzung lässt sich stattdessen über who erkennen, indem nach einer pts/*-Sitzung mit einer entfernten Adresse gesucht wird.

Im Ergebnis sieht der Ablauf so aus:

Wake-on-LAN
     |
     v
Gaming-PC bootet
     |
     v
Sunshine- / KI- / SSH-Aktivität
     |
     v
bleibt wach
     |
     v
30 Minuten wirklich idle
     |
     v
Abschalten

In Kombination mit Wake-on-LAN kann der Kellerrechner so den größten Teil seiner Zeit vollständig ausgeschaltet verbringen, statt den ganzen Tag im Leerlauf zu laufen.

Das Skript im Detail

Das Skript liegt unter /usr/local/sbin/idle-poweroff und wird über den systemd-Timer minütlich ausgeführt:

#!/bin/bash

STATE="/run/idle-poweroff-last-active"
SUNSHINE_LOG="/home/luschee/.config/sunshine/sunshine.log"

IDLE_LIMIT=1800
GPU_BUSY_LIMIT=10
NOW=$(date +%s)

active=false
reason=""

#
# 1. Aktive Sunshine/Moonlight-Session?
#
if [[ -f "$SUNSHINE_LOG" ]]; then
    LAST_CLIENT_EVENT=$(
        grep -E 'CLIENT CONNECTED|CLIENT DISCONNECTED' "$SUNSHINE_LOG" \
        | tail -n 1
    )

    if [[ "$LAST_CLIENT_EVENT" == *"CLIENT CONNECTED"* ]]; then
        active=true
        reason="Sunshine client connected"
    fi
fi

#
# 2. AMD-GPU beschäftigt?
#
for GPU_BUSY_FILE in /sys/class/drm/card*/device/gpu_busy_percent; do
    [[ -r "$GPU_BUSY_FILE" ]] || continue

    GPU_BUSY=$(cat "$GPU_BUSY_FILE" 2>/dev/null)

    if [[ "$GPU_BUSY" =~ ^[0-9]+$ ]] && (( GPU_BUSY >= GPU_BUSY_LIMIT )); then
        active=true
        reason="GPU busy: ${GPU_BUSY}%"
        break
    fi
done

#
# 3. Aktive interaktive SSH-Session?
#
if who | awk '$2 ~ /^pts\// && $NF ~ /^\(.*\)$/ {found=1} END {exit !found}'; then
    active=true
    reason="SSH session active"
fi

#
# Aktiv -> Idle-Timer zurücksetzen
#
if [[ "$active" == true ]]; then
    echo "$NOW" > "$STATE"
    logger -t idle-poweroff "Active: $reason"
    exit 0
fi

#
# Noch kein Idle-Zeitpunkt vorhanden -> Timer starten
#
if [[ ! -f "$STATE" ]]; then
    echo "$NOW" > "$STATE"
    logger -t idle-poweroff "Idle timer started"
    exit 0
fi

LAST=$(cat "$STATE")

# Defekten State sicher behandeln
if ! [[ "$LAST" =~ ^[0-9]+$ ]]; then
    echo "$NOW" > "$STATE"
    exit 0
fi

IDLE_TIME=$(( NOW - LAST ))

logger -t idle-poweroff "Idle for ${IDLE_TIME}s"

#
# 30 Minuten wirklich inaktiv -> ausschalten
#
if (( IDLE_TIME >= IDLE_LIMIT )); then
    logger -t idle-poweroff "Idle for 30 minutes - powering off"
    systemctl poweroff
fi

Der zugehörige systemd-Timer sorgt für die minütliche Ausführung:

[Unit]
Description=Check gaming/AI PC idle state

[Timer]
OnBootSec=5min
OnUnitActiveSec=1min

[Install]
WantedBy=timers.target

Die Logs lassen sich bequem live mitverfolgen:

journalctl -t idle-poweroff -f

Kein Monitor, keine Auflösung

Der Umzug des PCs in den Keller brachte noch ein weiteres, überraschend lästiges Problem mit sich. Ohne angeschlossenen Monitor meldete die Radeon jeden Anschluss als getrennt:

card1-DP-1/status: disconnected
card1-DP-2/status: disconnected
card1-DP-3/status: disconnected
card1-HDMI-A-1/status: disconnected

Xorg fiel folglich zurück auf:

current 1024 x 768

Genau das sah dann auch Sunshine und streamte es entsprechend. Der Grund dafür ist EDID. Normalerweise teilt der Monitor der GPU mit, welche Auflösungen, Bildwiederholraten und sonstigen Fähigkeiten er unterstützt. Wird der Monitor entfernt, verschwindet auch diese Information.

Ein HDMI/DisplayPort-Dummy-Stecker aus dem Elektronikhandel hätte das Problem gelöst, das Ziel war hier aber eine reine Softwarelösung.

Eine Fake-EDID für den Kellerrechner

Also wurde eine kleine EDID-Datei erzeugt, die einen virtuellen 2560×1440-Bildschirm beschreibt:

Detailed Timing:
2560x1440
59.95 Hz

und als

/lib/firmware/edid/headless-1440p.bin

installiert. Dem Kernel wird anschließend über Boot-Parameter mitgeteilt, diese EDID für den ansonsten getrennten DisplayPort-Anschluss zu verwenden:

drm.edid_firmware=DP-1:edid/headless-1440p.bin
video=DP-1:2560x1440@60e

Das e am Ende von video=... erzwingt, dass der Anschluss aktiviert wird, obwohl kein physisches Display erkannt wird.

Ein zusätzlicher Haken: amdgpu benötigt die EDID bereits früh beim Booten. Deshalb wird sie über einen kleinen Hook unter /etc/initramfs-tools/hooks/edid ins initramfs aufgenommen:

#!/bin/sh
set -e

case "$1" in
    prereqs)
        exit 0
        ;;
esac

mkdir -p "${DESTDIR}/lib/firmware/edid"

cp /lib/firmware/edid/headless-1440p.bin \
   "${DESTDIR}/lib/firmware/edid/headless-1440p.bin"

Der Hook macht die Lösung außerdem einigermaßen update-fest: Sobald Ubuntu beziehungsweise Mint für einen neuen Kernel ein initramfs erzeugt, wird die eigene EDID automatisch wieder mit eingebunden.

Nach einem Neustart ist der Unterschied deutlich:

Vorher:
DP-1 -> disconnected
Xorg -> 1024x768

Nachher:
DP-1 -> connected
Xorg -> 2560x1440 @ 60 Hz

Aus Sicht des Software-Stacks ergibt sich damit:

headless-1440p.bin
        |
        v
Linux DRM / amdgpu
        |
        v
"DP-1 hat einen Monitor angeschlossen"
        |
        v
Xorg / Cinnamon
        |
        v
2560x1440-Desktop
        |
        v
Sunshine
        |
        v
Moonlight

Der Gaming-PC kann jetzt vollständig headless im Keller stehen: Wake-on-LAN schaltet ihn ein, die Fake-EDID verschafft Sunshine ein passendes Display, und das Idle-Skript schaltet ihn wieder ab, sobald niemand spielt, keine KI-Jobs laufen und keine SSH-Verbindung besteht.

Kabel für den Keller, WLAN fürs Wohnzimmer

Der Gaming-PC im Keller hängt per Ethernet im Gigabit-Netzwerk:

Gaming-PC --- Ethernet --- Router oder Switch

Für den Raspberry Pi im Wohnzimmer hätte das ein zusätzliches Netzwerkkabel quer durch die Wohnung bedeutet. Stattdessen verbindet sich der Pi über das 5-GHz-WLAN mit demselben Netz:

Gaming-PC --- Ethernet --- Router oder Switch --- 5-GHz-WLAN --- Raspberry Pi

Auf kurzer Distanz zum Access Point reicht das für einen stabilen Moonlight-Stream aus, ohne dass Latenz oder Bildfehler auffallen. Der Verzicht auf ein Kabel im Wohnzimmer war hier bewusst der Kompromiss gegen eine zusätzliche, sichtbare Leitung.

Wer stattdessen Aussetzer oder Ruckler bemerkt, sollte trotzdem zuerst die Netzwerkverbindung prüfen: WLAN-Signalstärke und mögliche Störungen durch 2,4-GHz-Geräte in der Nähe, bevor an Codecs oder Bitraten in Sunshine und Moonlight geschraubt wird.

Der naheliegende Plan mit LibreELEC

Für das Wohnzimmer schien LibreELEC zunächst perfekt:

LibreELEC
├── Kodi
├── Jellyfin
└── Moonlight

Kodi ist bereits das Zentrum des Systems, Jellyfin ergänzt die eigene Mediathek und Moonlight liefert die Spiele. In der Praxis war die aktuelle Kombination aus Jellyfin und Moonlight dort aber nicht so unkompliziert wie erwartet. Statt weiter gegen die fertige Appliance zu arbeiten, wurde LibreELEC verworfen.

Das war der erste Wendepunkt: Nicht die Distribution mit den meisten Wohnzimmerfunktionen war die beste Grundlage, sondern diejenige, die möglichst wenig zwischen Kodi, Moonlight und der Hardware versteckt.

Raspberry Pi OS Lite ohne Desktop

Die neue Basis wurde Raspberry Pi OS Lite. Kein Desktop, kein Window Manager und kein grafischer Ballast, der für diesen Anwendungsfall nicht gebraucht wird. Darauf laufen lediglich die benötigten Komponenten:

Raspberry Pi OS Lite
├── Kodi
│   └── Jellyfin-Integration
└── Moonlight Qt

Moonlight Qt benötigt auf dem Pi weder X11 noch Wayland. Ohne Display-Server kann Qt den EGLFS-Pfad verwenden und direkt über DRM/KMS auf HDMI ausgeben:

Moonlight Qt
    |
    v
Qt EGLFS
    |
    v
DRM/KMS
    |
    v
HDMI

Auf einem Raspberry Pi 3+ funktioniert dieser schlanke Grafikpfad erstaunlich gut.

Moonlight zuerst direkt testen

Noch bevor Kodi beteiligt war, startete Moonlight direkt auf tty1:

moonlight-qt

Das funktionierte. Damit waren gleich mehrere wichtige Fragen beantwortet:

  • Moonlight startet auf dem Pi.
  • Der direkte Grafikpfad über DRM funktioniert.
  • Decoding und Rendering funktionieren grundsätzlich.
  • Der Controller wird erkannt.
  • Die Verbindung zu Sunshine steht.

Dieser Test wurde später zum wichtigsten Hinweis der gesamten Fehlersuche.

Wenn Kodi Moonlight starten soll

Der gewünschte Ablauf sah wie bei einer Konsole aus:

Kodi
  |
  v
Moonlight auswählen
  |
  v
spielen
  |
  v
Moonlight verlassen
  |
  v
zurück zu Kodi

Der erste Versuch war ein kleines Kodi-Addon, das Moonlight mit subprocess.Popen(...) startete. Das erschien logisch: Kodi läuft bereits, ein Menüeintrag ruft einen Prozess auf und nach dessen Ende geht es zurück zur Medienoberfläche.

Es funktionierte trotzdem nicht.

DRM/KMS sagt Nein

Beim Start aus Kodi erschien schließlich der entscheidende Fehler:

qt warning:
could not queue drm page flip on screen HDMI1
(permission denied)

Direkt auf der Konsole lief derselbe Aufruf von moonlight-qt weiterhin. Der Benutzer durfte außerdem auf die Geräte unter /dev/dri zugreifen. Damit war klar: Weder Moonlight selbst noch eine einfache Dateiberechtigung waren das eigentliche Problem.

Der Unterschied war der DRM-Kontext. Kodi hielt die Display- und DRM-Ressourcen noch belegt, während der von Kodi gestartete Moonlight-Prozess dieselben Ressourcen übernehmen wollte. Zwei Programme wollten zur gleichen Zeit die direkte Kontrolle über denselben Bildausgang.

Der Parent-Prozess war damit der falsche Ort, um den Wechsel zu organisieren.

tty1 wird zum Supervisor

Die funktionierende Lösung dreht die Verantwortung um: Kodi startet Moonlight nicht mehr. Stattdessen verwaltet der Login-Shell-Prozess auf tty1 beide Anwendungen nacheinander.

Login-Shell auf tty1
    |
    +-- Kodi starten
    |
    +-- Kodi beendet sich
    |
    +-- wurde Moonlight angefordert?
    |
    +-- warten, bis Kodi DRM freigegeben hat
    |
    +-- Moonlight direkt starten
    |
    +-- Moonlight endet
    |
    `-- Kodi erneut starten

Moonlight wird dadurch aus genau dem Kontext gestartet, in dem der manuelle Test zuvor funktioniert hatte: direkt aus tty1 und erst nachdem Kodi den Grafikpfad freigegeben hat.

Das Kodi-Addon setzt nur noch ein Flag

Das Addon schrumpft auf zwei Aufgaben zusammen. Es legt eine Datei als Startsignal an und beendet Kodi:

import os

import xbmc

with open(os.path.expanduser("~/.launch-moonlight"), "w") as marker:
    marker.write("1")

xbmc.executebuiltin("Quit")

Keine Prozessverwaltung, keine DRM-Sonderbehandlung und kein Warten innerhalb von Kodi. Das Addon teilt der äußeren Schleife nur mit, warum Kodi beendet wurde.

Der Wechsel passiert außerhalb von Kodi

Die eigentliche Steuerung übernimmt ein kleines Shell-Script:

#!/bin/bash

while true; do
    kodi-standalone

    if [ -f "$HOME/.launch-moonlight" ]; then
        rm -f "$HOME/.launch-moonlight"

        while pgrep -x kodi >/dev/null || pgrep -x kodi.bin >/dev/null; do
            sleep 1
        done

        /usr/bin/moonlight-qt
        continue
    fi

    break
done

Dieses Script wird beim Login auf tty1 gestartet. Beendet das Addon Kodi mit gesetztem Marker, wartet die Schleife, bis keine Kodi-Prozesse mehr laufen. Erst dann übernimmt Moonlight den Bildschirm. Nach dem Beenden von Moonlight beginnt die Schleife von vorn und startet Kodi erneut.

Der entscheidende Punkt ist nicht das Flag selbst. Entscheidend ist, dass Kodi und Moonlight Geschwister unter einem gemeinsamen Supervisor sind und niemals gleichzeitig DRM besitzen sollen.

Ein Controller für beide Welten

Der generische Xbox-Controller wird vom Raspberry Pi erkannt. Kodi verwendet ihn für die Navigation; Moonlight reicht seine Eingaben an Sunshine weiter.

Controller am Raspberry Pi
            |
            v
         Moonlight
            |
            v
virtueller Controller am Gaming-PC
            |
            v
           Spiel

Der Gaming-PC selbst braucht damit im Idealfall weder Tastatur noch Maus. Das ist der Moment, in dem aus einem technischen Streaming-Test tatsächlich eine Wohnzimmerkonsole wird.

Bild da, Controller da, Ton weg

Nach der DRM-Lösung wartete bereits das nächste Problem:

Bild        ja
Controller  ja
Audio       nein

ALSA erkannte sowohl den analogen Ausgang als auch HDMI:

card 0: bcm2835 Headphones
card 1: vc4-hdmi

Ein Test des Audiogeräts scheiterte trotzdem:

Playback open error: -524

Das sah zunächst nach einem Problem mit Raspberry Pi OS, ALSA oder Moonlight aus. Die entscheidende Information kam aber nicht aus der Anwendung, sondern vom angeschlossenen Display.

EDID verrät den eigentlichen Verursacher

Der Pi hing für die Einrichtung vorübergehend an einem Fujitsu B23T-7 LED. Die ausgelesenen ELD-Daten enthielten:

monitor_name    B23T-7 LED
connection_type HDMI
sad_count       0

Zusätzlich fehlte ein CEA-Erweiterungsblock in den EDID-Daten:

no CEA EDID Timing Extension block present

Das Display meldete dem Raspberry Pi damit keine nutzbaren HDMI-Audiofähigkeiten. Der HDMI-Ausgang tauchte zwar als vc4-hdmi auf, ein Audiostream ließ sich darüber aber nicht öffnen.

Manchmal ist ein HDMI-Audiofehler gar kein Audiofehler. Es ist nur der Monitor, der Linux höflich mitteilt, dass Audio für ihn nicht existiert.

Zurück am Samsung-TV funktioniert der Ton

Der Gegencheck war einfach: Raspberry Pi wieder an den Samsung-TV anschließen und speaker-test erneut ausführen. Dort kam sofort Ton.

Moonlight  nicht kaputt
ALSA       nicht kaputt
Pi         nicht kaputt
EDID des Testmonitors war die Ursache

Auch hier half die schrittweise Diagnose. Ein sichtbares HDMI-Gerät beweist noch nicht, dass das angeschlossene Display tatsächlich Audioformate über EDID angekündigt hat.

Das fertige System

Am Ende übernimmt jedes Gerät nur die Aufgabe, für die es geeignet ist:

Controller
    |
    v
Raspberry Pi 3+
    |
    +-- Kodi
    |    `-- Jellyfin
    |
    `-- Moonlight
          |
          | 5-GHz-WLAN
          v
       Sunshine
          |
          v
Linux-Mint-Gaming-PC
Ryzen 9 + Radeon RX 9070 XT
im Keller

Der Ablauf im Wohnzimmer ist entsprechend kurz:

TV einschalten
      |
      v
Pi bootet in Kodi
      |
      v
Moonlight auswählen
      |
      v
Gaming-PC bei Bedarf per WoL aufwecken
      |
      v
Sunshine streamt das Spiel
      |
      v
Moonlight verlassen
      |
      v
Kodi erscheint wieder

Kein Desktop auf dem Pi. Kein X11. Keine Tastatur. Keine Maus. Und kein zusätzlicher Gaming-Rechner im Wohnzimmer.

Kann ein Raspberry Pi 3+ nun moderne AAA-Spiele ausführen?

Absolut nicht.

Er decodiert lediglich den fertigen Videostream, und selbst dabei gibt es eine harte Grenze: Mehr als 1080p bei 30 fps schafft der Pi 3+ nicht. Wer höhere Auflösungen oder Bildraten möchte, kommt an einem Raspberry Pi 4, 5 oder vergleichbar leistungsfähiger Hardware nicht vorbei.

Aber er kann dafür sorgen, dass sich ein Ryzen 9 und eine Radeon RX 9070 XT im Keller so anfühlen, als stünden sie direkt unter dem Fernseher. 🌶️