Skip to content

feat(export): 4K master output + watermark scale#14

Merged
shreyaskarnik merged 1 commit into
mainfrom
feat/4k-master-export
May 5, 2026
Merged

feat(export): 4K master output + watermark scale#14
shreyaskarnik merged 1 commit into
mainfrom
feat/4k-master-export

Conversation

@shreyaskarnik
Copy link
Copy Markdown
Owner

Summary

Adds a 4K export path that preserves the supersampled detail captured by chromium + jpeg-stitch + deviceScaleFactor: 2 instead of downscaling 3840×2160 back to 1080p at export time. Companion: watermark.scale so the existing 1080p-sized logo PNG stays visually-relative at 4K output without forcing a fresh 2× asset.

Changes

  • export.outputWidth / export.outputHeight — when set, the pipeline keeps source resolution rather than downscaling. Defaults remain video.width / video.height (current behavior, no breaking change).
  • resolveExportSize(config) helper centralizes the precedence rule, used by CLI + pipeline.
  • scaleCameraMoves(moves, scaleX, scaleY) generalized from DSF-only so post-export camera moves work with any layout-to-frame ratio.
  • watermark.scale resamples the PNG (bicubic) before the overlay, so the same asset stays the right relative size at any output resolution.

Showcase config

Flipped to the 4K master:

  • browser: 'chromium' + captureMode: 'jpeg-stitch' + deviceScaleFactor: 2 (already v0.35's high-quality recording path)
  • export.outputWidth: 3840 / outputHeight: 2160 (the 4K master)
  • watermark: { scale: 2, margin: 52 } (was 26) so the brand bug stays visually-relative

Frame padding: 48 / borderRadius: 16 left at 1080p-tuned values intentionally — the point of 4K is to expose more UI detail, so a tighter relative frame is the right trade-off. Encoder preset stays at slow for final renders.

Test plan

  • `npx tsc -p tsconfig.json --noEmit`
  • `npm run build`
  • `npx vitest run` — 645 tests pass
  • `tests/cli.test.ts` mock updated with `resolveExportSize` (was the previous failure source)
  • CI matrix on chromium / firefox / webkit
  • Manual visual review of showcase 4K master

Compatibility

No breaking changes. Existing demos and configs that don't set `outputWidth` / `outputHeight` / `watermark.scale` get the previous behavior. The `scaleCameraMoves` signature change is backwards-compatible — `scaleY` defaults to `scaleX`.

Adds a 4K export path that preserves the supersampled detail captured by
chromium + jpeg-stitch + deviceScaleFactor: 2 instead of downscaling the
3840×2160 source back to 1080p at export time.

Surfaces:

* `export.outputWidth` / `export.outputHeight` — when set, the export
  pipeline keeps the source resolution rather than downscaling. Defaults
  to `video.width` / `video.height` (current behavior).
* `resolveExportSize(config)` helper used by CLI + pipeline to decide
  the final frame dimensions.
* `scaleCameraMoves` generalized — was DSF-only, now takes
  `scaleX, scaleY` so post-export camera moves work with any layout-to-
  frame ratio (1080p layout → 1080p output, 1080p layout → 4K output,
  etc.).
* `watermark.scale` — resamples the watermark PNG with bicubic before
  the overlay, so the same logo asset stays visually-relative at 4K
  output without forcing users to ship a 2× PNG.

Showcase config flips to:
  - browser: chromium + captureMode: jpeg-stitch + deviceScaleFactor: 2
    (already the v0.35 high-quality recording path)
  - export.outputWidth/outputHeight: 3840×2160 (the 4K master)
  - watermark scale: 2 + margin: 52 (was 26) so the brand bug stays the
    same on-screen size as the 1080p master

Frame padding/borderRadius intentionally left at 1080p-tuned values
(48 / 16) — the point of the 4K master is to expose more UI detail, so
a tighter relative frame is the right trade-off. Encoder preset stays
at `slow` for final renders.

Tests:
* tests/cli.test.ts mock now includes `resolveExportSize`
* tests/camera-move.test.ts covers the new `scaleX, scaleY` signature
* tests/config.test.ts covers `resolveExportSize` precedence rules
* tests/pipeline.test.ts + tests/record.test.ts + tests/narration.test.ts
  cover the new wiring

645 tests pass; build clean.
@shreyaskarnik shreyaskarnik merged commit 68df068 into main May 5, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant