feat: add Studio current-frame capture (#565)

## Problem

Closes #555. Studio users could inspect the preview, but there was no first-class way to capture the current rendered frame as an image.

## What this fixes

- Adds a `Capture` action to the Studio header toolbar so it does not cover the video preview.
- Downloads the current composition frame as a PNG using the current player time.
- Extends the existing thumbnail route and Studio/CLI thumbnail generators with an explicit PNG format path while preserving JPEG thumbnails for existing previews.
- Adds URL/filename utility coverage plus thumbnail route coverage for PNG requests.

## Root cause

Studio already had frame thumbnail generation, but the API path was JPEG-oriented and the editor UI only used it for previews. There was no current-frame capture affordance wired to the player state.

## Verification

### Local

- `bun run --filter @hyperframes/core test src/studio-api/routes/thumbnail.test.ts`
- `bun run --filter @hyperframes/studio test src/utils/frameCapture.test.ts src/player/components/PlayerControls.test.ts`
- `bun run --filter @hyperframes/studio typecheck`
- `bun run --filter @hyperframes/core typecheck`
- `bun run --filter @hyperframes/cli typecheck`
- `bunx oxlint packages/cli/src/server/studioServer.ts packages/core/src/studio-api/routes/thumbnail.test.ts packages/core/src/studio-api/routes/thumbnail.ts packages/core/src/studio-api/types.ts packages/studio/src/App.tsx packages/studio/src/icons/SystemIcons.tsx packages/studio/vite.config.ts packages/studio/src/utils/frameCapture.ts packages/studio/src/utils/frameCapture.test.ts`
- `bunx oxfmt --check packages/cli/src/server/studioServer.ts packages/core/src/studio-api/routes/thumbnail.test.ts packages/core/src/studio-api/routes/thumbnail.ts packages/core/src/studio-api/types.ts packages/studio/src/App.tsx packages/studio/src/icons/SystemIcons.tsx packages/studio/vite.config.ts packages/studio/src/utils/frameCapture.ts packages/studio/src/utils/frameCapture.test.ts`
- `git diff --check`

### Browser
<img width="1027" height="910" alt="image" src="https://github.com/user-attachments/assets/71973af4-0279-4074-9
<img width="1026" height="902" alt="Screenshot 2026-04-29 at 16 17 22" src="https://github.com/user-attachments/assets/a32e1c19-b793-40b9-82f8-de8bbb11f123" />
060-130839a2d419" />
This commit is contained in:
Miguel Ángel
2026-04-29 22:48:14 +02:00
committed by GitHub
parent b9a9998ff0
commit ea3b708b12
13 changed files with 321 additions and 117 deletions
+12 -5
View File
@@ -278,11 +278,18 @@ export function createStudioServer(options: StudioServerOptions): StudioServer {
};
}, opts.selector);
}
const screenshot = (await page.screenshot({
type: "jpeg",
quality: 80,
...(clip ? { clip } : {}),
})) as Buffer;
const screenshot = (await page.screenshot(
opts.format === "png"
? {
type: "png",
...(clip ? { clip } : {}),
}
: {
type: "jpeg",
quality: 80,
...(clip ? { clip } : {}),
},
)) as Buffer;
return screenshot;
} catch {
return null;