Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

Sparse-keyframe check silently skips single-keyframe videos — the worst case goes unreported (0.8.10)

Abierto
#3,460 1 comentario 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

@ravsau ya está trabajando en esto.

Desde el 15/9/2026.

  • #3538 de @rajanpanth — cerrado sin fusionar
  • #3573 de @miga-heygen — cerrado sin fusionar
  • #3576 de @miga-heygen — cerrado sin fusionar
  • #3762 de @Abhishek-kumarsingh — cerrado sin fusionar
  • #3971 de @ravsau — abierto

Evaluación

Dificultad
3/5
Tiempo estimado
1-2 días
Aptitud para principiantes
76/100
Tipo de issue
Error
Claridad
Bastante claro
Estado de actividad
Activo
Stack tecnológico
typescript

Línea de trabajo

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.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

triage/needs-triage

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).

Lenguaje dominante
TypeScript
Estrellas
54.1k
Forks
4.9k
Merge medio
7 h 21 min
PR fusionados (30 d)
722

Preparar el entorno

Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de heygen-com/hyperframes

Todos los issues de heygen-com/hyperframes

Issues similares

Más issues de TypeScript

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.