Sparse-keyframe check silently skips single-keyframe videos — the worst case goes unreported (0.8.10)
I maintainer di solito rispondono entro 1 giorno
@ravsau ci sta già lavorando.
Dal 15/9/2026.
Valutazione
- Difficoltà
- 3/5
- Tempo stimato
- 1-2 giorni
- Idoneità per principianti
- 76/100
- Tipo di issue
- Bug
- Chiarezza
- Abbastanza chiara
- Stato di attività
- Attiva
- Stack tecnologico
- typescript
- Ambito
- audio-video-rtc
Direzione di ricerca
Start in engine/src/utils/ffprobe.ts at analyzeKeyframeIntervalsUncached, then inspect the duration path in extractVideoMetadata and the compiler warning entry point. Reproduce the single-keyframe and two-keyframe cases from the issue, and verify that single-keyframe videos use their stream duration while zero-keyframe and zero-duration assets retain their existing behavior.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Summary
analyzeKeyframeIntervals bails out when a video has fewer than two keyframes and reports isProblematic: false. But a video with exactly one keyframe is the worst case for the very failure mode the warning exists to catch: every seek past 0 lands inside a single GOP that spans the whole file. The compiler warns about a 5-second GOP and stays silent about a 10-second one.
In analyzeKeyframeIntervalsUncached (bundled from engine/src/utils/ffprobe.ts):
const timestamps = stdout.split("\n").map(l => parseFloat(l.trim())).filter(Number.isFinite);
if (timestamps.length < 2) {
return { avgIntervalSeconds: 0, maxIntervalSeconds: 0, keyframeCount: timestamps.length, isProblematic: false };
}
The early return is reasonable for still images and 1-frame assets, but it also swallows real single-GOP videos of arbitrary length.
Reproduction
Two 10-second clips, identical except for GOP size:
ffmpeg -y -f lavfi -i testsrc=size=640x360:rate=30:duration=10 \
-c:v libx264 -pix_fmt yuv420p -g 1000 -keyint_min 1000 -sc_threshold 0 assets/single-gop.mp4
ffmpeg -y -f lavfi -i testsrc=size=640x360:rate=30:duration=10 \
-c:v libx264 -pix_fmt yuv420p -g 150 -keyint_min 150 -sc_threshold 0 assets/five-second-gop.mp4
Keyframe timestamps:
single-gop.mp4 0.000000
five-second-gop.mp4 0.000000 5.000000
index.html — both clips, each seeking to 8s:
<div id="root" data-composition-id="gop-repro" data-start="0" data-duration="2" data-width="640" data-height="360">
<video id="single-gop" class="clip layer" data-start="0" data-duration="1" data-track-index="0" data-media-start="8" src="assets/single-gop.mp4" muted></video>
<video id="five-second-gop" class="clip layer" data-start="1" data-duration="1" data-track-index="0" data-media-start="8" src="assets/five-second-gop.mp4" muted></video>
</div>
npx [email protected] render . -o out.mp4 2>&1 | grep Compiler
Observed
[WARN] [Compiler] WARNING: Video "five-second-gop" has sparse keyframes (max interval: 5s). ...
Nothing for single-gop, whose effective seek distance is 10s — twice as bad.
Expected
single-gop should warn at least as loudly as five-second-gop.
Suggested fix
When exactly one keyframe is found, the effective interval is the stream duration, not zero:
if (timestamps.length === 1) {
const duration = await probeDurationSeconds(filePath); // already available via extractVideoMetadata
return {
avgIntervalSeconds: duration,
maxIntervalSeconds: duration,
keyframeCount: 1,
isProblematic: duration > 2,
};
}
if (timestamps.length === 0) {
return { avgIntervalSeconds: 0, maxIntervalSeconds: 0, keyframeCount: 0, isProblematic: false };
}
Still images and single-frame assets keep their current behaviour, since their duration is 0 or below the threshold.
Why it matters in practice
This is not a synthetic corner case. In a 414-clip library downloaded straight from Pexels and Pixabay, 26 files are single-GOP with durations from 2.3s to 10s — exactly the ones the check skips. Overall that library sits well above the 2s threshold anyway (median max interval 3.04s, 82% above 3s), so in practice the check fires on nearly everything except the worst offenders.
Side note, offered as data rather than a complaint
While measuring the above we could not reproduce the failure the warning describes, on hyperframes render at least. Two stands cut deliberately mid-GOP — a stock clip with keyframes 10s apart, and an Archive.org master with 5.51s intervals, cut 3.5s past a keyframe — both rendered frame-accurate: mean per-pixel luma delta against ffmpeg-extracted ground truth was 1.4–1.8, versus 15–60 against any neighbouring moment. The video_extract phase resolves frames through ffmpeg (minVideoFrameCoverageRatio: 1), which decodes from the preceding keyframe correctly. Re-encoding per the suggested command changed render wall-clock by ~3% (95s vs 98s on the same stand), i.e. noise.
So the warning may be aimed at a different path (browser seeking in preview/studio?) than the one render takes. If that is the case, narrowing its wording or its scope might be worth considering alongside the fix above.
Environment: macOS 26.5.2 (arm64), Node 26.0.0, hyperframes 0.8.10 (also verified on 0.7.106).
- Lingua principale
- TypeScript
- Stelle
- 54.1k
- Fork
- 4.9k
- Merge medio
- 7h 18m
- PR unite (30g)
- 784
Preparare l'ambiente
Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di heygen-com/hyperframes
-
Docs: clarify that "Enable auto-update" is only available in the Claude Code terminal (CLI) /plugin UIForse già presa Una pull request collegata a questa issue è aperta o già unita. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 85/100
heygen-com/hyperframes#5027 ·
I maintainer di solito rispondono entro 1 giorno
-
fix(producer): propagate useGpu to HDR layered streaming encoderForse già presa @Monster-GM l’ha presa 2 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 87/100
heygen-com/hyperframes#5002 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
heygen-com/hyperframes#4702 · 1 commento · 1 reazione ·
I maintainer di solito rispondono entro 1 giorno
-
Studio catalog prompt editor has no accessible nameForse già presa @lorenzozanee l’ha presa 12 giorni fa. Apertabug difficulty/easy triage/ready
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
heygen-com/hyperframes#4384 ·
I maintainer di solito rispondono entro 1 giorno
-
lint: validate composition variables declared on supported root elementsForse di nuovo libera Una pull request per questa issue è stata chiusa senza essere unita. Apertabug difficulty/easy triage/ready
Difficoltà 2/5 1-3 ore Idoneità per principianti 88/100
heygen-com/hyperframes#4383 ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di heygen-com/hyperframes
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 85/100
umbraco/Umbraco-CMS-MCP-Dev#512 ·
I maintainer di solito rispondono entro 1 giorno
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
wimpysworld/sidra#290 ·
I maintainer di solito rispondono entro 1 giorno
-
defuFn invokes function values for inherited default propertiesForse già presa @xiehuanyi l’ha presa oggi. Aperta
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 85/100
-
feature request good first issue
Difficoltà 2/5 1-3 ore Idoneità per principianti 85/100
TabularisDB/tabularis#853 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 Meno di un'ora Idoneità per principianti 85/100
capricorn86/happy-dom#2474 ·
I maintainer di solito rispondono entro 2 giorni