Repository navigation
Closed
Labels
bugSomething isn't workingSomething isn't working
Description
Describe the bug
On low-memory PCs (e.g. Intel i5, 8GB RAM, Linux), very simple compositions – a single <video> and a trivial GSAP timeline – will eventually render if you wait long enough (upwards of 10-20+ minutes), but any real/comprehensive composition (multiple scenes, dynamic JS) instantly fails at 5% ("Compiling composition") with a timeout, even when setting huge timeout env vars.
Example simple composition (see below):
- Renders successfully after waiting a long time (initial 5% step takes 10+ minutes with no feedback/logs)
- This proves engine is not totally broken on the system
Any real-world composition (even with big timeout settings):
- Command:
PRODUCER_PUPPETEER_PROTOCOL_TIMEOUT_MS=300000 PRODUCER_PLAYER_READY_TIMEOUT_MS=300000 PUPPETEER_PROTOCOL_TIMEOUT=300000 bunx hyperframes render videos/bliss_no_bliss -q draft -f 1 -w 1 --no-browser-gpu --browser-timeout=300 - Fails instantly at 5% with:
Failed: Runtime.callFunctionOn timed out. Increase the 'protocolTimeout' setting in launch/connect calls for a higher timeout if needed. Try --docker for containerized rendering - Setting all relevant protocol/socket/browser/hyperframes timeouts to huge values does not help
Steps to reproduce
- Try a trivial comp (the example HTML, see below):
- It will render if you wait 10+ min with no logs after 5%
- Try any real timeline-driven comp (multi-scene, JS, etc.)
- Always fails instantly at 5% probe, regardless of timeouts
- Even with maximum timeout settings, real comps do not start rendering at all
Minimal composition that will eventually work if you wait:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Mockup Video</title>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/gsap.min.js"></script>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { background: red; overflow: hidden; }
#stage { margin: auto; }
video { width: 100%; height: 100%; object-fit: contain; }
</style>
</head>
<body>
<div id="stage" data-composition-id="mockup" data-width="1080" data-height="1920" data-start="0">
<video id="mockup-video" muted playsinline data-track-index="0" data-start="0" data-duration="8"
src="assets/mockup.webm"></video>
</div>
<script>
window.__timelines = window.__timelines || {};
window.__timelines['mockup'] = gsap.timeline({ paused: true });
</script>
</body>
</html>Expected behavior
- Trivial comps should render quickly, with logs if slow
- Real-world compositions should not time out at the duration probe/5% step, or should give actionable logging if stuck
- Setting timeouts to huge values should let the probe try much longer before failing
Actual behavior
- Trivial comp: hangs at 5% for minutes (10+), then eventually renders
- Real comp: fails instantly at 5% with Protocol timeout error, no logs while waiting, even if all timeouts are huge
Environment
- Hyperframes 0.6.73 (latest)
- Node.js v22.22.2 (Linux x64)
- CPU: Intel i5-7200U quad-core
- RAM: 8GB (3GB free)
- Disk: 40+ GB free
- /dev/shm: 3.9GB
- Chrome headless 131.0.6778.85 (bundled)
- Docker: running/disabled (same effect)
- Lubuntu 24.04Additional context
- See (bug) Render freezes & Chrome crash at 25% frame capture on low-memory Linux (video element) #1072 and PR fix(engine): scale Chrome memory budget and frame cache to system RAM #1073; original video frame extraction crash is fixed for super-simple comps but probe step is now the bottleneck
- Needs periodic (every minute) log output while duration probe is running (see also companion issue)
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working
Activity
O1Anas commentedon Jun 5, 2026
maybe, just maybe:
Correction to the previous comment — the
data-durationhypothesis was wrongI need to retract the previous comment. Setting
data-durationon the root element does not fix the timeout — the hang persists identically. After reading the actual composition source, here is what I believe is actually happening:Root cause:
SplitTextblocking on unloaded Arabic font metricsThe composition calls:
This runs synchronously on page load, before
window.__timelinesis registered. It targets.sentenceelements that arevisibility: hiddenand contain Arabic text rendered with a custom@font-facefont (Thmanyah, loaded fromassets/fonts/...). On low-memory hardware, the font is not yet decoded when SplitText runs. SplitText internally readsoffsetWidth/getBoundingClientRecton each word to split text — if the font hasn't painted, Chrome may block the layout thread waiting for the font to resolve, hanging the page indefinitely.Because
window.__timelines["bliss_no_bliss"]is only registered after SplitText completes (it's inside atryblock that runs after the split), hyperframes'window.__hfreadiness probe viaRuntime.callFunctionOnfinds no registered timeline and waits until timeout.Things that confirm this:
videoCount:0, audioCount:0confirmed), timeout env vars, ordata-durationvalueshuwiyya-introandbliss_no_blissfail identically — both use Arabic@font-face+ SplitTextProposed workarounds to test:
font-display: swapor preload the font before SplitText runs:Engine-level fix request: hyperframes should wait for
document.fonts.readybefore callingRuntime.callFunctionOnto probewindow.__hf, or at minimum document thatSplitText+ unloaded custom fonts can deadlock the readiness probe on slow hardware.fix: respect user timeouts on low-memory systems (#1219)
fix: respect user timeouts on low-memory systems (#1221)
feat(producer): auto low-memory safe render profile (#1225)
fix: respect user timeouts on low-memory systems (heygen-com#1221)
feat(producer): auto low-memory safe render profile (heygen-com#1225)