Aus #156, Durchgang 6. Fund in #405, Abschluss 4371 („Betrifft nur das Vorschaubild, nicht angefasst“).
Befund
Das Posterbild, das der Worker zu jedem hochgeladenen Video schneidet, ist farblich daneben. Gemessen beim Bau von #405: Ein Rot mit 255 im Video kommt im Poster-JPEG als 229 heraus. Das Video selbst ist richtig, in Chrome dekodiert Rot ≥ 245.
Sichtbar ist das Poster nur im Video-Picker (src/editor/video/VideoPicker.ts:57). Die Szene, die PREVIEW und das Spiel zeigen das Video, nicht das Poster.
Vermutete Ursache (gerechnet, nicht gegengeprüft)
VideoFormat::posterArgs (api/lib/VideoFormat.php:136) schneidet mit -vf scale=320:-2 und nennt keine Farbmatrix.
Die MP4 ist BT.709 (die Aufnahme aus #405 schreibt das in die Datei, ffprobe zeigt es nach der Umwandlung). ffmpeg übernimmt die Y'CbCr-Werte unverändert ins JPEG, ein JPEG wird aber immer mit BT.601 gelesen.
Gerechnet: reines Rot in BT.709, mit BT.601 zurückgerechnet, ergibt rund 233. Mit der JPEG-Kompression passt das zu den gemessenen 229.
Vorschlag
Beim Poster die Matrix ausdrücklich umrechnen: scale=320:-2:in_color_matrix=bt709:out_color_matrix=bt601:out_range=full. Die Eingangsmatrix kommt aus ffprobe (color_space). Was ohne Angabe gelten soll, ist Frage 2.
Bestehende Poster bleiben, wie sie sind. Neu geschnitten werden sie nur, wenn ein Video neu hochgeladen wird.
Offen (mit Vorschlag)
Alte Poster nachziehen? Vorschlag: nein. Es geht nur um das kleine Bild im Picker.
Video ohne Farbangabe: Vorschlag: BT.709 ab 720 px Höhe, darunter BT.601 (übliche Faustregel). Was Chrome in diesem Fall annimmt, ist nicht gemessen. Das gehört beim Bau mit einem Testvideo ohne Angabe geprüft.
Fertig, wenn
PHP-Test videos.test.php (Worker-Image, echtes ffmpeg): Ein Testvideo mit reinem Rot ergibt ein Poster mit Rot ≥ 245. Gegenprobe mit den alten Argumenten: unter 235.
Aus #156, Durchgang 6. Fund in #405, Abschluss 4371 („Betrifft nur das Vorschaubild, nicht angefasst“).
## Befund
- Das Posterbild, das der Worker zu jedem hochgeladenen Video schneidet, ist farblich daneben. Gemessen beim Bau von #405: Ein Rot mit 255 im Video kommt im Poster-JPEG als **229** heraus. Das Video selbst ist richtig, in Chrome dekodiert Rot ≥ 245.
- Sichtbar ist das Poster nur im Video-Picker (`src/editor/video/VideoPicker.ts:57`). Die Szene, die PREVIEW und das Spiel zeigen das Video, nicht das Poster.
## Vermutete Ursache (gerechnet, nicht gegengeprüft)
- `VideoFormat::posterArgs` (`api/lib/VideoFormat.php:136`) schneidet mit `-vf scale=320:-2` und nennt keine Farbmatrix.
- Die MP4 ist BT.709 (die Aufnahme aus #405 schreibt das in die Datei, ffprobe zeigt es nach der Umwandlung). ffmpeg übernimmt die Y'CbCr-Werte unverändert ins JPEG, ein JPEG wird aber immer mit BT.601 gelesen.
- Gerechnet: reines Rot in BT.709, mit BT.601 zurückgerechnet, ergibt rund 233. Mit der JPEG-Kompression passt das zu den gemessenen 229.
## Vorschlag
- Beim Poster die Matrix ausdrücklich umrechnen: `scale=320:-2:in_color_matrix=bt709:out_color_matrix=bt601:out_range=full`. Die Eingangsmatrix kommt aus ffprobe (`color_space`). Was ohne Angabe gelten soll, ist Frage 2.
- Bestehende Poster bleiben, wie sie sind. Neu geschnitten werden sie nur, wenn ein Video neu hochgeladen wird.
## Offen (mit Vorschlag)
1. **Alte Poster nachziehen?** Vorschlag: **nein.** Es geht nur um das kleine Bild im Picker.
2. **Video ohne Farbangabe:** Vorschlag: BT.709 ab 720 px Höhe, darunter BT.601 (übliche Faustregel). Was Chrome in diesem Fall annimmt, ist nicht gemessen. Das gehört beim Bau mit einem Testvideo ohne Angabe geprüft.
## Fertig, wenn
- PHP-Test `videos.test.php` (Worker-Image, echtes ffmpeg): Ein Testvideo mit reinem Rot ergibt ein Poster mit Rot ≥ 245. Gegenprobe mit den alten Argumenten: unter 235.
meleki
added the new label 2026-10-11 21:24:18 +02:00
Commits: Repo 31ce648 „Give video posters the colours the video shows (#411)“, Wiki 7b29263 „Videos: posters keep the colours of the video (#411)“.
Was gebaut ist
VideoFormat::colour($probe) (neu) liest Matrix und Range aus der fertigen MP4. Der Worker probt dafür die umgewandelte Datei, nicht das Original.
VideoFormat::posterArgs rechnet das Poster ausdrücklich von dieser Matrix nach BT.601 Full Range um: scale=320:-2:in_color_matrix=…:in_range=…:out_color_matrix=bt601:out_range=pc:flags=accurate_rnd+full_chroma_int. Ohne accurate_rnd+full_chroma_int landen dunkle Grautöne rund zwei Stufen zu tief.
Die Suche nach dem ersten bewegten Video-Strom ist ein gemeinsamer Helfer für plan und colour.
Wiki Videos: neuer Absatz zu den Poster-Farben.
Frage 2: Video ohne Farbangabe (gemessen)
In Chromium mit einem roten H.264-Video ohne Farb-Tags gemessen (VideoFrame.colorSpace.matrix): ab 720 Zeilen BT.709, darunter BT.601 (smpte170m bei 640x360). Das ist genau die Faustregel aus dem Vorschlag, colour() folgt ihr.
Frage 1: alte Poster
Bleiben wie besprochen, wie sie sind.
Tests
videos.test.php im Worker-Image (echtes ffmpeg): ALL PASSED, 90 Checks. Drei rote Videos laufen durch den echten Worker: BT.709 mit Angabe, 720p ohne Angabe, 360p in BT.601. Rot kommt als 254 heraus (Soll ≥ 245, vorher 229).
Gegenprobe mit dem alten Filter scale=320:-2: 3 Checks rot, Rot wieder 229. Datei zurückgesetzt, cmp bestätigt.
php -l sauber. Das JS-Gate lief nicht, die Änderung enthält kein TypeScript.
feuerwerk-video ist neu gestartet (Warteschlange war leer).
Nicht geprüft
Ein Upload über die Live-API mit Blick auf das Poster im Picker.
Nebenbei (nicht Teil dieses Issues)
Beim Bau kam die Frage auf, warum Aufnahmen in VLC dunkler wirken. Gefunden: Chromes Encoder markiert die Aufnahmen mit der Transferkurve sRGB (iec61966-2-1), und bei Game-View-Aufnahmen steht „Full Range“ nur im Matroska-Kopf, nicht im H.264-Strom. Chrome ignoriert beides beim Abspielen, die Bilddaten selbst stimmen. Der VLC-Vergleich mit umgetaggten Testdateien läuft beim User, das Ergebnis gehört in ein eigenes Issue.
Co-Authored-By: Claude Opus 5.5
## Erledigt
Commits: Repo `31ce648` „Give video posters the colours the video shows (#411)“, Wiki `7b29263` „Videos: posters keep the colours of the video (#411)“.
## Was gebaut ist
- **`VideoFormat::colour($probe)`** (neu) liest Matrix und Range aus der fertigen MP4. Der Worker probt dafür die umgewandelte Datei, nicht das Original.
- **`VideoFormat::posterArgs`** rechnet das Poster ausdrücklich von dieser Matrix nach BT.601 Full Range um: `scale=320:-2:in_color_matrix=…:in_range=…:out_color_matrix=bt601:out_range=pc:flags=accurate_rnd+full_chroma_int`. Ohne `accurate_rnd+full_chroma_int` landen dunkle Grautöne rund zwei Stufen zu tief.
- Die Suche nach dem ersten bewegten Video-Strom ist ein gemeinsamer Helfer für `plan` und `colour`.
- Wiki *Videos*: neuer Absatz zu den Poster-Farben.
## Frage 2: Video ohne Farbangabe (gemessen)
In Chromium mit einem roten H.264-Video ohne Farb-Tags gemessen (`VideoFrame.colorSpace.matrix`): **ab 720 Zeilen BT.709, darunter BT.601** (smpte170m bei 640x360). Das ist genau die Faustregel aus dem Vorschlag, `colour()` folgt ihr.
## Frage 1: alte Poster
Bleiben wie besprochen, wie sie sind.
## Tests
- `videos.test.php` im Worker-Image (echtes ffmpeg): **ALL PASSED, 90 Checks.** Drei rote Videos laufen durch den echten Worker: BT.709 mit Angabe, 720p ohne Angabe, 360p in BT.601. **Rot kommt als 254** heraus (Soll ≥ 245, vorher 229).
- **Gegenprobe** mit dem alten Filter `scale=320:-2`: 3 Checks rot, Rot wieder **229**. Datei zurückgesetzt, `cmp` bestätigt.
- `php -l` sauber. Das JS-Gate lief nicht, die Änderung enthält kein TypeScript.
- `feuerwerk-video` ist neu gestartet (Warteschlange war leer).
## Nicht geprüft
- Ein Upload über die Live-API mit Blick auf das Poster im Picker.
## Nebenbei (nicht Teil dieses Issues)
Beim Bau kam die Frage auf, warum Aufnahmen in VLC dunkler wirken. Gefunden: Chromes Encoder markiert die Aufnahmen mit der Transferkurve sRGB (`iec61966-2-1`), und bei Game-View-Aufnahmen steht „Full Range“ nur im Matroska-Kopf, nicht im H.264-Strom. Chrome ignoriert beides beim Abspielen, die Bilddaten selbst stimmen. Der VLC-Vergleich mit umgetaggten Testdateien läuft beim User, das Ergebnis gehört in ein eigenes Issue.
Co-Authored-By: Claude Opus 5.5
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Aus #156, Durchgang 6. Fund in #405, Abschluss 4371 („Betrifft nur das Vorschaubild, nicht angefasst“).
Befund
src/editor/video/VideoPicker.ts:57). Die Szene, die PREVIEW und das Spiel zeigen das Video, nicht das Poster.Vermutete Ursache (gerechnet, nicht gegengeprüft)
VideoFormat::posterArgs(api/lib/VideoFormat.php:136) schneidet mit-vf scale=320:-2und nennt keine Farbmatrix.Vorschlag
scale=320:-2:in_color_matrix=bt709:out_color_matrix=bt601:out_range=full. Die Eingangsmatrix kommt aus ffprobe (color_space). Was ohne Angabe gelten soll, ist Frage 2.Offen (mit Vorschlag)
Fertig, wenn
videos.test.php(Worker-Image, echtes ffmpeg): Ein Testvideo mit reinem Rot ergibt ein Poster mit Rot ≥ 245. Gegenprobe mit den alten Argumenten: unter 235.vorschläge passen
Erledigt
Commits: Repo
31ce648„Give video posters the colours the video shows (#411)“, Wiki7b29263„Videos: posters keep the colours of the video (#411)“.Was gebaut ist
VideoFormat::colour($probe)(neu) liest Matrix und Range aus der fertigen MP4. Der Worker probt dafür die umgewandelte Datei, nicht das Original.VideoFormat::posterArgsrechnet das Poster ausdrücklich von dieser Matrix nach BT.601 Full Range um:scale=320:-2:in_color_matrix=…:in_range=…:out_color_matrix=bt601:out_range=pc:flags=accurate_rnd+full_chroma_int. Ohneaccurate_rnd+full_chroma_intlanden dunkle Grautöne rund zwei Stufen zu tief.planundcolour.Frage 2: Video ohne Farbangabe (gemessen)
In Chromium mit einem roten H.264-Video ohne Farb-Tags gemessen (
VideoFrame.colorSpace.matrix): ab 720 Zeilen BT.709, darunter BT.601 (smpte170m bei 640x360). Das ist genau die Faustregel aus dem Vorschlag,colour()folgt ihr.Frage 1: alte Poster
Bleiben wie besprochen, wie sie sind.
Tests
videos.test.phpim Worker-Image (echtes ffmpeg): ALL PASSED, 90 Checks. Drei rote Videos laufen durch den echten Worker: BT.709 mit Angabe, 720p ohne Angabe, 360p in BT.601. Rot kommt als 254 heraus (Soll ≥ 245, vorher 229).scale=320:-2: 3 Checks rot, Rot wieder 229. Datei zurückgesetzt,cmpbestätigt.php -lsauber. Das JS-Gate lief nicht, die Änderung enthält kein TypeScript.feuerwerk-videoist neu gestartet (Warteschlange war leer).Nicht geprüft
Nebenbei (nicht Teil dieses Issues)
Beim Bau kam die Frage auf, warum Aufnahmen in VLC dunkler wirken. Gefunden: Chromes Encoder markiert die Aufnahmen mit der Transferkurve sRGB (
iec61966-2-1), und bei Game-View-Aufnahmen steht „Full Range“ nur im Matroska-Kopf, nicht im H.264-Strom. Chrome ignoriert beides beim Abspielen, die Bilddaten selbst stimmen. Der VLC-Vergleich mit umgetaggten Testdateien läuft beim User, das Ergebnis gehört in ein eigenes Issue.Co-Authored-By: Claude Opus 5.5