feat(export): 4K master output + watermark scale#14
Merged
Conversation
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a 4K export path that preserves the supersampled detail captured by chromium + jpeg-stitch +
deviceScaleFactor: 2instead of downscaling 3840×2160 back to 1080p at export time. Companion:watermark.scaleso 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 remainvideo.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.scaleresamples 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-relativeFrame
padding: 48/borderRadius: 16left 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 atslowfor final renders.Test plan
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`.