Add desktop/server MP4 export pipeline, hardening, and render tests (v1.3.0)

Desktop MP4 export renders frames from a hidden BrowserWindow via
capturePage, pipes PNGs to a bundled ffmpeg (libx264/yuv420p/+faststart),
and writes the file through an atomic temp-file swap. It shares scene
validation (shared/renderValidation.cjs) and the render.html renderer with
the standalone Puppeteer server, which is hardened in parallel.

Render worker & main (electron/):
- abortable render loop with an inactivity watchdog and cancel plumbing
- atomic temp-file + rename so a cancel/failure never truncates a
  pre-existing target (#7); stdin EPIPE / early-exit / backpressure-hang
  handled (#8)
- HiDPI frames normalized to canvas size (#10); odd dimensions padded to
  even (#13, also server); backgroundThrottling disabled (#12)
- reject canvases larger than the display (#11); single-render guard;
  isolated render session that blocks network requests (#5)

Tests:
- Electron harnesses (scripts/verify-*.cjs) for capture, export, cancel,
  timeout, assets, background, capture-fidelity, resolution, odd-dims,
  aggregated by verify-desktop-render.cjs
- server smoke + e2e and shared validation unit tests
- headless hook (src/devtools/headless.ts) to run the in-app suite under
  browser/electron hosts; pixel-diff util + capture fixtures (test/)
- dev_docs plans: integration, fixes (#7-#13), and the e2e/capture strategy

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
thandClaude Opus 4.8 committed 2026-06-06 20:41:25 +02:00
1 parent 46f9f32aef
commit 518d43855b
41 files changed
+3907 -86

No files matched your search

+22
View File
@@ -68,6 +68,18 @@ npm run desktop:build # build platform installer/package artifacts into release
app without creating an installer. `desktop:build` uses `electron-builder` and
targets AppImage on Linux, NSIS on Windows, and DMG on macOS.
Desktop MP4 export runs inside Electron and uses ffmpeg from
`resources/bin/<platform>/` in packaged builds. The build scripts run
`npm run stage:ffmpeg -- --optional`, which copies `FFMPEG_PATH` or `ffmpeg` on
`PATH` into `bin/<platform>/` when available. For release artifacts, replace
that local copy with redistributable static ffmpeg binaries for Linux, Windows,
and macOS.
If no bundled binary is present, MP4 export still falls back to `FFMPEG_PATH`
or system `ffmpeg` and reports a clear error when neither can be executed.
Before shipping bundled ffmpeg, document the binary source, version, configured
codecs, and GPL/LGPL obligations for that build.
## MP4 render server
MP4 export is handled by the optional render server in `server/`. It binds to
@@ -96,6 +108,16 @@ The included `docker-compose.yml` keeps the published host port on
`127.0.0.1:6000` and requires `RENDER_TOKEN` in the environment before it will
start.
Render-server checks:
```bash
npm run test:render-server # health/auth/validation route smoke
npm run test:render-server:e2e # renders a tiny MP4 and verifies it with ffprobe
```
The E2E check requires Chromium, ffmpeg, and ffprobe. Set
`PUPPETEER_EXECUTABLE_PATH` when Chromium is not at `/usr/bin/chromium`.
## Stack
- Vue 3 (`<script setup>`) + Pinia state