fix: make subtitle burn-in diagnosable and multilingual - #120
Conversation
There was a problem hiding this comment.
All reported issues were addressed across 6 files
Reply with feedback, questions, or to request a fix.
Fix all with cubic | Re-trigger cubic
A font name containing a comma, apostrophe, backslash, or control character could terminate the force_style argument or inject extra ASS style fields. Reject those up front and cover it with a regression test.
There was a problem hiding this comment.
All reported issues were addressed across 2 files (changes from recent commits).
Reply with feedback, questions, or to request a fix.
Fix all with cubic | Re-trigger cubic
Only validate the EDL subtitle_font override when subtitles are actually burned in, so --no-subtitles or a missing EDL subtitles path no longer fails on a field that will not be used. Convert the ValueError into a SystemExit so an invalid font override prints a message instead of a traceback, matching the existing libass check.
|
Both flagged, thanks. Handling them separately since one was already closed out: The The second one is fair and is fixed in 591beac. Two problems, both real:
Existing render tests still pass. |
There was a problem hiding this comment.
All reported issues were addressed across 1 file (changes from recent commits).
Tip: Review your code locally with the cubic CLI to iterate faster.
Fix all with cubic | Re-trigger cubic
A bad font config now fails before the expensive render work, gated on actual burn-in intent so --no-subtitles never trips on it.
There was a problem hiding this comment.
1 issue found across 1 file (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="helpers/render.py">
<violation number="1" location="helpers/render.py:687">
P3: A non-string JSON `subtitle_font` (e.g. a number or `true`) makes `re.search` raise `TypeError`, which the surrounding `except ValueError` does not catch, so the render aborts with a raw traceback instead of the clean diagnostic this PR is meant to provide. Consider normalizing/asserting `isinstance(font_name, str)` before validating, or widening the catch.</violation>
</file>
Tip: Review your code locally with the cubic CLI to iterate faster.
Fix all with cubic | Re-trigger cubic
| subs_path = None | ||
| if args.build_subtitles or subs_path is not None: | ||
| try: | ||
| subtitle_force_style = build_subtitle_force_style( |
There was a problem hiding this comment.
P3: A non-string JSON subtitle_font (e.g. a number or true) makes re.search raise TypeError, which the surrounding except ValueError does not catch, so the render aborts with a raw traceback instead of the clean diagnostic this PR is meant to provide. Consider normalizing/asserting isinstance(font_name, str) before validating, or widening the catch.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At helpers/render.py, line 687:
<comment>A non-string JSON `subtitle_font` (e.g. a number or `true`) makes `re.search` raise `TypeError`, which the surrounding `except ValueError` does not catch, so the render aborts with a raw traceback instead of the clean diagnostic this PR is meant to provide. Consider normalizing/asserting `isinstance(font_name, str)` before validating, or widening the catch.</comment>
<file context>
@@ -681,6 +682,13 @@ def main() -> None:
subs_path = None
+ if args.build_subtitles or subs_path is not None:
+ try:
+ subtitle_force_style = build_subtitle_force_style(
+ edl.get("subtitle_font")
+ )
</file context>
Subtitle burn-in currently reaches the final compositing pass before discovering that the selected ffmpeg lacks the libass-backed
subtitlesfilter, so the documented default Homebrew installation wastes the earlier render work and ends in an opaqueCalledProcessError. The same path always forces Helvetica, which prevents a project from selecting a font with glyph coverage for CJK and other non-Latin scripts. The EDL and skill documentation expose a subtitle file but no font override, despite describing subtitle styling as customizable. The issue also proposes language-aware cue chunking, but that distinct segmentation behavior is outside this plan's explicitly declared partial scope.Summary by cubic
Add a production-used ffmpeg capability check in
helpers/render.pyand run it before segment extraction whenever the requested render will burn an existing EDL subtitle file or build subtitles, while preserving--no-subtitlesand subtitle-free renders; on failure, exit cleanly with the missing-libass diagnosis and installation/PATH guidance. Replace the fixed font portion of the force style with an EDL-levelsubtitle_fontoverride that retains the current Helvetica default and all proven geometry, color, and safe-zone values, then pass the resolved style through the existing final-composite call path. Document the new EDL field and require projects with non-Latin captions to choose an installed, script-compatible font rather than relying on a platform-specific global default.Test
--build-subtitleswith an ffmpeg filter listing that lacks an exactsubtitlesentry exits before segment extraction and reports that a libass-enabled ffmpeg is required, including actionable macOS PATH guidance rather than a traceback.--no-subtitles, an EDL with no subtitle request, and an EDL whose configured subtitle file is absent retain their current skip/warning behavior without requiring libass.subtitlesfilter passes capability detection without being confused by unrelated text, and a failed ffmpeg capability probe produces the same controlled diagnostic.subtitle_fontproduces the existing Helvetica force style byte-for-byte, preserving FontSize, bolding, colors, alignment, and MarginV=90.Heiti SCchanges onlyFontNamein the final subtitles filter and leaves overlay ordering, subtitle path escaping, and all other style fields intact.install.md, and the EDL contract inSKILL.mdconsistent about libass availability,ffmpeg-fullPATH precedence, and per-project font selection.Closes #118
Summary by cubic
Adds an
ffmpegpreflight for libass subtitles and an EDLsubtitle_fontoverride so subtitle burn-in fails early with a clear message and supports multilingual fonts. Helvetica stays the default; renders without subtitles are unchanged.Bug Fixes
subtitlesfilter viaffmpeg -hide_banner -filters; on failure, exit early with install/PATH guidance (brew install ffmpeg-full, prepend toPATH).subtitle_fontis checked only when burn-in will occur; invalid names exit cleanly without a traceback.subtitles(notass/similar), avoiding false positives.subtitle_fontto preventforce_styleinjection.New Features
"subtitle_font"; passed to final compositing asforce_styleso onlyFontNamechanges. Default remains Helvetica with the same geometry, colors, and safe-zone (MarginV=90).README.md,SKILL.md,install.md) with theffmpegcapability check,ffmpeg-fullPATH precedence, and per-project font guidance for non‑Latin captions.Closes #118
Written for commit d5c41b1. Summary will update on new commits.