heygen-com/hyperframes · error · Error
ffmpeg timed out extracting first frame from ${videoPath}
Error message
ffmpeg timed out extracting first frame from ${videoPath} What it means
Thrown by extractVideoFrameToBuffer when the ffmpeg subprocess did not finish within FFMPEG_EXTRACT_TIMEOUT_MS (30 seconds) while grabbing one frame at t=0 from a video reference. runFfmpegOnce reports timedOut=true, so the command fails fast instead of hanging the whole render on a stuck ffmpeg.
Source
Thrown at packages/cli/src/commands/grade-compare.ts:505
if (!ffmpegPath) return null;
const args = [
"-hide_banner",
"-loglevel",
"error",
"-ss",
"0",
"-i",
videoPath,
"-frames:v",
"1",
"-q:v",
"2",
"-y",
outPath,
];
const result = await runFfmpegOnce(ffmpegPath, args, FFMPEG_EXTRACT_TIMEOUT_MS);
if (result.timedOut) {
throw new Error(`ffmpeg timed out extracting first frame from ${videoPath}`);
}
if (result.code !== 0 || !existsSync(outPath)) {
const detail = result.stderr.trim() ? `: ${result.stderr.trim()}` : "";
throw new Error(`ffmpeg could not extract first frame from ${videoPath}${detail}`);
}
return readFileSync(outPath);
} finally {
rmSync(tmp, { recursive: true, force: true });
}
}
async function loadReferenceFrame(framePath: string): Promise<ReferenceFrame> {
if (!existsSync(framePath)) {
throw new Error(`Reference frame not found: ${framePath}`);
}
const buffer = isVideoPath(framePath)
? await extractVideoFrameToBuffer(framePath)View on GitHub (pinned to c2996c8626)
Solutions
- Pre-extract a frame yourself (`ffmpeg -i video.mp4 -frames:v 1 frame.png`) and pass `--for frame.png` to bypass the in-CLI extraction entirely.
- Verify the video plays and isn't corrupt with `ffprobe video.mp4`.
- If the video is large, trim or re-encode it to something ffmpeg can seek quickly before running grade-compare.
- Retry on faster local storage if the file is on a slow/network mount.
Example fix
# before — hand ffmpeg the whole video hyperframes grade-compare --for clip.mp4 --grades g.json # after — pre-extract the frame ffmpeg -i clip.mp4 -ss 0 -frames:v 1 -q:v 2 frame.png hyperframes grade-compare --for frame.png --grades g.json
Defensive patterns
Strategy: fallback
Validate before calling
// Pre-extract a frame so the CLI never shells out to ffmpeg
import { spawnSync } from "node:child_process";
function ensureFrame(videoPath: string): string {
const out = videoPath.replace(/\.[^.]+$/, "") + ".frame.png";
const r = spawnSync("ffmpeg", ["-i", videoPath, "-frames:v", "1", "-q:v", "2", "-y", out]);
if (r.status !== 0) throw new Error("ffmpeg pre-extract failed");
return out;
} Try / catch
try {
// pass video to grade-compare
} catch (err) {
if (/timed out extracting first frame/.test((err as Error).message))) {
// pre-extract and pass the PNG instead
}
} Prevention
- Always pre-extract a frame for large/long videos instead of handing the whole file to grade-compare.
- Verify videos with ffprobe before grading.
- Keep reference videos short or seekable to stay under the 30s cap.
When it happens
Trigger: Passing `--for video.mp4` (or .mov/.mkv/.webm/etc.) where ffmpeg hangs — e.g. a corrupt container, a very large remote-ish file, slow disk, or a ffmpeg build stuck on a particular codec. The 30s cap is hit before the first frame is written.
Common situations: Corrupt or partially downloaded video; an unusual codec that ffmpeg decodes slowly on a cold cache; resource-constrained CI runner; a network-mounted filesystem with high latency.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- ffmpeg could not extract first frame from ${videoPath}${deta
- Could not extract a frame from video: ${framePath}
- Grade entry "${label}" must include a grading value
- --luts must include at least one LUT path
- --for <path> is required
AI-assisted analysis of heygen-com/hyperframes@c2996c8626 (2026-08-12).
Data as JSON: /api/errors/2472085fb1f155fb.
Report an issue: GitHub.