Skip to content

fix(core): prevent double-offset on pip video visibility and media sync#1083

Closed
miguel-heygen wants to merge 1 commit into
mainfrom
fix/pip-video-double-offset-visibility
Closed

fix(core): prevent double-offset on pip video visibility and media sync#1083
miguel-heygen wants to merge 1 commit into
mainfrom
fix/pip-video-double-offset-visibility

Conversation

@miguel-heygen

Copy link
Copy Markdown
Collaborator

Summary

Fixes pip-wired media elements being permanently hidden in preview when their host sub-composition starts at a non-zero time. Applies the fix consistently across all three start-time consumers in the runtime.

Root cause

resolveStartForElement adds the host composition's global start offset on top of the media element's own data-start. When a pip video has data-start="45.40" inside a host at data-start="45.40", the resolved start becomes 90.80 — well past the host's window, keeping the video permanently hidden.

Media elements authored with explicit data-start use global coordinates (matching the render pipeline's discoverMediaFromBrowser which reads the raw attribute). The resolver's local-to-global accumulation double-counts the offset for these elements.

Fix

For media elements (video/audio) without the data-hf-auto-start marker, read data-start directly as a global timestamp. Elements with data-hf-auto-start (compiler-injected data-start="0") continue using the resolver since their timing is composition-local.

Applied to all three consumers:

  • Visibility loop in init.ts
  • refreshRuntimeMediaCache start/duration resolution in init.ts
  • resolveMediaWindowEndSeconds in timeline.ts

Tests

Two new tests in init.test.ts:

  • Double-offset regression: pip video at data-start="45.40" inside host at 45.40 — visible at t=46, hidden at t=53 and t=44
  • Auto-start guard: video with data-start="0" + data-hf-auto-start inside host at 10 — visible at t=12, hidden at t=5 and t=16

All 998 core tests pass.

Attribution

Based on analysis by @JamesXiaoFF in #1078. Supersedes that PR with fixes across all three call sites and the auto-start regression guard.

When a pip-wired media element has data-start authored in global time
inside a sub-composition host, resolveStartForElement adds the host
offset a second time. Use the raw data-start for media elements without
data-hf-auto-start (explicitly authored, global coordinates) across all
three consumers: visibility loop, refreshRuntimeMediaCache, and
resolveMediaWindowEndSeconds. Auto-injected timing (data-hf-auto-start)
remains composition-local via the resolver.

Based on JamesXiaoFF's analysis in #1078.
@github-actions

Copy link
Copy Markdown

Fallow audit report

Found 62 findings.

Duplication (41)
Severity Rule Location Description
minor fallow/code-duplication packages/core/src/runtime/init.test.ts:53 Code clone group 1 (15 lines, 2 instances)
minor fallow/code-duplication packages/core/src/runtime/init.test.ts:100 Code clone group 2 (13 lines, 2 instances)
minor fallow/code-duplication packages/core/src/runtime/init.test.ts:100 Code clone group 3 (11 lines, 3 instances)
minor fallow/code-duplication packages/core/src/runtime/init.test.ts:104 Code clone group 4 (7 lines, 7 instances)
minor fallow/code-duplication packages/core/src/runtime/init.test.ts:112 Code clone group 5 (14 lines, 2 instances)
minor fallow/code-duplication packages/core/src/runtime/init.test.ts:130 Code clone group 2 (13 lines, 2 instances)
minor fallow/code-duplication packages/core/src/runtime/init.test.ts:130 Code clone group 3 (11 lines, 3 instances)
minor fallow/code-duplication packages/core/src/runtime/init.test.ts:134 Code clone group 4 (7 lines, 7 instances)
minor fallow/code-duplication packages/core/src/runtime/init.test.ts:142 Code clone group 5 (14 lines, 2 instances)
minor fallow/code-duplication packages/core/src/runtime/init.test.ts:160 Code clone group 6 (12 lines, 2 instances)
minor fallow/code-duplication packages/core/src/runtime/init.test.ts:164 Code clone group 4 (7 lines, 7 instances)
minor fallow/code-duplication packages/core/src/runtime/init.test.ts:183 Code clone group 7 (12 lines, 2 instances)
minor fallow/code-duplication packages/core/src/runtime/init.test.ts:202 Code clone group 6 (12 lines, 2 instances)
minor fallow/code-duplication packages/core/src/runtime/init.test.ts:206 Code clone group 4 (7 lines, 7 instances)
minor fallow/code-duplication packages/core/src/runtime/init.test.ts:217 Code clone group 7 (12 lines, 2 instances)
minor fallow/code-duplication packages/core/src/runtime/init.test.ts:235 Code clone group 8 (10 lines, 3 instances)
minor fallow/code-duplication packages/core/src/runtime/init.test.ts:241 Code clone group 9 (23 lines, 2 instances)
minor fallow/code-duplication packages/core/src/runtime/init.test.ts:246 Code clone group 10 (8 lines, 3 instances)
minor fallow/code-duplication packages/core/src/runtime/init.test.ts:253 Code clone group 11 (8 lines, 3 instances)
minor fallow/code-duplication packages/core/src/runtime/init.test.ts:283 Code clone group 12 (37 lines, 2 instances)
minor fallow/code-duplication packages/core/src/runtime/init.test.ts:286 Code clone group 4 (7 lines, 7 instances)
minor fallow/code-duplication packages/core/src/runtime/init.test.ts:325 Code clone group 3 (11 lines, 3 instances)
minor fallow/code-duplication packages/core/src/runtime/init.test.ts:373 Code clone group 12 (37 lines, 2 instances)
minor fallow/code-duplication packages/core/src/runtime/init.test.ts:376 Code clone group 4 (7 lines, 7 instances)
minor fallow/code-duplication packages/core/src/runtime/init.test.ts:480 Code clone group 8 (10 lines, 3 instances)
minor fallow/code-duplication packages/core/src/runtime/init.test.ts:480 Code clone group 13 (11 lines, 2 instances)
minor fallow/code-duplication packages/core/src/runtime/init.test.ts:536 Code clone group 13 (11 lines, 2 instances)
minor fallow/code-duplication packages/core/src/runtime/init.test.ts:536 Code clone group 8 (10 lines, 3 instances)
minor fallow/code-duplication packages/core/src/runtime/init.test.ts:603 Code clone group 4 (7 lines, 7 instances)
minor fallow/code-duplication packages/core/src/runtime/init.test.ts:653 Code clone group 14 (12 lines, 2 instances)
minor fallow/code-duplication packages/core/src/runtime/init.test.ts:673 Code clone group 14 (12 lines, 2 instances)
minor fallow/code-duplication packages/core/src/runtime/init.ts:754 Code clone group 15 (21 lines, 2 instances)
minor fallow/code-duplication packages/core/src/runtime/init.ts:782 Code clone group 15 (21 lines, 2 instances)
minor fallow/code-duplication packages/core/src/runtime/init.ts:1631 Code clone group 16 (14 lines, 2 instances)
minor fallow/code-duplication packages/core/src/runtime/init.ts:1908 Code clone group 16 (14 lines, 2 instances)
minor fallow/code-duplication packages/core/src/runtime/startResolver.test.ts:215 Code clone group 10 (8 lines, 3 instances)
minor fallow/code-duplication packages/core/src/runtime/startResolver.test.ts:222 Code clone group 11 (8 lines, 3 instances)
minor fallow/code-duplication packages/core/src/runtime/timeline.test.ts:364 Code clone group 9 (23 lines, 2 instances)
minor fallow/code-duplication packages/core/src/runtime/timeline.test.ts:369 Code clone group 10 (8 lines, 3 instances)
minor fallow/code-duplication packages/core/src/runtime/timeline.test.ts:376 Code clone group 11 (8 lines, 3 instances)
minor fallow/code-duplication packages/studio/src/player/hooks/useTimelinePlayer.test.ts:68 Code clone group 1 (15 lines, 2 instances)
Health (21)
Severity Rule Location Description
minor fallow/high-cognitive-complexity packages/core/src/runtime/init.ts:29 'initSandboxRuntimeModular' has cognitive complexity 22 (threshold: 15)
critical fallow/high-crap-score packages/core/src/runtime/init.ts:263 'applyClipLayout' has CRAP score 567.6 (threshold: 30.0, cyclomatic 49)
minor fallow/high-crap-score packages/core/src/runtime/init.ts:468 'resolveAuthoredCompositionDurationFloorSeconds' has CRAP score 31.6 (threshold: 30.0, cyclomatic 10)
critical fallow/high-crap-score packages/core/src/runtime/init.ts:537 'resolveRootTimelineFromDocument' has CRAP score 385.6 (threshold: 30.0, cyclomatic 40)
minor fallow/high-crap-score packages/core/src/runtime/init.ts:643 'collectRootChildCandidates' has CRAP score 37.1 (threshold: 30.0, cyclomatic 11)
major fallow/high-crap-score packages/core/src/runtime/init.ts:913 'bindRootTimelineIfAvailable' has CRAP score 71.3 (threshold: 30.0, cyclomatic 16)
minor fallow/high-crap-score packages/core/src/runtime/init.ts:969 'emitRootStageLayoutDiagnostics' has CRAP score 43.1 (threshold: 30.0, cyclomatic 12)
minor fallow/high-crap-score packages/core/src/runtime/init.ts:1073 'onError' has CRAP score 43.1 (threshold: 30.0, cyclomatic 12)
minor fallow/high-crap-score packages/core/src/runtime/init.ts:1137 'rebindTimelineFromResolution' has CRAP score 37.1 (threshold: 30.0, cyclomatic 11)
major fallow/high-crap-score packages/core/src/runtime/init.ts:1186 '<arrow>' has CRAP score 79.4 (threshold: 30.0, cyclomatic 17)
critical fallow/high-crap-score packages/core/src/runtime/init.ts:1263 'syncMediaForCurrentState' has CRAP score 268.2 (threshold: 30.0, cyclomatic 33)
major fallow/high-crap-score packages/core/src/runtime/init.ts:1289 'resolveDurationSeconds' has CRAP score 79.4 (threshold: 30.0, cyclomatic 17)
minor fallow/high-crap-score packages/core/src/runtime/init.ts:1726 'seekStandaloneRegisteredTimelines' has CRAP score 43.1 (threshold: 30.0, cyclomatic 12)
critical fallow/high-crap-score packages/core/src/runtime/init.ts:1814 'transportTick' has CRAP score 482.4 (threshold: 30.0, cyclomatic 45)
major fallow/high-crap-score packages/core/src/runtime/init.ts:1934 'hardSyncAllMedia' has CRAP score 71.3 (threshold: 30.0, cyclomatic 16)
major fallow/high-crap-score packages/core/src/runtime/init.ts:1958 '<arrow>' has CRAP score 97.0 (threshold: 30.0, cyclomatic 19)
critical fallow/high-crap-score packages/core/src/runtime/init.ts:2115 'teardown' has CRAP score 106.4 (threshold: 30.0, cyclomatic 20)
minor fallow/high-crap-score packages/core/src/runtime/timeline.ts:53 'normalizeTrackAssignments' has CRAP score 31.6 (threshold: 30.0, cyclomatic 10)
minor fallow/high-crap-score packages/core/src/runtime/timeline.ts:151 'buildTimelineClipLabel' has CRAP score 31.6 (threshold: 30.0, cyclomatic 10)
critical fallow/high-crap-score packages/core/src/runtime/timeline.ts:177 'collectRuntimeTimelinePayload' has CRAP score 212.0 (threshold: 30.0, cyclomatic 143)
minor fallow/high-crap-score packages/core/src/runtime/timeline.ts:216 'resolveMediaWindowEndSeconds' has CRAP score 31.6 (threshold: 30.0, cyclomatic 10)

Generated by fallow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant