Skip to content

feat(remotion-composer): CJK-aware captions and caption styling props - #507

Open
sakuraozation wants to merge 1 commit into
calesthio:mainfrom
sakuraozation:feat/cjk-caption-support
Open

feat(remotion-composer): CJK-aware captions and caption styling props#507
sakuraozation wants to merge 1 commit into
calesthio:mainfrom
sakuraozation:feat/cjk-caption-support

Conversation

@sakuraozation

Copy link
Copy Markdown

Summary

CaptionOverlay assumes space-delimited text, which breaks captions for CJK languages in three ways:

  1. A hardcoded " " is rendered between words — Japanese/Chinese don't use inter-word spaces, so captions show spurious gaps.
  2. Lines can wrap anywhere inside a word (every CJK character is a CSS line-break opportunity), producing mid-word breaks and punctuation stranded at line starts.
  3. Pages are cut every wordsPerPage words regardless of sentence boundaries, so a clause from the next sentence can leak onto the current page.

This PR makes the caption system CJK-capable while keeping the default rendering for space-delimited languages pixel-identical, and exposes the caption colors that TalkingHead previously hardcoded.

Before / after (same props, Japanese captions — the caption text itself explains the fix: "Japanese captions don't put spaces between words!"):

before after
before after

Before: spurious spaces, a break in the middle of 単語のあいだに, and a stranded ん! at a line start. After: no spaces, wraps only at word (clause) boundaries.

Related issue

None filed — happy to open one first if you prefer issue-first workflow.

Changes

  • CaptionOverlay: new wordSeparator prop (default " " keeps current behavior; CJK callers pass "").
  • CaptionOverlay: each word renders as an unbreakable inline block, so lines wrap only at word boundaries. For space-delimited text this matches the previous behavior (browsers already broke at the spaces); for CJK it prevents mid-word breaks.
  • WordCaption: optional pageBreakAfter flag; buildPages flushes the page early when set, letting callers align pages with sentence/scene boundaries.
  • TalkingHead: exposes captionColor / captionBackgroundColor (previously hardcoded inline), captionFontFamily, and captionWordSeparator. All default to the current values, so existing props files render identically.

One known limitation, by design: a single word/chunk wider than the caption box will overflow rather than break. Callers control chunk granularity (for Japanese, clause-level chunks of 2–10 characters are natural), so this hasn't been a problem in practice.

Testing

  • Stills rendered with the same Japanese props before/after (screenshots above). Rendered with the resolveAsset fix (fix(remotion-composer): resolve videoSrc through resolveAsset in TalkingHead #506) applied so the demo clip loads; the caption diff is exactly this branch.
  • Default-props render of English captions confirmed visually unchanged (separator defaults to " ", and word-boundary wrapping matches the browser's existing space-based breaks).
  • tsc --noEmit clean.
  • In production use for Japanese vertical (1080x1920) ad videos — clause-chunked captions with wordSeparator: "", pageBreakAfter on scene boundaries, and a Japanese rounded-gothic captionFontFamily.

Checklist

  • The change is focused on a single logical concern (caption i18n/styling surface of TalkingHead).
  • I ran the relevant tests locally where applicable — no TS test infra for remotion-composer; verified manually as above.
  • I updated docs/README if behavior or usage changed — props are documented inline; happy to add a README section if you'd like one.
  • No unrelated files are included in the diff.

Disclosure: this patch was developed with AI assistance, then human-reviewed and verified in production use. Happy to adjust anything to match project conventions.

CaptionOverlay assumes space-delimited text: it hardcodes a " " between
words and lets lines wrap anywhere inside a word. For CJK captions this
produces spurious inter-word spaces (Japanese does not use them) and
mid-word line breaks, including punctuation stranded at line starts.

Changes:
- CaptionOverlay: new wordSeparator prop (default " " keeps current
  behavior; CJK callers pass ""). Each word renders as an unbreakable
  inline block so lines wrap only at word boundaries - visually unchanged
  for space-delimited text, fixes mid-word breaks for CJK.
- WordCaption: optional pageBreakAfter flag; buildPages flushes the page
  early when set, so pages can align with sentence/scene boundaries
  instead of splitting a clause across pages.
- TalkingHead: exposes captionColor / captionBackgroundColor (previously
  hardcoded inline), captionFontFamily, and captionWordSeparator, all
  defaulting to the current values.

Tested by rendering TalkingHead stills with Japanese captions before and
after (screenshots in PR), and with default props to confirm the
space-delimited rendering is unchanged. Used in production for Japanese
vertical ad videos.
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