heygen-com/hyperframes · error · Error

Could not extract a frame from video: ${framePath}

Error message

Could not extract a frame from video: ${framePath}

What it means

Thrown by loadReferenceFrame when `--for` is a video path and extractVideoFrameToBuffer returned null. The only null return path in that function is when findFFmpeg() cannot locate an ffmpeg binary — meaning no ffmpeg is available to extract a frame from the supplied video.

Source

Thrown at packages/cli/src/commands/grade-compare.ts:526

      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)
    : readFileSync(framePath);
  if (!buffer) {
    throw new Error(`Could not extract a frame from video: ${framePath}`);
  }

  const metadata = await sharp(buffer).metadata();
  if (!metadata.width || !metadata.height) {
    throw new Error(`Could not read reference frame dimensions: ${framePath}`);
  }

  return {
    buffer,
    width: metadata.width,
    height: metadata.height,
    stagedName: isVideoPath(framePath) ? "frame.png" : frameFileNameForPath(framePath),
  };
}

async function captureGradeCompareSheet(
  projectDir: string,
  timeoutMs: number,

View on GitHub (pinned to c2996c8626)

Solutions

  1. Install ffmpeg and ensure it's on PATH (`ffmpeg -version` should succeed in the same shell).
  2. If ffmpeg is installed somewhere nonstandard, set the env var HyperFrames' findFFmpeg honors (FFMPEG_BINARY_PATH) to its absolute path.
  3. Alternatively, pre-extract a frame to PNG and pass `--for frame.png` so no ffmpeg is needed at compare time.

Example fix

# before — no ffmpeg on PATH
hyperframes grade-compare --for clip.mp4 --grades g.json
# after — install ffmpeg, or extract manually
ffmpeg -i clip.mp4 -frames:v 1 frame.png
hyperframes grade-compare --for frame.png --grades g.json
Defensive patterns

Strategy: validation

Validate before calling

// Ensure ffmpeg is available before handing a video to grade-compare
import { spawnSync } from "node:child_process";
function ffmpegAvailable(): boolean {
  return spawnSync("ffmpeg", ["-version"], { stdio: "ignore" }).status === 0;
}
if (isVideoPath(frame) && !ffmpegAvailable()) {
  throw new Error("ffmpeg not on PATH; pre-extract a frame or install ffmpeg");
}

Type guard

function isVideoPath(p: string): boolean {
  return /\.(mp4|mov|m4v|webm|mkv|avi|mpeg|mpg|ogv)$/i.test(p);
}

Try / catch

try {
  // run grade-compare on a video
} catch (err) {
  if (/Could not extract a frame from video/.test((err as Error).message))) {
    // install ffmpeg, or pre-extract a PNG and pass that as --for
  }
}

Prevention

When it happens

Trigger: Passing `--for video.mp4` on a machine where ffmpeg is not installed or not on PATH. findFFmpeg searches known locations and PATH; if none yields a usable binary, the extractor returns null and this error names the video.

Common situations: Fresh CI runner without ffmpeg preinstalled; a slim Docker image; ffmpeg installed but not on PATH; `FFMPEG_BINARY_PATH` not set when ffmpeg lives in a nonstandard location.

Related errors


AI-assisted analysis of heygen-com/hyperframes@c2996c8626 (2026-08-12). Data as JSON: /api/errors/658dc56baadf11e7. Report an issue: GitHub.