mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-14 18:01:20 +08:00
43337ae224
Lint rules: - media_missing_id (error): audio/video with data-start but no id - media_missing_src (error): media with id but no src - media_preload_none (warning): preload="none" blocks the renderer - video_nested_in_timed_element upgraded from warning to error Compiler: - Strip preload="none" from media during compilation - Fire-and-forget keyframe interval + VFR detection via ffprobe - Warn on sparse keyframes (>2s) and variable frame rate videos CLI: - Shared lintProject() lints index.html + compositions/*.html - Shared formatLintFindings() used by lint, render, and dev commands - Pre-render lint: warns by default, --strict blocks on errors, --strict-all blocks on errors + warnings - Pre-dev lint: prints issues for agents before starting studio - Render orchestrator hints --workers 1 on parallel capture timeout Refactor: - Extract runFfprobe() + parseProbeJson() (~80 lines deduped) - Extract shouldBlockRender() for testable strict flag logic - Extract formatLintFindings() (3 consumers unified)
@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