Files
feuerwerk/api/lib
adminandClaude Opus 5.5 31ce6480b2
feuerwerk / gate (push) Successful in 4m30s
feuerwerk / suite (push) Successful in 18m12s
Give video posters the colours the video shows (#411)
The worker made the poster with a plain scale=320:-2. ffmpeg then
read every picture as BT.601 in the limited range, so a red of 255 in
a BT.709 video came out as 229 in the JPEG. The picker showed paler
posters than the video in the editor.

- VideoFormat::colour reads matrix and range of the converted MP4.
  When the file says nothing, it follows Chrome: BT.709 from 720 lines
  up, BT.601 below. That guess was measured in Chromium with a red
  H.264 video without colour tags.
- posterArgs turns the picture from that matrix into BT.601 in the
  full range, the way a JPEG is read. accurate_rnd and
  full_chroma_int keep dark greys from landing two steps too low.
- The search for the first moving video stream is now one helper,
  used by plan and colour.
- Posters made before this change stay as they are.

Tests:
- videos.test.php in the worker image: ALL PASSED, 90 checks. Three
  red videos go through the real worker: BT.709 tagged, 720p without
  tags and 360p in BT.601. Red comes out as 254.
- Counter-check with the old filter: 3 checks red, red is 229 again.
- php -l clean on all three files. The gate was not run, the change
  has no TypeScript.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 16:45:20 +02:00
..
Plugins belong to the project, and they load before it: the project file gained the field plugins: ["demo-plugin.js"] (default empty, no formatVersion bump), the Plugins tab's switch writes into it as an ordinary undo step (SetPluginActiveCommand) instead of into a server-wide plugins.json, and the start order is turned around - startPlugins only fetches the list of files, then editor.boot() runs and ProjectStore.load(id, prepare) hands the raw JSON through before it is deserialized, where pluginsOf(raw) reads the list and PluginManager.syncTo() activates exactly those; that is the point of the issue, because what a plugin registers has to stand there before normalizeGraph would throw it away as unknown (#126, #127), a project switch first stops what the new project does not name and then starts what it does, a file the server does not have is passed over silently, and after signing out the manager is dead so a late event cannot start anything in a torn-down session; on the server plugins.json, PluginStore::setActive, isActive, the route PUT ?r=plugins/{file} and the 403 for inactive modules are gone and GET ?r=plugins only answers {file,bytes,updatedAt}, which makes every plugin file fetchable - the consequence accepted in #117, written down in the wiki for #115 and #116; publishPlugins(root) only copies files now, the seeder switches the demo plugin on in the fixture project, and the Plugins tab carries a puzzle piece as its icon while only a plugin's own tab still goes without one (the knob and the socket are cubic curves, not arcs, which Pixi's parser draws as a spike after an L); 3 new e2e checks in module 38 and 5 new unit tests cover the project as the owner of the switch, its undo, the order, pluginsOf against crude input and an unknown file name (#119)
2026-09-20 14:24:27 +02:00
2026-09-08 13:43:08 +02:00