Files
hyperframes/docs/packages/engine.mdx
T
Akshar Patel 1d4aadc1fb fix(engine): mux uppercase WebM exports with Opus audio (#6579)
* fix(engine): mux uppercase WebM exports with Opus audio

* test(engine): terminate ffprobe options before input
2026-10-27 18:15:39 +00:00

120 lines
4.0 KiB
Plaintext

---
title: "@hyperframes/engine"
description: "Low-level, seekable frame capture and encoding primitives."
---
`@hyperframes/engine` is the low-level layer beneath the
[Producer](/packages/producer). It opens a page that implements the HyperFrames
seek protocol, seeks to an exact time, and captures the resulting frame.
Most integrations should use the CLI or Producer. Use the Engine only when you
need to own frame capture, encoding, media extraction, or browser management.
```bash
npm install @hyperframes/engine
```
## Why it is different from screen recording
A screen recorder waits for the wall clock and may miss frames under load. The
Engine asks the page to seek to a specific time and captures that state before
moving on.
That makes frame scheduling repeatable and prevents dropped frames caused by a
slow machine. Exact pixels can still vary with Chrome, fonts, codecs, GPU
behavior, and the host environment. Pin those dependencies when exact visual
reproducibility matters.
## Capture frames
The page at `serverUrl` must expose `window.__hf` with a `duration` and a
deterministic `seek(time)` function.
```ts
import {
captureFrame,
closeCaptureSession,
createCaptureSession,
getCompositionDuration,
initializeSession,
} from "@hyperframes/engine";
const fps = { num: 30, den: 1 };
const session = await createCaptureSession(
serverUrl,
"./frames",
{
width: 1920,
height: 1080,
fps,
format: "jpeg",
},
);
try {
await initializeSession(session);
const duration = await getCompositionDuration(session);
const totalFrames = Math.ceil(duration * 30);
for (let frame = 0; frame < totalFrames; frame += 1) {
const time = frame / 30;
await captureFrame(session, frame, time);
}
} finally {
await closeCaptureSession(session);
}
```
Use `captureFrameToBuffer()` when the next stage needs an in-memory buffer
instead of a file.
## WebGPU requirements
A composition marked `data-requires-webgpu` must be able to create a WebGPU
device before capture starts. Finding an adapter alone is insufficient: device
creation can still fail because of the browser or graphics driver. The adapter
and device check share a ten-second timeout, and failure stops capture with
`WebGpuUnavailableError`.
Hardware adapters are required by default. A launch explicitly configured for
software WebGPU may use SwiftShader, but it must also create a device. The check
releases its temporary device; the composition still creates its own device
with any features or limits its renderer needs.
## What else the package exposes
| Surface | Use it for |
| --- | --- |
| Browser management | Launching, pooling, and releasing Chrome |
| Encoders | MP4, WebM, MOV, GIF, PNG-sequence, muxing, and faststart |
| Media extraction | Preparing source video frames and audio tracks |
| Parallel capture | Distributing frame ranges across workers |
| Diagnostics | Capture performance, media metadata, and GPU parity |
Paths passed to `encodeFramesChunkedConcat()` and `concatVideoFiles()` may be
relative or absolute. Relative paths resolve from the calling process's working
directory.
`muxVideoWithAudio()` recognizes output filename extensions regardless of case.
WebM output, including `.WEBM` and `.WeBm`, converts audio to Opus while copying
the video stream.
These are rendering internals. Their result and error conventions differ by
operation: browser and capture orchestration throws, FFmpeg wrappers generally
return result objects, and teardown helpers avoid masking the original failure.
Browser and frame-capture diagnostics, including motion-blur reports, go to
stderr. This keeps stdout available for machine-readable results such as
`hyperframes benchmark --json`.
## Related topics
<CardGroup cols={2}>
<Card title="@hyperframes/producer" icon="video" href="/packages/producer">
Get a finished video without assembling the pipeline yourself.
</Card>
<Card title="Deterministic rendering" icon="repeat" href="/concepts/determinism">
Understand what HyperFrames controls and what the environment still affects.
</Card>
</CardGroup>