Files
hyperframes/packages/producer
Miguel ÁngelandClaude Opus 4.6 6cd6514daa fix(producer): extract head styles/scripts from non-template sub-compositions
Mirrors the runtime compositionLoader fix: the producer's
inlineSubCompositions() was parsing only `bodyEl.innerHTML`,
discarding all <head> content. CSS backgrounds, positioning,
fonts, and library scripts (GSAP CDN) defined in <head> were
silently dropped during compilation.

Also externalizes postcss in the esbuild config to fix
"Dynamic require of path is not supported" error that broke
local dev rendering via `npx tsx cli render`.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 15:18:25 +00:00
..
2026-04-03 04:36:19 +00:00

@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

  1. Serve — spins up a local file server for the HTML composition
  2. Capture — opens the page in headless Chrome, seeks frame-by-frame via HeadlessExperimental.beginFrame, captures screenshots
  3. Encode — pipes frames through FFmpeg (with GPU encoder detection and chunked concat)
  4. Mix — extracts <audio> elements and mixes them into the final video
  5. Finalize — applies faststart for streaming-friendly MP4

Documentation

Full documentation: hyperframes.heygen.com/packages/producer