HDR render composites elements without data-start under the HDR video (captions and overlays vanish)
メンテナーはふだん 1 日以内に返信
評価
- 難易度
- 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
hyperframes render . -o auto.mp4 --fps 30(auto picks HDR: log shows"effectiveHdr":"hlg"andcapture_hdr_layered)hyperframes render . -o sdr.mp4 --fps 30 --sdr- 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
- 平均マージ
- 8時間 49分
- マージ済み PR(30日)
- 667
環境構築
このプロジェクトには開発コンテナ、Dockerfile、コントリビューションガイドがありません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
heygen-com/hyperframes のほかの issue
-
product-launch-video: assemble-index.mjs is not idempotent — a second run drops every approved frame video対応中かも @Dante-dan が 1 日前に担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
heygen-com/hyperframes#5733 ·
メンテナーはふだん 1 日以内に返信
-
gsap_tween_tail counts GSAP's force3D and autoRound flags as properties対応中かも @rudycelekli が 2 日前に担当しました。 オープンbug triage/needs-triage
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
heygen-com/hyperframes#5683 ·
メンテナーはふだん 1 日以内に返信
-
Timeline: show a clip's full name when its label is cut off対応中かも @DanielMcSheehy が今日担当しました。 オープンdesktop-candidate difficulty/easy enhancement good first issue help wanted triage/ready
難易度 2/5 1〜3時間 初心者へのやさしさ 85/100
heygen-com/hyperframes#5582 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
Studio: press ? to open the keyboard shortcuts panel対応中かも @B-Payal が 4 日前に担当しました。 オープンdesktop-candidate difficulty/easy enhancement good first issue help wanted triage/ready
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
heygen-com/hyperframes#5580 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
remotion-to-hyperframes: Easing.cubic is mapped to power3 (quartic); cubic is power2対応中かも @user-github-me が 4 日前に担当しました。 オープンdifficulty/easy documentation help wanted triage/ready
難易度 1/5 1時間未満 初心者へのやさしさ 88/100
heygen-com/hyperframes#5538 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
heygen-com/hyperframes の issue をすべて見る
似ている issue
-
documentation
難易度 2/5 1〜3時間 初心者へのやさしさ 74/100
components-web-app/docs#260 ·
-
難易度 1/5 1時間未満 初心者へのやさしさ 65/100
521xueweihan/HelloGitHub#4025 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
ctrf-io/playwright-ctrf-json-reporter#117 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
voidzero-dev/void#478 ·
メンテナーはふだん 1 日以内に返信