heygen-com/hyperframes · error

Audio file too large for headless analysis

Error message

Audio file too large for headless analysis (${mb}MB > ${MAX_AUDIO_BYTES / 1e6}MB).

What it means

Thrown by analyzeBeatsHeadless() before any browser work when audioBytes.length exceeds MAX_AUDIO_BYTES (80 MiB). The guard exists because the audio is base64-encoded (+33% size) and shipped to the headless page over CDP; a very large file would blow CDP message limits and stall. The message reports the actual size in MB and the cap (80MB).

Solutions

  1. Trim the audio to the section you need: `ffmpeg -i in.flac -t 180 -c:a libmp3lame -q:a 2 clip.mp3` (first 180s).
  2. Downsample/compress to MP3 or AAC to shrink the byte size while keeping beat-detection-relevant frequencies.
  3. If you need beats for a long track, analyze a representative segment and extrapolate, or raise the cap locally by editing MAX_AUDIO_BYTES if you control memory.

Example fix

# before — 200MB FLAC rejected
$ bunx hyperframes beats album.flac
# trim and compress
$ ffmpeg -i album.flac -t 300 -c:a libmp3lame -b:a 192k clip.mp3
$ bunx hyperframes beats clip.mp3
Defensive patterns

Strategy: validation

Validate before calling

const MAX = 80 * 1024 * 1024;
if (audioBytes.length > MAX) {
  throw new Error(`Audio too large (${Math.round(audioBytes.length / 1e6)}MB). Trim or compress to <= 80MB.`);
}
await analyzeBeatsHeadless(audioBytes);

Type guard

function audioWithinLimit(bytes: Buffer): boolean {
  return bytes.length <= 80 * 1024 * 1024;
}

Prevention

When it happens

Trigger: Calling analyzeBeatsHeadless(buf) where buf is a Buffer longer than 83,886,080 bytes (80*1024*1024). Typical with long mixes, podcast episodes, or lossless files (FLAC/WAV) of a few minutes.

Common situations: User runs the beats command on a 2-hour podcast WAV; a lossless FLAC that is large per minute; a full album rip passed as one file.

Related errors


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

Appendix: source

Thrown at packages/cli/src/beats/headlessAnalyzer.ts:133

  });
  page.on("console", (m) => {
    if (m.type() === "error") pageErrors.push(m.text());
  });
  await page.setContent("<!doctype html><html><body></body></html>");
  await page.addScriptTag({ content: bundle });
  try {
    return (await page.evaluate(inPageAnalyze, b64)) as HeadlessBeatResult;
  } catch (err) {
    const detail = pageErrors.length ? ` (${pageErrors.join("; ")})` : "";
    throw new Error(`${err instanceof Error ? err.message : String(err)}${detail}`);
  }
}

/** Decode + analyze the given audio bytes in headless Chrome. */
export async function analyzeBeatsHeadless(audioBytes: Buffer): Promise<HeadlessBeatResult> {
  if (audioBytes.length > MAX_AUDIO_BYTES) {
    const mb = Math.round(audioBytes.length / 1e6);
    throw new Error(
      `Audio file too large for headless analysis (${mb}MB > ${MAX_AUDIO_BYTES / 1e6}MB).`,
    );
  }
  const bundle = await buildAnalyzerBundle();
  const { ensureBrowser } = await import("../browser/manager.js");
  const puppeteer = await import("puppeteer-core");
  const browser = await ensureBrowser();
  const chrome: Browser = await puppeteer.default.launch({
    headless: true,
    executablePath: browser.executablePath,
    args: ["--no-sandbox", "--disable-dev-shm-usage", "--autoplay-policy=no-user-gesture-required"],
  });
  try {
    const page = await chrome.newPage();
    return await detectOnPage(page, bundle, audioBytes.toString("base64"));
  } finally {
    await chrome.close();
  }

View on GitHub (pinned to c2996c8626)