Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

HDR render composites elements without data-start under the HDR video (captions and overlays vanish)

未关闭
#5,102 1 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

@Dante-dan 已经在做这个了。

开始于 2026年10月7日。

  • #5183 来自 @Dante-dan —— 未关闭

评估

难度
4/5
预计耗时
3-5 天
新手友好度
58/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
活跃
技术栈
html, typescript
领域
backend

调研方向

Start by locating the bundled engine’s queryElementStacking and groupIntoLayers functions mentioned in the issue, then trace the HDR layered-render path and its existing tests. Use the provided HLG reproduction to verify that an untimed caption above the video remains visible in HDR, while the timed-caption control still works; also check that --sdr behavior is unchanged.

由索引模型根据 Issue 内容生成。

描述

Describe the bug

When a render takes the HDR layered path (any video tagged HLG or PQ, which includes every iPhone clip shot with HDR on), elements that have no data-start attribute are composited underneath the native HDR video, whatever their z-index. In the output the video covers them: captions, titles and overlays disappear. Preview and --sdr renders are correct.

Cause, from reading the bundled engine: queryElementStacking builds the layer list from document.querySelectorAll("[data-start]") only, and groupIntoLayers sorts that list by effective z-index. An element without data-start never gets its own entry, so it never lands in a DOM layer above the HDR video. It only shows up as part of a layer below it (or the base), and the HDR video frame is then blitted over it.

This is easy to hit in practice: the desktop app's own takeover-explainer format drives its captions, hook titles, screenshot cards and logos with GSAP on plain elements (#tx-caps at z-index: 4, #tx-hook at 5, #tx-cards at 3, and so on, none with data-start), above a .tx-plate-wrap video at z-index: 2. Shot on an iPhone, the exported reel loses all of them while the preview looks right. The desktop Export has no SDR option, so a desktop user cannot work around it without re-encoding their footage.

Minimal reproduction
mkdir -p repro/assets && cd repro
# 3 s test pattern carrying HLG tags (tags alone switch the render to HDR)
ffmpeg -f lavfi -i "testsrc2=s=540x960:r=30:d=3" \
  -vf "setparams=color_primaries=bt2020:color_trc=arib-std-b67:colorspace=bt2020nc,format=yuv420p" \
  -c:v libx264 -x264-params "colorprim=bt2020:transfer=arib-std-b67:colormatrix=bt2020nc" \
  -color_primaries bt2020 -color_trc arib-std-b67 -colorspace bt2020nc assets/hlg.mp4

index.html:

<!doctype html>
<html lang="en"><head><meta charset="utf-8"><title>hdr overlay repro</title>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/gsap.min.js"></script>
<style>
  html, body { margin: 0; padding: 0; background: #000; }
  #root { position: relative; width: 540px; height: 960px; overflow: hidden; background: #000; }
  .wrap { position: absolute; inset: 0; z-index: 2; }
  .wrap video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
  #caps { position: absolute; inset: 0; z-index: 4; }
  .cap { position: absolute; left: 70px; top: 700px; width: 400px; height: 120px; background: #FF00FF; }
</style></head>
<body>
<div id="root" data-composition-id="main" data-width="540" data-height="960" data-duration="3" data-fps="30">
  <div class="wrap"><video id="plate" data-start="0" data-duration="3" data-track-index="0" src="assets/hlg.mp4" muted playsinline></video></div>
  <div id="caps"><div id="cap" class="cap"></div></div>
</div>
<script>window.__timelines = window.__timelines || {}; window.__timelines["main"] = gsap.timeline({ paused: true });</script>
</body></html>

Control: give the caption timing (<div id="cap" class="cap clip" data-start="0" data-duration="3" data-track-index="1"></div>) and the same HDR render is correct.

Steps to reproduce
  1. hyperframes render . -o auto.mp4 --fps 30 (auto picks HDR: log shows "effectiveHdr":"hlg" and capture_hdr_layered)
  2. hyperframes render . -o sdr.mp4 --fps 30 --sdr
  3. Sample the caption area at t=1.5 s in both, e.g. ffmpeg -ss 1.5 -i auto.mp4 -frames:v 1 -vf "format=rgb24,crop=1:1:270:760" -f rawvideo - | xxd -p
Expected behavior

The magenta caption (#caps, z-index: 4) draws above the video (.wrap, z-index: 2) in both renders, as it does in preview and in --sdr. Elements without data-start take part in the stacking order like any other element.

Actual behavior
auto (effectiveHdr hlg)   caption pixel #020ffc   <- test pattern: the video covers the caption
--sdr                     caption pixel #fc00fd   <- caption on top
caption with data-start   caption pixel #ff00fe   <- correct in HDR too

Things I ruled out on the way, each rendered correctly in HDR as long as the overlay had data-start: a transformed/scaled video wrapper, clip-path: inset(...) and filter on the wrapper, a second video sharing the same source at opacity 0, a z-index: 1 background layer under the video, and overlays that start opacity: 0; visibility: hidden and are revealed with autoAlpha. On the real takeover-explainer reel, removing the second video, the clip-paths, the filters or the transforms (one at a time) did not help either; adding nothing but HLG tags to the plate is what breaks it, and converting the plate to bt709 fixes it.

Environment
HyperFrames desktop 0.1.0 (build b269), bundled hyperframes CLI + @hyperframes/* 0.8.133
macOS 27.0.1 (26A434), Apple M1 Pro (arm64)
Rendered with the desktop's own bundled CLI and ffmpeg (no `npx hyperframes doctor`: desktop app)
Additional context

Possible fixes:

  • Build the stacking list from every rendered element in the composition root (or from paint order), not only [data-start], so untimed overlays get their own DOM layer above or below each HDR video.
  • Failing that, detect DOM that is not covered by [data-start] stacking and fall back to SDR (or warn loudly) instead of silently hiding it.
  • Give the desktop Export a Standard (SDR) option, so a desktop user has a way out.

Related, both closed: #1952 (HDR layered path froze timed overlays) and #3591 (HDR layered path ignored sub-composition windows). Same path, different defect.

Workaround for anyone hitting this: convert the footage to SDR before exporting, for example zscale=min=bt2020nc:pin=bt2020:tin=bt709:rin=tv:m=bt709:p=bt709:t=bt709:r=tv,format=yuv420p with bt709 output tags, or render from the CLI with --sdr.

主要语言
TypeScript
星标
54.1k
派生
4.9k
平均合并
7 小时 21 分钟
30 天内合并 PR
722

环境准备

这个项目没有提供开发容器、Dockerfile 或贡献指南,环境需要你自己搭建:先看它的 README,通用步骤见我们的新手贡献指南。

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

heygen-com/hyperframes 的其他 Issue

查看 heygen-com/hyperframes 的全部 Issue

相似的 Issue

更多 TypeScript Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。