morz-infoboard/docs/LAYOUT-JSON.md

213 lines
4.9 KiB
Markdown

# Info-Board Neu - `layout_json` fuer `message_wall`
## Ziel
Dieses Dokument definiert das `layout_json` fuer `message_wall` verbindlich fuer v1.
Es beschreibt nicht die eigentliche Mediendatei, sondern die serverseitige Segmentlogik, mit der aus einem Gesamtmotiv konkrete Screen-Szenen erzeugt werden.
## Grundentscheidung fuer v1
- `message_wall` wird serverseitig aufgeloest
- der Player bekommt nur fertige Screen-Szenen
- `layout_json` wird vom Backend oder Worker interpretiert
- der Player berechnet keine Ausschnitte ueber mehrere Displays hinweg
## V1-Modell
Das `layout_json` beschreibt ein virtuelles Gesamtkoordinatensystem und eine Menge von Slots.
Jeder Slot repraesentiert einen Zielbereich im Gesamtmotiv.
## Struktur
```json
{
"version": 1,
"coordinate_space": {
"width": 300,
"height": 300,
"unit": "grid"
},
"fit_mode": "cover",
"slots": [
{
"slot_id": "wall-r1-c1",
"x": 0,
"y": 0,
"width": 100,
"height": 100
},
{
"slot_id": "wall-r1-c2",
"x": 100,
"y": 0,
"width": 100,
"height": 100
}
]
}
```
## Felder
### `version`
- aktuell fest `1`
- erlaubt spaetere Weiterentwicklung ohne uneindeutiges Parsing
### `coordinate_space`
Definiert den virtuellen Gesamtraum.
Felder:
- `width`
- `height`
- `unit`
Fuer v1 gilt:
- `unit` ist immer `grid`
- `width` und `height` sind positive Ganzzahlen
Interpretation:
- das Gesamtmotiv wird in diesem virtuellen Raum beschrieben
- Slots schneiden daraus Teilbereiche aus
### `fit_mode`
Definiert, wie das Ausgangsmedium auf den virtuellen Gesamtraum bezogen wird.
Zulaessige Werte fuer v1:
- `cover`
- `contain`
V1-Standard:
- `cover`
Interpretation:
- `cover`: das Motiv fuellt den Gesamtraum vollstaendig, mit moeglichem Beschnitt
- `contain`: das Motiv bleibt vollstaendig sichtbar, mit moeglichen Randflaechen
### `slots`
Liste aller Zielslots innerhalb des virtuellen Gesamtraums.
Jeder Slot hat:
- `slot_id`
- `x`
- `y`
- `width`
- `height`
Regeln:
- `slot_id` ist innerhalb eines Layouts eindeutig
- `x`, `y`, `width`, `height` sind Ganzzahlen im virtuellen Koordinatensystem
- `width > 0` und `height > 0`
- Slots duerfen sich in v1 nicht ueberlappen
- Slots muessen vollstaendig innerhalb des `coordinate_space` liegen
## Semantik
Ein Slot beschreibt den Ausschnitt, den ein bestimmter Screen spaeter bekommt.
Das Backend oder der Worker erzeugt daraus pro Zielscreen eine konkrete Scene mit:
- Zielscreen oder Zielslot
- Originalmedium
- berechnetem Crop-Bereich
- Dauer, Timeout und Fehlerverhalten
## Beispiel 3x3-Infowand
```json
{
"version": 1,
"coordinate_space": {
"width": 300,
"height": 300,
"unit": "grid"
},
"fit_mode": "cover",
"slots": [
{ "slot_id": "wall-r1-c1", "x": 0, "y": 0, "width": 100, "height": 100 },
{ "slot_id": "wall-r1-c2", "x": 100, "y": 0, "width": 100, "height": 100 },
{ "slot_id": "wall-r1-c3", "x": 200, "y": 0, "width": 100, "height": 100 },
{ "slot_id": "wall-r2-c1", "x": 0, "y": 100, "width": 100, "height": 100 },
{ "slot_id": "wall-r2-c2", "x": 100, "y": 100, "width": 100, "height": 100 },
{ "slot_id": "wall-r2-c3", "x": 200, "y": 100, "width": 100, "height": 100 },
{ "slot_id": "wall-r3-c1", "x": 0, "y": 200, "width": 100, "height": 100 },
{ "slot_id": "wall-r3-c2", "x": 100, "y": 200, "width": 100, "height": 100 },
{ "slot_id": "wall-r3-c3", "x": 200, "y": 200, "width": 100, "height": 100 }
]
}
```
## Ergebnis der serverseitigen Aufloesung
Aus einem `message_wall`-Template mit diesem `layout_json` entstehen konkrete Screen-Szenen.
Jede resultierende Szene enthaelt fachlich mindestens:
- `slot_id`
- `src`
- `crop`
- `fit_mode`
- `duration_seconds`
- `load_timeout_seconds`
- `on_error`
Der `crop` beschreibt dann genau den Ausschnitt fuer diesen Slot.
## Warum Grid statt Pixel?
Fuer v1 wird absichtlich ein abstrahiertes Grid-Modell verwendet.
Vorteile:
- leicht lesbar und dokumentierbar
- unabhaengiger von konkreten Asset-Abmessungen
- einfach im Backend validierbar
- gut fuer Admin-Vorschau und Segmentlogik
Pixelgenaue Berechnung kann spaeter intern aus dem Grid abgeleitet werden.
## Validierungsregeln fuer das Backend
Das Backend oder der Worker muss mindestens pruefen:
- `version == 1`
- `coordinate_space.width > 0`
- `coordinate_space.height > 0`
- `unit == grid`
- `fit_mode` ist erlaubt
- keine doppelten `slot_id`
- keine Slots ausserhalb des Gesamtraums
- keine ueberlappenden Slots
## V1-Abgrenzung
Nicht Teil von v1:
- rotierte Slots
- verschachtelte Layouts
- freie Polygonformen
- playerseitige Segmentlogik
- automatische Textsatz-Engine im Layout selbst
## Bezug zur Implementierung
Die erste Backend-Implementierung soll aus diesem `layout_json` eine Liste konkreter Screen-Szenen ableiten koennen.
Dabei gilt:
- das Input-Modell bleibt bewusst einfach
- die Aufloesung ist serverseitige Fachlogik
- der Player bekommt nur bereits aufgeloeste Einzelinhalte