Halloween-Fensterprojektion per MQTT steuern
Für Halloween wollte ich mehrere Fensterprojektionen zentral und genau im richtigen Moment starten können. Die Player sollen selbstständig auf Raspberry Pis laufen, sich per MQTT ansteuern lassen und nach jedem Effekt wieder in ihre Idle-Schleife zurückkehren.
MQTT übernimmt die Regie
Die Befehle kommen bei mir aus Home Assistant. Dort verknüpfe ich Bewegungsmelder oder Zeitpläne mit Automationen, die MQTT-Nachrichten an einen einzelnen Player oder an alle Player veröffentlichen. Jeder Pi hat dafür eine eigene ID; über halloween/all/cmd lässt sich die ganze Gruppe ansprechen.
Ein Befehl kann neben der Video-ID einen absoluten Unix-Zeitstempel enthalten. So können mehrere Player auf denselben Startzeitpunkt zielen, auch wenn die MQTT-Nachrichten nicht exakt gleichzeitig eintreffen. Kommt ein Befehl verspätet an, steigt der Player an der passenden Stelle in den Clip ein. Voraussetzung dafür sind per NTP synchronisierte Uhren; zwei bis drei Sekunden Vorlauf haben sich bewährt.

Home-Assistant-Automationen veröffentlichen MQTT-Befehle. Jeder Player startet beim Boot, wartet auf init, spielt den Effekt zum gesetzten Zeitpunkt ab und fällt danach in die Idle-Schleife zurück.
Der Player startet mit dem Raspberry Pi
Auf jedem Pi läuft der Player als systemd-Dienst, also als automatisch verwalteter Linux-Dienst. Beim Einschalten startet er selbstständig und gibt das Bild direkt über KMS/DRM aus – ohne Desktop, Mauszeiger oder Konsolentext.
Nach dem Start zeigt der Player zunächst Schwarz und wartet auf init. Erst dieser Befehl schaltet ihn frei und startet die Idle-Schleife. Standardmäßig ist das ein schwarzer Endlosclip; in der Konfiguration lässt sich auch ein anderer Clip verwenden. Die Freigabe ist bewusst nötig: Nach einem Stromausfall soll die Show nicht ungefragt wieder anlaufen.
Kein schwarzes Aufblitzen zwischen den Clips
Der Player beendet mpv nicht zwischen den Videos. Beim Wechsel bleibt das bisherige Bild stehen, bis der erste Frame des nächsten Clips bereit ist. Am Clipende hält mpv mit --keep-open=yes den letzten Frame, während der Player die Idle-Schleife lädt. So fällt die Projektion nicht kurz auf den schwarzen Hintergrund zurück. Es sind harte Schnitte, keine Überblendungen – mit schwarzer Idle-Schleife bleibt der Wechsel trotzdem unauffällig.
Nach einem normalen Effekt kehrt der Player selbstständig in die Idle-Schleife zurück. Ein stop-Befehl kann ebenfalls sofort dorthin wechseln. Den aktuellen Zustand – waiting, idle oder playing – sowie die Verfügbarkeit meldet jeder Player über weitere MQTT-Topics. Eine Home-Assistant-Automation kann damit zum Beispiel prüfen, ob ein Player gerade idle ist, bevor sie durch Bewegung einen Clip startet.
Home Assistant sendet die MQTT-Befehle
Nach jedem Neustart muss der Player zuerst mit init freigegeben werden. Das kann Home Assistant zum Beispiel zum Beginn der Show erledigen:
action: mqtt.publish
data:
topic: halloween/all/cmd
payload: '{"action": "init"}'
Ein Effekt lässt sich gezielt oder für die ganze Gruppe starten. In diesem Beispiel wird der Kurzname raven drei Sekunden in die Zukunft geplant:
action: mqtt.publish
data:
topic: halloween/all/cmd
payload: >-
{"video": "raven", "at": {{ (now().timestamp() + 3) | int }}}
Für einen einzelnen Player wird halloween/all/cmd durch halloween/<beamer_id>/cmd ersetzt. Kurznamen wie raven werden in der Konfiguration einem lokalen Dateinamen zugeordnet; so müssen lange Videonamen nicht in jeder Automation stehen.
In meiner Bewegungsautomation löst der Zustands- oder Attributwechsel des Bewegungsmelders Halloween – Bewegung den MQTT-Aufruf aus. Er veröffentlicht den Clip scare-unison an halloween/beamer1/cmd – also gezielt an Player 1, ohne Zeitplanung oder Gruppenstart.

Bei Änderung des Bewegungsmelders veröffentlicht Home Assistant {"video": "scare-unison"} auf halloween/beamer1/cmd.
Eine weitere Automation kann einen Zeitplan nutzen, etwa um die Player zum Beginn des Abends mit init freizugeben. Bewegung und Zeitplan lösen also unterschiedliche Teile derselben MQTT-Steuerung aus.
Was für den Nachbau nötig ist
- Raspberry Pi 3 oder neuer mit Raspberry Pi OS Lite (64 Bit, ohne Desktop)
- Beamer mit HDMI-Eingang
- Home Assistant mit MQTT-Integration und ein erreichbarer MQTT-Broker
- Eigene MP4-Effektvideos; sie werden lokal auf den Playern gespeichert und sind nicht Teil des Repositories
Einen Player einrichten
-
Raspberry Pi OS Lite (64 Bit) mit dem Raspberry Pi Imager auf die SD-Karte schreiben und WLAN sowie SSH einrichten.
-
Per SSH verbinden, Git installieren und das öffentliche Projekt herunterladen:
sudo apt update && sudo apt install -y git git clone https://github.com/digitaldex/halloween-projection.git ~/halloween -
Den Installer starten:
bash ~/halloween/deploy/install_pi.shEr installiert die benötigten Pakete, richtet die Grafikgruppen und den systemd-Dienst ein, erzeugt den schwarzen Idle-Clip und fragt nach dem MQTT-Passwort. Eine vorhandene Konfiguration oder ein schon gespeichertes Passwort wird nicht überschrieben.
-
Den Pi einmal neu starten, damit die Gruppen für die direkte Bildausgabe wirksam werden. Danach
~/halloween/config/settings.yamlöffnen und Broker-Adresse sowie eine eindeutigeclient.beamer_ideintragen. -
Die eigenen Videos nach
~/halloween/media/kopieren. Mit--list-videoslassen sich die erkannten Namen prüfen; kurze Aliase wieravenkönnen in der Konfiguration ergänzt werden. Für Videodateien muss man selbst die nötigen Nutzungsrechte besitzen. -
Den Dienst starten und den Player aus Home Assistant mit
initfreigeben:sudo systemctl start halloween-beamer
Für jeden zusätzlichen Beamer wird die Einrichtung wiederholt und eine eigene ID vergeben. Die betreffenden Clips müssen auf jedem Player lokal vorhanden sein. Nachfolgende Neustarts starten den Dienst automatisch; nach einem Stromausfall wartet er trotzdem erneut auf init.
Praxiserfahrung
Der Aufbau wurde auf einem Raspberry Pi 3 mit 1080p30-Material getestet. Bei einem 60-Sekunden-Clip mit 9 Mbit/s wurden mit Software-Decoding und dem mpv-Profil fast keine verworfenen Frames gemessen. Auf diesem Pi war der Hardware-Decoder langsamer. Das ist ein Messwert für genau diesen Clip und Aufbau, keine Garantie für beliebiges Material; 4K oder höhere Bildraten überfordern einen Pi 3.
Fazit und Ressourcen
Home Assistant entscheidet, wann welcher Effekt startet; jeder Raspberry Pi übernimmt die Wiedergabe selbstständig. Das MQTT-Protokoll hält die Steuerung einfach, während die Idle-Schleife nach jedem Clip einen definierten Zustand herstellt.