lacing.tracks.subtitle#
Subtitle / lyric / caption tracks — the (sections, lines, words) trio.
SubtitleBuilder lets callers add sections, lines, and words to a
store with float seconds and a single asset_id, instead of
hand-rolling Annotation / MediaRef / Provenance /
TimeInterval. SubtitleTrack provides matching read-side
convenience: lines_in(window), words_in(window),
sections_covering(t).
Body schemas are conventional URIs:
annot://schema/song-section/v1—{label, title?, energy?, mood?}annot://schema/lyric-line/v1—{text, line_index?, section?}annot://schema/word/v1—{text, line_index?, confidence?}(matches the built-in
lacing.bodies.wordschema)
These are not enforced unless the caller has registered Pydantic
validators for them; register_subtitle_schemas will register simple
permissive validators if you want body validation. Otherwise the body
is just a dict.
Quick start:
from lacing import MemoryStore
from lacing.tracks.subtitle import SubtitleBuilder, SubtitleTrack
store = MemoryStore()
with SubtitleBuilder(store, asset_id="song/audio.mp3") as b:
b.section("intro", 0.0, 12.5)
b.line("I came down to the river", 12.5, 16.2,
section="verse_1", words=[
("I", 12.5, 12.7),
("came", 12.7, 13.0),
("down", 13.0, 13.3),
])
track = SubtitleTrack(store, asset_id="song/audio.mp3")
chorus_lines = track.lines_in(35.0, 55.0)
section_at_42 = track.sections_covering(42.0)
Module Attributes
Mapping of body URI → minimal example body. |
Functions
Register permissive body validators for the subtitle URIs. |
Classes
|
Builder for |
|
Read-side facade for |
- lacing.tracks.subtitle.BUILT_IN_BODY_SCHEMAS: dict[str, dict[str, Any]] = {'annot://schema/lyric-line/v1': {'line_index': 0, 'section': 'verse_1', 'text': 'I came down to the river'}, 'annot://schema/song-section/v1': {'energy': 'medium', 'label': 'verse_1', 'mood': 'wistful', 'title': 'verse 1'}, 'annot://schema/word/v1': {'confidence': 0.94, 'line_index': 0, 'text': 'river'}}#
Mapping of body URI → minimal example body. Used by
register_subtitle_schemas()and as inline reference for callers building outside the builder.
- class lacing.tracks.subtitle.SubtitleBuilder(store, *, asset_id, rate=1000, was_generated_by='lacing.tracks.subtitle', was_attributed_to='lacing', ensure_tiers=True)[source]#
Bases:
objectBuilder for
(sections, lines, words)tiers over one asset.The builder is a context manager only as a convenience; it has no transactional semantics. Calling
.section()/.line()/.word()writes immediately, in the order given.- Parameters:
store (
IntervalAnnotationStore) – AnyIntervalAnnotationStore(memory, sqlite, postgres).asset_id (
str) – TheMediaRef.asset_idto attach every annotation to. Typically a path or content-hash of the audio file.rate (
int) – Tick rate for time intervals. Defaults to 1000 (ms).was_generated_by (
str) –Provenance.was_generated_by. Defaults to"lacing.tracks.subtitle".was_attributed_to (
str) –Provenance.was_attributed_to.ensure_tiers (
bool) – When True (default), creates the three tiers if they don’t exist. Pass False if your store uses different tier names and you’ve created them yourself.
- add(*, tier, body_schema_uri, body, start_s, end_s)[source]#
Add an annotation to
tierwith explicit schema/body.- Return type:
_BuiltAnnotation
- line(text, start_s, end_s, *, line_index=None, section='', words=(), extra=None)[source]#
Add a lyric line.
wordsis an optional list of(text, start, end)or(text, start, end, confidence)tuples that will be inserted on thewordstier.- Return type:
_BuiltAnnotation
- class lacing.tracks.subtitle.SubtitleTrack(store, *, asset_id, rate=1000)[source]#
Bases:
objectRead-side facade for
(sections, lines, words)over an asset.Methods take
floatseconds; conversions toRationalTimeare handled internally. Returned annotations are sorted by start time.- Parameters:
store (
IntervalAnnotationStore) – AnyIntervalAnnotationStore.asset_id (
str|None) – When set, query results are filtered to annotations whoseMediaRef.asset_idequals this value. PassNoneto ignore asset filtering (rarely what you want).rate (
int) – Tick rate used to build query intervals.