mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-04 07:19:52 +00:00
## Summary Tighten `hdr-regression` Window F `maxFrameFailures` from 5 → 0 now that Chunk 4 (matrix3d support + scene initial-state) has landed. ## Why Window F (transform + scale + border-radius on the video itself) was the remaining known-fail in the `hdr-regression` suite, baked into the golden so the suite stayed green while Chunk 4 was outstanding. After Chunk 4 fixed `parseTransformMatrix` (matrix3d support) and the shader-transitions initial-state, re-running the suite shows **0 failed frames** against the existing golden — the encoder is byte-deterministic, and Window F's GSAP rotation/scale happens to emit 2D `matrix()` rather than `matrix3d()`, so the same golden is still correct after the fix. Tightening the budget catches any drift in the layered HDR compositor immediately. ## What changed - `tests/hdr-regression/meta.json`: `maxFrameFailures` 5 → 0 (matches `hdr-hlg-regression`). - `tests/hdr-regression/README.md`: Window F row + Fix history section updated to reflect the new state. ## Test plan - [x] `bun run test --filter hdr-regression` — passes with 0 failed frames at the new budget. ## Stack Follow-up to Chunk 4 (transform & clipping). Reviewable separately so the budget tightening is decoupled from the code fix.
@hyperframes/producer
Full HTML-to-video rendering pipeline: capture frames with Chrome's BeginFrame API, encode with FFmpeg, mix audio — all in one call.
Install
npm install @hyperframes/producer
Requirements: Node.js >= 22, Chrome/Chromium (auto-downloaded), FFmpeg
Usage
Render a video
import { createRenderJob, executeRenderJob } from "@hyperframes/producer";
const job = createRenderJob({
inputPath: "./my-composition.html",
outputPath: "./output.mp4",
width: 1920,
height: 1080,
fps: 30,
});
const result = await executeRenderJob(job, (progress) => {
console.log(`${Math.round(progress.percent * 100)}%`);
});
console.log(result.outputPath); // ./output.mp4
Run as an HTTP server
The producer can also run as a render server, accepting render requests over HTTP:
import { startServer } from "@hyperframes/producer";
await startServer({ port: 8080 });
// POST /render with a RenderConfig body
Configuration
RenderConfig controls the render pipeline:
| Option | Default | Description |
|---|---|---|
inputPath |
— | Path to the HTML composition |
outputPath |
— | Output video file path |
width |
1920 | Frame width in pixels |
height |
1080 | Frame height in pixels |
fps |
30 | Frames per second (24, 30, or 60) |
quality |
"standard" |
Encoder preset ("draft", "standard", "high") |
How it works
- Serve — spins up a local file server for the HTML composition
- Capture — opens the page in headless Chrome, seeks frame-by-frame via
HeadlessExperimental.beginFrame, captures screenshots - Encode — pipes frames through FFmpeg (with GPU encoder detection and chunked concat)
- Mix — extracts
<audio>elements and mixes them into the final video - Finalize — applies faststart for streaming-friendly MP4
Documentation
Full documentation: hyperframes.heygen.com/packages/producer
Related packages
@hyperframes/core— types, parsers, frame adapters@hyperframes/engine— lower-level capture and encode primitiveshyperframes— CLI