213 lines
4.9 KiB
Markdown
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
|