362e089be0beac781914a660af235826a0e11426
5 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
02765e6b34 |
CUE-SZENENLISTE PRO LAYER + macOS-SUPPORT (35/35 E2E, 123 Checks gesamt)
1) Cue-/Szenenliste JE Layer (35/35 E2E): - Cue sichern = Snapshot (Quelle, Alpha, Position, Groesse, Z-Order, FX1/FX2 + Intensitaeten); Name + fade_ms + follow_ms pro Cue - GO vor/zurueck (steps), Goto (Index), Wrap-around am Listenende - FADE: Quellwechsel = dip-to-black (Phase1 runter, Wechsel bei 0, Phase2 hoch; E2E: alpha 0.49 -> 0.32 -> Ziel 0.8), sonst sanfter Tween von Alpha + FX-Intensitaeten; laufende Fades abbrechbar - AUTO-FOLLOW: follow_ms schaltet nach Ablauf automatisch weiter (E2E: Cue mit 600ms -> Wrap zum naechsten) - DMX CUE-GO: cue_go_channel (Settings + UI), steigende Flanke >=128 = GO auf allen Layern; ohne Flanke kein GO (E2E: 0->1, 1==1 bei High-Halten, neue Flanke 1->0); Sequenzfilter aktiv - Cue-Entfernen mit Indexkorrektur; Cues in Projekten speicher-/ladbar (3 Cues nach Projekt-Load erhalten) - UI: Cue-Bereich je Layer (Cue sichern / GO / Zurueck / Goto / Loeschen, aktiver Cue markiert, Fade+Follow-Anzeige) - Fehlerfaelle: unbekannter Layer 400, fehlendes Medium 400, unbekannter Generator 400 2) macOS (Apple Silicon + Intel) mit Skript: - setup_macos.sh: Homebrew installiert python@3.12, python-tk, GStreamer + alle Plugin-Sets + PyGObject; Apple-Silicon-PATH- Hinweis (/opt/homebrew); Erklaerung warum Homebrew statt gstreamer-.pkg (keine PyGObject-Bindings in .pkg) - Bootstrap (--bootstrap): darwin-Zweig mit brew-Installationspfad - run.py --generate-setup erzeugt jetzt 3 Skripte (Windows .ps1 / Linux .sh / macOS .sh); Bash-Syntax geprueft 3) Gefundene + behobene FEHLER: - WEB-UI-ABSTURZ (echter JS-Ternary-Klammerfehler in loadServers, seit Verteilungs-Commit unentdeckt, weil API-Tests den Browser- Code nie parsen): Klammerstruktur korrigiert + JS-Syntax nun per node --check verifizierbar (Syntax OK) + Remote-Buttons robust per data-Attribute (kein Quote-Escaping mehr) - update_layer blockierte Quellwechsel Video->Generator (Cues brauchen beides): Name entscheidet jetzt den Typ, Wechsel in beide Richtungen - Cue-E2E-Timing: dip-to-black hat 2 Phasen (Pruefung 0.2s/0.6s), Auto-Follow-Index-Fix, Art-Net-Sequenznummern im Test inkrementierend (Sequenzfilter verwirft Duplikate korrekt) E2E-Bilanz: Cue 35/35 + Regressionen Projekte 25/25, Verteilung 33/33, App 14/14, FX 16/16 = 123 Checks gruen |
||
|
|
7e191ff6c9 |
GENERATOREN + MEDIEN-VERTEILUNG + AUTOSTART-SETTINGS (33/33 E2E)
1) MADRIX-artige Generator-Layer (15 prozedurale Quellen): - engine.GENERATORS: ball (animiert), gradient, pinwheel (animiert), zone-plate (animiert), checkers, snow (Rauschen animiert), circular, spokes, smpte, gamut, red/green/blue/black/white - alle per gst-launch verifiziert, kombinierbar mit FX1/FX2 (Generator+FX gerendert, 28 Frames im Test) - add_generator + Pattern-Wechsel zur Laufzeit (ball->snow) mit Rebuild, Katalog-Endpoint /api/generators, UI-Dropdown im Layer-Tab - Generatoren in Projekten speicher-/ladbar (gradient nach Load aktiv) - Ungueltige Generator-IDs werden mit 400 abgewiesen 2) Medien-Verteilung ueber mehrere Server: - hms_app/distribution.py: Server-Check (/api/health), Remote-Medien-Liste, Streaming-Import mit Upload-Sicherung - config.servers: Remote-Server registrieren (Name+URL, HTTP-only, Duplikat-Schutz), /api/servers (online/offline + Medien), servers/import: Datei von Remote ins lokale Archiv ziehen - UI: Remote-Server in Einstellungen verwalten, Remote-Medien im Medien-Tab mit 'Ins Archiv ziehen'-Button - run.py --data-root: mehrere Instanzen auf einer Maschine mit getrennten config/media/projects-Ordnern - E2E mit ZWEI echten Servern: A registriert B, sieht B-Medien, zieht clip byte-identisch (SHA verifiziert) und spielt ihn als Layer; Offline-Erkennung nach B-Stop; 404/400-Faelle 3) Autostart in den Einstellungen: - Einstellungen: Autostart-Projekt-Dropdown (aus Projektliste), abwaehlbar; Projekte-Tab weiterhin mit Autostart-Button - FIX Settings-Save-Merge: POST /api/settings merged jetzt auf die AKTUELLEN Settings - Autostart und registrierte Server gehen beim Speichern anderer Einstellungen nicht mehr verloren (E2E: Autostart ueberlebt Settings-Save, FPS uebernommen) E2E: 33/33 PASS (Verteilung/Generatoren) + Regressionen: Projekte 25/25, App 14/14, FX 16/16 - alle gruen |
||
|
|
70502458d8 |
PROJEKTE: Speichern/Laden/Autostart (25/25 E2E inkl. Server-Neustart)
- hms_app/projects.py: ProjectStore mit atomarem Speichern (.hms.json in projects/), Format-Kennung, Namens-Sanitize (Pfad-Traversal-Schutz, Leerzeichen erlaubt), Liste/Loeschen - engine.py: export_state() (Layer mit Alpha/Pos/Groesse/Z/FX + Intensitaeten + Master) und load_state() (ersetzt alle Layer, fehlende Medien werden uebersprungen und gemeldet, Werte geclamped, ungueltige FX-IDs verworfen) - server.py: /api/projects (GET Liste + Autostart), POST projects/save|load|delete|autostart; Loeschen des Autostart-Projekts raeumt config.json automatisch auf - config.py: engine.autostart_project (validiert, optional) - run.py: laedt Autostart-Projekt beim Programmstart - ui.py: neuer Reiter 'Projekte': Name eingeben + Speichern, Tabelle mit Laden/Autostart/Loeschen, Autostart-Badge E2E-BEWEIS (25/25 PASS, mit ECHTEM Server-Neustart): 1 Server startet · 2 Upload · 3 Layer · 4 FX/Alpha/Pos gesetzt · 5 Projekt 'Show A' gespeichert · 6 Traversal-Name sanitizet zu 'evil' · 7 Liste · 8 Layerzahl · 9 Zustand geleert (master=0.1) · 10 Projekt geladen · 11 Layer wiederhergestellt · 12 Alpha 0.7 wiederhergestellt · 13 FX1 blur 0.8 wiederhergestellt · 14 Position x=50 y=20 wiederhergestellt · 15 Master 0.9 · 16 Engine rendert · 17 Autostart gesetzt · 18 Server NEU GESTARTET · 19 Autostart: Layer+FX automatisch geladen · 20 Autostart: Engine rendert (60 Frames) · 21 config.json Autostart · 22 fehlendes Projekt 404 · 23 geloescht · 24 Autostart automatisch geleert · 25 config.json geleert Regressionen: App-E2E 14/14 (app=0) + FX-E2E 16/16 (fx=0) unveraendert gruen |
||
|
|
10b988c33a |
EFFECTS LIVE: 21 Effekte in der Pipeline (FX1/FX2 je Layer, 16/16 E2E)
Echte GPU-nahe GStreamer-Effekte, zur Laufzeit pro Layer schaltbar: - FX_CATALOG: 21 verfuegbare Effekte (gst-inspect verifiziert): blur, sharpen, color, contrast, brightness, gamma, pixelate, solarize, vertigo, edge, ripple, radioactv, revtv, quark, op, burn, dilate, warp, streak, aging, exclusion - FX1 + FX2 pro Layer (Kette: videoconvert ! FX1 ! videoconvert ! FX2 ! videoconvert - Muster gegen gst-launch verifiziert) - Intensitaet je FX live regelbar OHNE Rebuild (Property-Update direkt am Element, Frames laufen weiter 118->120) - Strukturwechsel (FX waehlen/entfernen) -> atomarer Rebuild mit Rollback; Intensitaeten werden auf neue Pipeline uebertragen - DMX: fx1_channel/fx2_channel optional konfigurierbar -> steuert FX-Intensitaet live (E2E: Kanal 20 = 255 -> Intensitaet 1.0) - UI: Layer-Editor mit FX1/FX2-Dropdown (Katalog via /api/fx) + Intensitaets-Slider je FX - /api/fx: Effekt-Katalog mit Label/Bereich fuer die UI - config.py: fx1_channel/fx2_channel in Validierung (optional, 1-512) - Ungueltige FX-IDs werden abgewiesen (fallback None) E2E-BEWEIS (16/16 PASS, im Container): 1 Health · 2 Katalog 21 Effekte · 3-8 alle Kern-FX enthalten · 9 Layer · 10 FX1 blur -> Rebuild laeuft (118 Frames) · 11 Intensitaet live ohne Ruckler · 12 FX2 color dazu (161 Frames) · 13 FX entfernen ok (180 Frames) · 14 fx1_channel konfiguriert · 15 DMX steuert FX-Intensitaet auf 1.0 · 16 ungueltiger FX abgewiesen Regression: kompletter App-E2E weiterhin 14/14 PASS (app=0 fx=0) |
||
|
|
68ce87e5ac |
ECHTES PROGRAMM: Medienverwaltung + Upload + konfigurierbares Art-Net (14/14 E2E bestanden)
Vollständige Anwendung in hms_app/ (6 Module) + schlanker run.py: - config.py: config.json-Persistenz, Defaults, strikte Validierung (Bereiche, Universes, Kanal-Mapping; ungültige Settings => 400) - media.py: Upload-Streaming (chunkweise, Größenlimit, .part-Sicherung), Duplikat-Umbenennung, Thumbnail-Erzeugung per GStreamer, Metadaten-Cache (Dauer via query_duration), Löschen, Pfad-Schutz - artnet.py: ArtDMX voll KONFIGURIERBAR (Port, Universes, Kanäle), Sequenz-/Duplikat-Filter, Signalverlust-Policy hold/fade_black, Watchdog, Live-Restart nach Settings-Änderung - engine.py: dynamische Layer (Video + Bild via imagefreeze), atomarer Rebuild mit Rollback (alte Pipeline läuft bei Fehler weiter), Positions/Größen/Z-Order/Alpha je Layer, EOS-Loop, DMX-Mapping - server.py: REST komplett (upload/delete, layers add/remove/update, master/blackout/playback, settings GET/POST mit Validierung), Thumbnails + Datei-Download, Traversal-Schutz - ui.py: 4-Tabs-WebUI: Live (Preview+Slider+Diagnose), Medien (Drag&Drop-Upload mit Fortschritt, Thumbnails, Als-Layer/Delete), Layer-Editor (Alpha/Pos/Größe/Z), Einstellungen (Art-Net komplett umstellbar inkl. Port/Universes/Kanäle, Preview, Engine, Upload-Limit) - setup.py: Bootstrap + setup_windows.ps1/setup_linux.sh Generierung - run.py: Einstieg (--port, --setup, --bootstrap, --generate-setup, Datei-Import via CLI) E2E-BEWEIS (14/14 PASS, im Container ausgeführt): 1 Health OK · 2 Video-Upload via HTTP · 3 Bild-Upload · 4 Bibliothek mit Metadaten (Video-Dauer erkannt) · 5 Thumbnail JPEG · 6 Traversal-Schutz (404) · 7/8 Layer Video+Bild dynamisch · 9 Engine rendert (91 Frames) · 10 Art-Net live auf Port 6455 mit Master-Kanal 10 umgestellt · 11 DMX steuert Master 0.251 auf NEUEM Port/Kanal · 12 Layer-Alpha via DMX · 13 config.json persistiert · 14 Layer-Remove ohne Absturz (258 Frames, atomar) · Ungültige Settings werden mit 400 + Feldname abgewiesen Fixes: Bild-Caps kombiniert (parse-Fehler), Thumbnail-Namens-Mapping, kind_of-Methode, atomarer Rebuild mit Rollback, DMX-accepted-Zähler |