braidio.captions#

Subtitles for a rendered production, built from the script it was rendered from.

A braidio render is one of the rare cases where the caption track needs no speech recognition: the narration text is authored, and render_production() will hand back a TimelineBreakdown saying exactly when each beat plays. Transcribing the mix back into text would pay an ASR pass to recover something that was never lost – and do it worse (a measured pass on braidio’s own output turned “purse sets up hurts” into “Perse sets up herts”).

So captions_for() joins the two: beat text from the Script, beat timing from the TimelineBreakdown. Narration and dialogue beats are split into sentence-sized cues timed within their beat in proportion to length; a SegmentBeat becomes one cue carrying its reference, marked as lyric/quote.

Pure and dependency-free – part of the functional core, importable with nothing installed beyond braidio itself.

Examples

>>> from braidio.script import Narration, Script
>>> from braidio.timeline import build_timeline
>>> script = Script(title="t", id_slug="01", beats=[Narration("One. Two.")])
>>> tl = build_timeline(kinds=["narration"], durations=[4.0])
>>> print(captions_for(script, tl))
1
00:00:00,000 --> 00:00:02,000
One.

2
00:00:02,000 --> 00:00:04,000
Two.

Functions

captions_for(script, timeline, *[, max_chars])

The SRT document for script as laid out by timeline.

cues_for(script, timeline, *[, max_chars])

Subtitle cues for script as laid out by timeline.

format_srt(cues)

Render cues as an SRT document.

Classes

Cue(start_s, end_s, text)

One subtitle: [start_s, end_s) and the text shown.

class braidio.captions.Cue(start_s, end_s, text)[source]#

Bases: object

One subtitle: [start_s, end_s) and the text shown.

braidio.captions.captions_for(script, timeline, *, max_chars=0)[source]#

The SRT document for script as laid out by timeline.

Return type:

str

braidio.captions.cues_for(script, timeline, *, max_chars=0)[source]#

Subtitle cues for script as laid out by timeline.

Beats are matched by index, so a timeline built from the same script lines up even when some beats were dropped by a rights profile (a dropped beat simply has no span and contributes no cue).

Cues never overlap. That matters because the weave crossfades consecutive beats, so a beat’s start sits slightly before the previous beat’s end; left alone that produces subtitles that fight each other. Each cue is clamped to begin where the previous one finished.

Parameters:
  • script – the Script that was rendered.

  • timeline – the TimelineBreakdown from render_production(..., return_timeline=True).

  • max_chars (int) – if > 0, split sentences longer than this at whitespace, so no single cue overflows a player’s two lines. 0 leaves sentences whole.

Return type:

list[Cue]

Returns:

Cues in playback order.

braidio.captions.format_srt(cues)[source]#

Render cues as an SRT document.

Return type:

str