No description
  • HTML 50.2%
  • Go 46.2%
  • Shell 1.8%
  • PowerShell 0.8%
  • Makefile 0.5%
  • Other 0.5%
Find a file
thiel a7a959cb47
All checks were successful
CI / release (push) Successful in 17s
CI / test (push) Successful in 7s
Server-Referenzzeit: geraeteunabhaengige Uhr-/Timer-Sync
playerui zeigt via nowMs()=Date.now()+Offset in allen Sekunden-Widgets
und der Sync die identische Server-Zeit statt der eigenen Geraeteuhr.
Der Offset kommt aus X-Server-Now:
- sync.go: liest X-Server-Now beim Manifest-Poll (RTT/2-korrigiert),
  merkt den Offset atomar; ServerNowMs() liefert die frische Schaetzung
- server.go: stempelt X-Server-Now frisch auf /manifest.json (aus dem
  gemerkten Offset), damit die zwischengespeicherte Zeit nicht veraltet
- playerui/index.html: nowMs()/syncClockOffset(); alle Zeitlesestellen +
  clockAlign + syncClock-elapsed + Video-Sync auf nowMs(); poll liest Header
2026-07-14 04:43:59 +00:00
.forgejo/workflows ci: image.yml nur noch manuell (workflow_dispatch) statt bei jedem Tag -> kein rotes Release mehr 2026-07-13 07:49:56 +00:00
cmd/agent player: Auto-Browser unter Windows via rundll32 (zuverlaessiger als cmd /c start) 2026-07-13 09:25:39 +00:00
deploy Robuster lokaler Player fuer Windows/Linux/macOS aus einem Repo (v0.1.21) 2026-07-11 13:36:17 +00:00
internal Server-Referenzzeit: geraeteunabhaengige Uhr-/Timer-Sync 2026-07-14 04:43:59 +00:00
playerui Server-Referenzzeit: geraeteunabhaengige Uhr-/Timer-Sync 2026-07-14 04:43:59 +00:00
.dockerignore Web-Player Variante A: headless Docker-Image (Dockerfile/compose/.dockerignore, multi-arch image.yml) + Klick-to-Fullscreen-Geste in der Player-UI 2026-07-05 16:20:58 +00:00
.gitignore Player-Repo initialisiert 2026-07-04 20:03:12 +00:00
CHANGELOG.md Headless Web-Player (Variante A): Start-Log LAN/Host-IP-Hinweis 2026-07-10 21:07:35 +00:00
docker-compose.yml Web-Player Variante A: headless Docker-Image (Dockerfile/compose/.dockerignore, multi-arch image.yml) + Klick-to-Fullscreen-Geste in der Player-UI 2026-07-05 16:20:58 +00:00
Dockerfile Player: Update-Hook + Multi-Arch-Image-Fix 2026-07-09 22:01:28 +00:00
go.mod Player-Agent Slice 1: pull, cache, lokale UI, Kiosk 2026-07-04 20:39:29 +00:00
Makefile Robuster lokaler Player fuer Windows/Linux/macOS aus einem Repo (v0.1.21) 2026-07-11 13:36:17 +00:00
README.md docs: Browser-Ersteinrichtung + Binary/exe-Verteilung in README 2026-07-13 12:34:06 +00:00

signagetools-player

On-Device-Player für signagetools. Läuft auf dem Anzeigegerät (Raspberry Pi / Mini-PC) und zeigt das vom Server zugewiesene Layout an — auch offline.

Design- und Architektur-Dokumente liegen zentral im Haupt-Repo signagetools (siehe docs/). Dieses Repo enthält nur den Player.

Rolle

  • Meldet sich per Token am Server an (Pairing → Token).
  • Pull-Modell: zieht regelmäßig sein Manifest (JSON: zugewiesenes Layout + Medienliste mit Hashes) vom Server.
  • Lädt nur geänderte Medien (Hash-Abgleich) in einen lokalen Cache.
  • Startet Chromium im Kiosk-Modus gegen eine lokal ausgelieferte Player-UI.
  • Läuft bei Netzausfall offline weiter (letzter gültiger Stand).
  • Meldet Status zurück (zuletzt gesehen, aktueller Inhalt, Fehler).

Player-Optionen im Überblick

Es gibt mehrere Wege, einen Bildschirm zu bespielen — vom „Browser aufmachen" bis zur robusten Dauerinstallation. Alle nutzen dasselbe Modell: das Gerät koppelt sich (Kopplungscode → im Builder unter ▶ Player → Verwaltung freigeben) und wird dann mit ▶ Spielen oder über den Zeitplan bespielt.

Option Installation Vollbild/Kiosk Offline-Cache Am besten für
Web-Player im Browser (/play) keine Tap / „Zum Home-Bildschirm" (PWA) nur Browser-Cache (schwächer) iPads/Tablets/Smart-TVs, schnelle & temporäre Screens
Nativer lokaler Player (Laptop/Mini-PC) Binary + Autostart (deploy/) eigener Kiosk-Browser, Auto-Neustart voller Platten-Cache dauerhafte, robuste Screens ohne Docker (Win/Linux/macOS)
Nativer Player auf Raspberry Pi Binary (make build-pi) + -kiosk eigener Kiosk-Browser voller Platten-Cache klassische Kiosk-Appliance
Docker (headless, „Variante A") docker compose up Browser/TV zeigt :4000 an Volume-Cache Server/Mini-PC mit Docker, zentrale Updates

Kurz entscheiden:

  • Schnell / temporär / TabletWeb-Player (https://<server>/play), nichts zu installieren.
  • Dauerhaft & robust auf einem Laptop/Mini-PCnativer lokaler Player (siehe deploy/) — offline-fest, kein Docker.
  • Du betreibst ohnehin DockerContainer-Variante (headless).

Zwei Betriebsarten (für native/Docker-Player und den Web-Player):

  • Kopplung (empfohlen): ohne festes Ziel starten → Kopplungscode → im Builder freigeben. Vollwertiges Flottengerät (Zeitplan, Wartung, Sofort-Nachrichten, Screenshots, Videowand). Token bleibt im DATA_DIR bzw. localStorage.
  • Festes Ziel (ohne Kopplung): LAYOUT_ID= (festes Layout) oder SCREEN_ID= (zeitgesteuerter Screen-Key) — praktisch für schnelle Kioske.

Details: robuster lokaler Player → deploy/README.md; Web-Player & Server-Betrieb → docs/DEPLOYMENT.md im Server-Repo (§12 Web-Player, §5/§6 Player koppeln & zuweisen).

Ersteinrichtung im Browser (Windows, ohne Flags)

Für einen Windows-Mini-PC ist kein Kommandozeilen-Flag nötig:

  1. Aktuelle sigplayer-windows-amd64.exe aus den Releases dieses Repos herunterladen (Asset am jeweiligen v*-Tag; die CI baut alle Plattformen: Linux amd64/arm64, Windows, macOS amd64/arm64).
  2. Doppelklick → der Player öffnet automatisch den Browser auf http://localhost:4000 mit einer Einrichtungsseite. Öffnet er nicht von selbst (ältere .exe), die Adresse manuell aufrufen.
  3. Server-Adresse eintragen und speichern → der Player zeigt einen Kopplungscode, den man im Builder unter Geräte freigibt.
  4. Die Eingaben werden in player.json im Datenverzeichnis gespeichert; beim nächsten Start verbindet sich der Player direkt, ohne Eingabe.

Für den echten Dauerbetrieb -kiosk verwenden (Vollbild, eigener Browserstart) — am einfachsten per deploy/windows/install.ps1 als Autostart.

Vollständiger Ablauf inkl. Freigabe und Layout-Zuweisung: docs/onboarding.md im Server-Repo.

Warum ein eigenes Repo

  • Eigenes Deployable auf fremder Hardware, eigener Release-Zyklus.
  • Wird an Geräte verteilt; soll klein und unabhängig bleiben.
  • Braucht das Admin-Frontend/den Builder nicht — der lebt im Server-Repo.

Geplante Struktur

signagetools-player/
  cmd/agent/          # Einstiegspunkt des Agenten (Go)
  internal/
    sync/             # Manifest ziehen, Hash-Abgleich, Download, atomarer Umschalt
    cache/            # lokaler Medien-/Layout-Cache auf Platte
    kiosk/            # Chromium-Kiosk starten/überwachen (Watchdog)
    api/              # Status-Meldung an Server, Enrollment
  playerui/           # lokal ausgelieferte Player-Seite (rendert das Layout)
  configs/            # Beispiel-Konfiguration (Server-URL, Token-Pfad)

Tech

  • Go — ein statisches Binary, ideal für ARM (Pi) und x86 (Mini-PC).
  • Player-UI: schlankes HTML/JS, das ein gecachtes Manifest rendert.

Ausführen

make build

# Empfohlen: Enrollment-Modus (ohne -screen/-layout).
# Der Agent registriert sich, zeigt einen Kopplungscode auf dem Bildschirm und
# wartet auf Freigabe im Builder unter „Geräte".
./bin/agent -server http://<server>:8080 -addr :4000

# Legacy/ohne Auth: festes Layout oder Screen-Key (kein Token nötig).
./bin/agent -server http://<server>:8080 -screen foyer -addr :4000
./bin/agent -server http://<server>:8080 -layout <LAYOUT_ID> -addr :4000

# Kiosk auf dem Pi zusätzlich:  -kiosk   (startet Chromium auf http://localhost:4000)

Konfiguration auch per Env: SERVER_URL, SCREEN_ID, LAYOUT_ID, PORT, DATA_DIR, POLL_INTERVAL, KIOSK, CHROMIUM_BIN. Cross-Compile für Pi: make build-pi.

Robuster lokaler Player (Laptop/Mini-PC — Windows · Linux · macOS, ohne Docker)

Turnkey-Autostart-Skripte, damit ein Gerät nach dem Einschalten von selbst im Vollbild-Kiosk hochkommt (Auto-Neustart bei Absturz, Browser wird automatisch erkannt — Chrome/Chromium/Edge/Brave). Ein Repo, alle Systeme:

make dist   # native Binaries: dist/sigplayer-<os>-<arch>[.exe]

Einrichten (Server-URL angeben):

# Linux
SERVER_URL=https://signage.example.tld sh deploy/linux/install.sh ./sigplayer-linux-amd64
# macOS
SERVER_URL=https://signage.example.tld sh deploy/macos/install.sh ./sigplayer-macos-arm64
# Windows (PowerShell)
.\deploy\windows\install.ps1 -ServerUrl https://signage.example.tld -Binary .\sigplayer-windows-amd64.exe

Details und die einmaligen OS-Einstellungen (Auto-Login, Ruhezustand aus) siehe deploy/README.md.

Die Geräte-Identität und das Token liegen in DATA_DIR/device.json. Solange ein Token vorhanden ist, läuft der Agent im Gerätemodus und zieht /api/devices/manifest mit Authorization: Bearer <token>.

Der Agent liefert die UI immer aus dem lokalen Cache aus — fällt der Server aus, läuft der Bildschirm mit dem letzten Stand weiter.

Web-Player (Variante A, Docker, headless)

Statt Chromium auf dem Gerät kann der Agent headless in einem Container laufen und die Player-UI unter :4000 ausliefern. Anzeige übernimmt ein beliebiger Browser oder Smart-TV, der die Seite öffnet — der erste Klick/Tap schaltet Vollbild und Ton frei (Autoplay-Videos starten vorher stumm, wie vom Browser verlangt). KIOSK bleibt aus (kein Chromium im Container), DATA_DIR ist ein Volume und hält Cache + Enrollment-Token über Neustarts.

# Bauen und starten (Server-URL angeben):
SERVER_URL=https://signage.example.tld docker compose up -d --build
# Danach im Browser/TV öffnen:  http://<docker-host>:4000

Standardmäßig startet der Container im Enrollment-Modus: die Seite zeigt einen Kopplungscode, den man im Builder unter „Geräte" freigibt. Alternativ SCREEN_ID (zeitlich aufgelöster Zeitplan) oder LAYOUT_ID in der Compose-Datei setzen. Ein fertiges Multi-Arch-Image (amd64/arm64) wird bei jedem v*-Tag in die Forgejo-Registry gepusht (.forgejo/workflows/image.yml, Secret REGISTRY_TOKEN nötig).

Diese Variante wurde gewählt, weil ein reiner Browser-Player den RSS-Ticker (CORS) bräche und den Offline-Platten-Cache verlöre — der Agent im Container behält beides.

Status

Slice 1+2 laufen und sind end-to-end getestet (inkl. Offline-Weiterbetrieb): Manifest ziehen → Medien per Delta (Asset-ID) cachen → lokale UI rendert das Layout und loopt die Playlists. Geräte-Enrollment ist umgesetzt: Pairing per Kopplungscode, Freigabe im Builder, danach Token-authentifizierte Pulls; -screen und -layout bleiben als Modi ohne Authentifizierung erhalten.