Skip to content

feat(LyricOverlay): fps and duration props, optional soundtrack, orientation-safe layout - #662

Merged
calesthio merged 1 commit into
OpenMontageInc:mainfrom
mynetfocus:mc/lyric-overlay
Nov 8, 2026
Merged

calesthio merged 1 commit into
OpenMontageInc:mainfrom
mynetfocus:mc/lyric-overlay

Conversation

@mynetfocus

Copy link
Copy Markdown
Contributor

Summary

LyricOverlay hardcoded its frame rate and its length, and had no way to play a soundtrack. That makes it hard to use for anything but the fixture it shipped with: a 25 fps song rendered at 30, and the composition's duration had to be edited in source.

This adds calculateLyricOverlayMetadata so fps and duration come from the props, an optional soundtrack, and a lyric band that holds up in portrait as well as landscape.

Related issue

None.

Changes

  • calculateLyricOverlayMetadata derives durationInFrames and fps from the props, so the composition no longer fixes either in source.
  • Optional soundtrack, with the video's own audio kept at a settable volume.
  • Lyric band sizes and wraps from the frame's short side rather than a landscape assumption, so portrait renders no longer overflow.
  • Soundtrack is exported from CinematicRenderer so compositions share one implementation instead of each growing their own.

Testing

  • Rendered portrait (1080×1920) on the video's own audio and landscape (1920×1080) muted under a soundtrack; lyric lines land in the band in both, and the mid-fade frame is identical at 30 and 60 fps.
  • A spec whose audio is entirely silent is refused before rendering rather than producing a silent video.
  • tsc --noEmit clean on this branch against remotion-composer's own tsconfig (strict: true).

Checklist

  • The change is focused on a single logical concern.
  • I ran the relevant tests locally (make test-contracts / make test) where applicable. — those run pytest tests/, the Python side; this is TypeScript only, inside remotion-composer/, which those suites do not cover.
  • I updated docs/README if behavior or usage changed. — props are additive and default to the previous behaviour.
  • No unrelated files (build artifacts, local config) are included in the diff.

…n-safe layout

calculateMetadata reads fps (24/25/30/50/60, else 30) and durationSeconds
(else 28 s); size stays with the composition default or --width/--height.
Fade/underline/visibility constants are scaled from 30 fps frames, and a
line's fade-out ends at the next line's in-time so back-to-back lines never
stack. Layout scales from the frame's short side, the readability backdrop
runs to the bottom edge (it ended in a hard line), explicit line breaks are
kept, and the video is cover-fitted with optional trim and volume. An optional
soundtrack reuses CinematicRenderer's Soundtrack, now exported unchanged.

Behaviour change for existing props: objectFit cover, pre-line text, and the
backdrop geometry. Defaults for fps and duration are unchanged (30 fps, 840 frames).

Measured: stills at mid fade-in, mid fade-out and a contiguous boundary are
PSNR inf for 30 vs 24 and 30 vs 60 fps (portrait and landscape; text present,
25.1 dB from an empty frame). 25 fps distinct-colour source at fps 25 -> 0
repeated frames in 90 (fps 30 control: 17). Soundtrack reaches the output.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
(cherry picked from commit 87c99c7c955f0b639471ba69042060c5120e0bbf)

@calesthio calesthio left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for extending LyricOverlay with metadata-driven fps/duration, footage trimming and soundtrack reuse. Reviewed all three changed files against current main: defaults remain 30 fps/28 seconds, animation constants scale by fps, the composition registers calculateMetadata, and video/audio options pass through to the existing media components. The next-line clamp and portrait/landscape scaling are coherent. Static review only on this host: the Remotion node dependencies are absent, so I did not claim a TypeScript build or visual render. Please retain representative short/back-to-back lyric renders in the normal render validation.

@calesthio calesthio closed this Nov 7, 2026
@calesthio calesthio reopened this Nov 7, 2026
calesthio pushed a commit that referenced this pull request Nov 8, 2026
@calesthio
calesthio merged commit 0c6a492 into OpenMontageInc:main Nov 8, 2026
1 check passed
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.

2 participants