Files
ZeasyAlexandClaude Opus 5 5f6301268a Native Windows-Auslieferung statt Container
Docker faellt weg. Das Projekt hat keine npm-Abhaengigkeiten und Node fuehrt
TypeScript direkt aus - der Container schrieb nur noch drei Programme fest,
und dafuer braucht es keine Virtualisierung, sondern einen Ordner.

Der Anlass war, dass ADR-0004 zwar `docker compose pull` versprach, es aber
nie ein veroeffentlichtes Image gab. Wer installieren wollte, musste
whisper.cpp aus dem Quelltext uebersetzen.

Plattformschicht (packages/core/src/platform.ts):
- Programme werden neben der Anwendung gesucht, nicht im PATH
- Daten unter %LOCALAPPDATA%, damit Installation und Update ohne
  Administratorrechte auskommen
- Schriften mitgeliefert: ohne fontsdir setzt libass wortlos eine
  Ersatzschrift ein - gemessen 720 statt 826 Pixel Zeilenbreite

Windows-Eigenheiten, an echtem ffmpeg 8.1 durchprobiert:
- Pfade im Filtergraphen brauchen alle drei Schritte (Vorwaertsschraegstriche,
  escapter Doppelpunkt, Anfuehrungszeichen); je zwei davon reichen nicht
- `nice` gibt es nicht, ersetzt durch os.setPriority

Auslieferung:
- scripts/build-package.ts baut das Paket, laeuft auch unter Linux
- install.ps1 ohne Administratorrechte, Autostart ueber den Aufgabenplaner
- update legt neue Fassungen bereit; eingespielt wird beim naechsten Start,
  nie mitten im Stream
- ZIP lesen und schreiben ohne Abhaengigkeiten (packages/core/src/zip.ts)

Kein `irm ... | iex`-Einzeiler: git.zeasy.dev antwortete instanzweit mit einer
Umleitung auf /user/login, und `iex` fuehrte die Anmeldeseite als PowerShell
aus. Der Updater verfolgt Umleitungen jetzt nicht und hat keine erfundene
Vorgabeadresse mehr.

Ausserdem: backup.ps1 war an zwei Stellen dokumentiert, aber nie geschrieben.

ADR-0007 ersetzt ADR-0004. 84 Tests, Typpruefung sauber.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AhVSfMFdWnXKCv5JfLnArZ
2026-09-09 17:39:26 +02:00

136 lines
6.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# OBS-Layout — die Vorgabe
**Kurzfassung für Abdu:** Facecam **480×270** bündig oben links. Chat und
Alerts erst ab **x = 1405**. Der Streifen dazwischen bleibt frei.
![Ausrichtungsvorlage](assets/obs-layout-vorlage.png)
## Warum überhaupt eine Vorgabe
Der Zuschnitt auf 9:16 nimmt feste Bildbereiche aus dem fertigen Streambild.
Verrutscht die Kamera um 50 Pixel, sitzt in jedem Short der Kopf schief — und
das merkt man erst, wenn der Clip fertig ist.
Ein Vergleich zweier Aufnahmen hat gezeigt, dass die Kamera derzeit von Stream
zu Stream unterschiedlich liegt. Statt das nachzumessen, steht die Position
jetzt fest. Einmal einrichten, danach passt jeder Clip.
## Die Zahlen
| Element | Position | Größe |
|---|---|---|
| **Facecam** | x 0, y 0 (bündig oben links) | **480 × 270** |
| **Gameplay-Band** | x 515 bis 1405 | 890 × 1080 |
| **Chat, Alerts, Overlays** | ab x 1405 | 515 px Spalte |
| **Minimap, HUD, Kacheln** | x 0 bis 515, unterhalb der Kamera | frei |
Zwischen Kamera (endet bei 480) und Gameplay-Band (beginnt bei 515) liegen
35 Pixel Luft. Der Abstand ist Absicht: Ein leicht verrutschter Kamerarahmen
schiebt dann nicht sofort einen Streifen Gesicht in das Gameplay-Bild.
## So richtest du es ein
1. **Vorlage laden.** In OBS eine **Bild-Quelle** anlegen, Datei
`docs/assets/obs-layout-vorlage.png`, und sie in der Quellenliste **ganz
nach oben** ziehen. Größe auf 1920×1080, Position 0,0.
2. **Deckkraft runter.** Rechtsklick auf die Quelle → Filter → *Farbkorrektur*
→ Deckkraft ca. 60 %. Dann sieht man die eigenen Quellen darunter.
3. **Facecam ziehen**, bis sie den grünen Rahmen ausfüllt. Beim Skalieren
`Shift` **nicht** gedrückt halten — das Seitenverhältnis muss 16:9 bleiben,
die Kamera darf nicht verzerrt werden.
> Steht die Kamera in OBS als 4:3 (z. B. 640×480), vorher in den
> Kameraeinstellungen auf eine 16:9-Auflösung umstellen (1280×720 oder
> 1920×1080). Ein 4:3-Bild in einen 16:9-Rahmen zu ziehen staucht das
> Gesicht.
4. **Chat-Overlay und Alerts** nach rechts schieben, sodass sie komplett
rechts der orangen Linie liegen.
5. **Alles andere** (Minimap gehört zum Spiel, Kacheln, Sub-Ziel) nach links
unten oder in die rechte Spalte — nur nicht in den cyanen Bereich.
6. **Vorlage ausblenden** (Auge anklicken). Nicht löschen: beim nächsten
Layout-Umbau ist sie wieder da.
## Prüfen
```powershell
abdulive calibrate
```
Nimmt das neueste Video aus dem Wiedergabepuffer-Ordner und legt drei Bilder
unter `%LOCALAPPDATA%\abdulive\clips\_calibration` ab: das Einzelbild, dasselbe mit eingezeichneten
Ausschnitten, und die fertige 9:16-Vorschau. Sitzt in der Vorschau der Kopf
mittig und ist im Gameplay-Teil kein Chat zu sehen, stimmt das Layout.
## Text im Bild — hier wird es eng
**Wer malt den Text?** Das ist nicht zu erraten — die Overlays sind ins
Streambild eingebrannt, man muss nachsehen, welche OBS-Quelle sie zeichnet:
```powershell
abdulive sources
```
Der Befehl fragt das laufende OBS und listet jede Quelle der aktuellen Szene
mit Position, Größe und dem Urteil, ob sie im 9:16-Ausschnitt landet. Bei
Browser-Quellen steht die Adresse dabei — daran erkennt man den Dienst
dahinter. Was nach Untertiteln aussieht, wird am Ende noch einmal
zusammengefasst.
Dafür muss in OBS **Werkzeuge → WebSocket-Server-Einstellungen → Server
aktivieren** gesetzt sein (Port 4455) und das Passwort unter `/setup` liegen.
Bei der Prüfung eines echten Clips lagen **drei Textebenen übereinander**:
1. die Untertitel des Spiels („Genau, ich mach da … sag zu dem Typen")
2. ein **Live-Caption-Overlay** mit lila Wort-Markierung („Okay FIFA **Es**")
3. dazu käme der Untertitel, den das Toolkit für das Short erzeugt
Das ist eine Ebene zu viel — und die ersten beiden sind fest ins Streambild
eingebrannt, lassen sich also nachträglich nicht entfernen.
**Spieluntertitel: aus.** Sie laufen über die volle Bildbreite, werden vom
Ausschnitt rechts angeschnitten und bringen im Short nichts.
**Live-Captions: verschieben, nicht abschalten.** Für Zuschauer im Stream sind
sie wertvoll, gerade für Leute, die ohne Ton mitlesen. Sie müssen nur aus dem
cyanen Band heraus. Zwei brauchbare Plätze:
| Ort | Vorteil | Nachteil |
|---|---|---|
| **unten links**, x 0 bis 515, zweizeilig | bleibt live sichtbar, stört das Short nicht | schmaler, also mehr Zeilenumbrüche |
| **rechte Spalte** unter dem Chat, ab x 1405 | viel Platz | konkurriert mit dem Chat um Aufmerksamkeit |
Ganz abschalten geht auch — dann haben nur die Shorts Untertitel. Das ist eine
Entscheidung für den Stream, nicht fürs Toolkit; beides funktioniert.
Ein **HUD am rechten Rand** (Killfeed, Inventar) ist im Short nicht zu sehen.
Wo das stört, bekommt das Spiel ein eigenes Profil in
[`config/layout.yaml`](../config/layout.yaml).
## Was das Ergebnis begrenzt — und wie man es hebt
Das Short entsteht aus dem **fertig zusammengesetzten Streambild**. Die Kamera
ist darin 480 Pixel breit und wird für das Hochformat auf 1080 vergrößert, also
um Faktor 2,25. Das sieht weicher aus als das Original. Genauso das Gameplay,
Faktor 1,21 — das fällt kaum auf.
Wer schärfer will, braucht eine zweite Bildquelle statt eines Zuschnitts:
| Weg | Aufwand | Ergebnis |
|---|---|---|
| Zuschnitt aus dem Streambild (heute) | keiner | brauchbar, leicht weich |
| OBS-Plugin **Source Record** — Kamera zusätzlich einzeln aufnehmen | Plugin installieren, eine Quelle konfigurieren | Kamera in voller Auflösung, Zusammensetzen aus zwei Dateien |
| OBS-Plugin **Aitum Vertical** — echte zweite Leinwand 1080×1920 | Plugin plus eigene Szene | bestes Ergebnis, kein Zuschnitt nötig |
Das ist eine Aufgabe für nach dem MVP. Der Zuschnitt reicht, um anzufangen —
und ohne Clips, die überhaupt entstehen, bringt die beste Bildqualität nichts.
## Wenn das Layout sich doch ändert
`config/layout.yaml` kennt mehrere Profile. Das Profil `bestand-2026-09` hält
fest, wie es vor der Vorgabe aussah — damit lassen sich alte Aufnahmen noch
korrekt rendern:
```powershell
abdulive render <datei> bestand-2026-09
```