Skip to content

fix(producer): honor disabled looping for finite-loop GIF inputs - #3943

Open
kapelame wants to merge 1 commit into
heygen-com:mainfrom
kapelame:codex/hyperframes-gif-loop-override
Open

kapelame wants to merge 1 commit into
heygen-com:mainfrom
kapelame:codex/hyperframes-gif-loop-override

Conversation

@kapelame

Copy link
Copy Markdown

What

A GIF with finite loop metadata still repeats when authored with data-loop="false". A two-frame, 0.4-second GIF with a loop count of 3 repeats three times inside a two-second clip instead of playing once and holding its last frame.

Why

GIF preparation resolves data-loop to a boolean that treats an explicit false and an absent override identically. The finite-loop branch then applies the source metadata in both cases. Removing the generated video's native loop attribute cannot undo the repetitions already baked into its WebM source.

How

Keep the nullable authored override through playback planning. Source loop counts apply only when no valid override was authored. Existing infinite-loop expansion and default finite-loop behavior remain covered by the surrounding tests.

Test plan

Standalone branch, based on f6041d7597c8c53d381d4c27feb86b305b3317a4:

  • bun install --frozen-lockfile --ignore-scripts completed with an independent dependency tree.
  • bun test packages/producer/src/services/animatedGifPrep.test.ts packages/producer/src/services/htmlCompiler.animatedGif.test.ts: 10 pass, 0 fail, 47 assertions. The regression covers explicit data-loop="false" with both infinite and finite source loop metadata; the existing default finite-loop test remains unchanged.
  • Recursive import resolution checked 193 local workspace files and 423 workspace import edges. Both test entry points and the implementation resolve inside this standalone worktree, with no imports from the combined audit worktree and no producer/CLI build output reused. Only build output from unchanged dependency packages was copied.
  • bunx oxlint packages/producer/src/services/animatedGifPrep.ts packages/producer/src/services/animatedGifPrep.test.ts, bunx oxfmt --check packages/producer/src/services/animatedGifPrep.ts packages/producer/src/services/animatedGifPrep.test.ts, and git diff --check pass.
  • Unmodified pre-commit and commit-msg hooks passed: staged lint/format, tracked-artifact and large-file checks, fallow audit --base origin/main --fail-on-issues, Core/Studio/scripts type checks, and commitlint. Fallow reported advisory clone warnings but passed its new-issues gate.
  • Documentation updated (not applicable; restores the existing override contract).

Prior combined audit

The regression was first reproduced against the base implementation (Expected: 1, Received: 3). An actual FFmpeg GIF transcode changed from 3 iterations plus a 0.8-second final-frame hold to 1 iteration plus a 1.6-second hold; both outputs were 2.000-second VP9 WebM. These before/after runs belong to the prior audit, not this standalone branch.

Earlier in the audit, the full workspace build passed while the separate initialization fix was still being completed. All workspace typechecks subsequently passed with the GIF and initialization fixes applied. The engine suite (1,737 tests, 3 skipped) and producer Bun unit lane (662 tests) also passed before the download fix was added. After adding that fix, the final combined checkout passed the CLI build/typecheck, repository lint/format checks, and CLI suite (3,213 tests, 3 skipped). These broader results were not rerun as whole-workspace gates on this standalone branch; its direct regression validation is the focused run above.

The prior full workspace run was not green on macOS arm64 / Node 25.9.0 / FFmpeg 8.1.1: an existing AAC loudness integration assertion also failed using the base implementation, browser suites encountered Node 25 native Web Storage behavior, and a producer integration expectation requires Linux BeginFrame capture. Linux/Windows CI, cloud adapters, and large-composition visual regression renders were not exercised locally.

Additional verification of the final combined state: after confirming that the original audit checkout contained exactly the three reviewed patches on f6041d7597c8c53d381d4c27feb86b305b3317a4, HYPERFRAMES_NO_TELEMETRY=1 bun run build and HYPERFRAMES_NO_TELEMETRY=1 bun run --filter '*' typecheck were rerun and both passed. Before/after source and diff hashes are identical. These new whole-workspace results cover the final three-fix combination; this standalone branch's own focused tests and hook checks remain documented separately above.

Current-upstream integration check: the three reviewed patches were also applied to a separate checkout of a0a6244be7a40956c5343f5846609e584ee5c6b5. With independent dependencies and a freshly rebuilt current Core runtime, 388 focused tests passed: audio route/transport (97), capture classification (19), render orchestration (222), GIF preparation/compiler (10), and init/download (40). A real local Chrome/FFmpeg smoke check reused the init-generated audio element in a minimal two-second scene with a finite-loop GIF and data-loop="false"; output was 160×90 H.264/AAC, 10 frames, 2.000 seconds, with one GIF playback and a 1.6-second tail hold. The screenshot retry branches were checked by unit tests, not an injected browser failure. Source/diff hashes remained unchanged. This verifies the combined patches against that upstream SHA; the independent commit and its original base remain unchanged.

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