From f11bd4f6c488f5675547bb977ccfc4e5f58ec464 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesko=20Ansch=C3=BCtz?= Date: Mon, 23 Mar 2026 10:50:17 +0100 Subject: [PATCH] Bugfixes: Player-UI Content-Rendering, Backend-URL Dev-Display, MIME-Type-Erkennung MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Player-UI: Content-Type-Handling (image/video/web statt alles-iframe), Fast-Retry-Polling beim Start, Splash wird korrekt ausgeblendet, Fallback-Anzeige bei X-Frame-Options-Blockade - Dev-Display: Backend-URL auf 192.168.64.1 für Multipass-Netz korrigiert - Media-Upload: Typ wird aus MIME-Type abgeleitet statt blind aus Formular - TODO: Daten-Bug dokumentiert Co-Authored-By: Claude Opus 4.6 --- TODO.md | 1 + ansible/host_vars/info01-dev/vars.yml | 1 + player/agent/internal/playerserver/server.go | 191 ++++++++++++++++-- .../backend/internal/httpapi/manage/media.go | 18 ++ 4 files changed, 194 insertions(+), 17 deletions(-) diff --git a/TODO.md b/TODO.md index f1e64f7..7d377ab 100644 --- a/TODO.md +++ b/TODO.md @@ -74,6 +74,7 @@ - [x] Minimalen Player-Agent-Prototyp bauen - [x] Minimale Player-UI bauen - [ ] Lokale Test-Playlist mit Bild, Video, PDF und Webseite anlegen +- [ ] **BUG**: Datei `120papag.mpg` ist als `type: image` gespeichert, muss `type: video` sein – Player-UI versucht ``-Laden, was fehlschlägt - [x] Fallback-Verzeichnisbetrieb demonstrieren - [ ] `valid_from`/`valid_until` im Prototyp pruefen - [x] Offline-Sync mit lokalem Cache pruefen diff --git a/ansible/host_vars/info01-dev/vars.yml b/ansible/host_vars/info01-dev/vars.yml index 5dd1baa..d9b9cc1 100644 --- a/ansible/host_vars/info01-dev/vars.yml +++ b/ansible/host_vars/info01-dev/vars.yml @@ -4,3 +4,4 @@ ansible_user: admin screen_id: info01-dev screen_name: "Info01 Entwicklung" screen_orientation: landscape +morz_server_base_url: "http://192.168.64.1:8080" diff --git a/player/agent/internal/playerserver/server.go b/player/agent/internal/playerserver/server.go index 10180d1..ddba4a6 100644 --- a/player/agent/internal/playerserver/server.go +++ b/player/agent/internal/playerserver/server.go @@ -187,12 +187,37 @@ const playerHTML = ` font-weight: 500; letter-spacing: 0.03em; color: #fff; } - /* Inhalts-iframe */ - #frame { + /* Inhalts-Elemente: iframe, img, video */ + #frame, #img-view, #video-view { position: fixed; inset: 0; width: 100%; height: 100%; border: none; display: none; z-index: 10; } + #img-view { + object-fit: contain; + background: #000; + } + #video-view { + object-fit: contain; + background: #000; + } + + /* Fehler-Fallback für blockierte iframes */ + #frame-error { + position: fixed; inset: 0; + width: 100%; height: 100%; + display: none; z-index: 10; + background: #000; + align-items: center; justify-content: center; flex-direction: column; + gap: 1rem; + } + #frame-error .error-title { + font-family: sans-serif; font-size: 2rem; color: rgba(255,255,255,0.7); + text-align: center; padding: 0 10%; + } + #frame-error .error-hint { + font-family: sans-serif; font-size: 1rem; color: rgba(255,255,255,0.35); + } /* Verbindungsstatus-Punkt */ #dot { @@ -210,13 +235,23 @@ const playerHTML = `
+ + +
+ + Seite kann nicht eingebettet werden +
` diff --git a/server/backend/internal/httpapi/manage/media.go b/server/backend/internal/httpapi/manage/media.go index 4f890b7..e90f4cd 100644 --- a/server/backend/internal/httpapi/manage/media.go +++ b/server/backend/internal/httpapi/manage/media.go @@ -83,6 +83,9 @@ func HandleUploadMedia(tenants *store.TenantStore, media *store.MediaStore, uplo defer file.Close() mimeType := header.Header.Get("Content-Type") + if detectedType := mimeToAssetType(mimeType); detectedType != "" { + assetType = detectedType + } if title == "" { title = strings.TrimSuffix(header.Filename, filepath.Ext(header.Filename)) } @@ -149,6 +152,21 @@ func HandleDeleteMedia(media *store.MediaStore, uploadDir string) http.HandlerFu } } +// mimeToAssetType leitet den Asset-Typ aus dem MIME-Type ab. +func mimeToAssetType(mime string) string { + mime = strings.ToLower(strings.TrimSpace(mime)) + switch { + case strings.HasPrefix(mime, "image/"): + return "image" + case strings.HasPrefix(mime, "video/"): + return "video" + case mime == "application/pdf": + return "pdf" + default: + return "" + } +} + func sanitize(s string) string { var b strings.Builder for _, r := range s {