muvid.lyrics¶
Lyrics — transcription and markdown round-trip.
Two surfaces for the user:
transcribe(audio_path)— callsmixing.transcript.transcribe(ElevenLabs Scribe) and writes the raw word-timestamped JSON tolyrics/transcript.json. This is the seed; the user is expected to correct it.write_lyrics_md/parse_lyrics_md— the canonical, editable form. A simple markdown with[section]headers, one line per sung line, and an optional// <seconds>end-of-line anchor.
The alignment module consumes both: it reads lyrics.md for the
text the user committed to, and transcript.json for the timing
to splice in.
Functions
|
True when lyric lines are indented differently: a shape a parse would lose. |
|
What the default parse flattens, as data: |
|
The leading whitespace of each lyric line, aligned with |
|
Build a default LyricsDoc from a transcription response. |
|
Parse the user-editable lyrics markdown. |
|
|
|
|
|
Inverse of |
|
Run ElevenLabs Scribe on the audio and (optionally) write the JSON. |
|
Normalize Scribe's word entries: |
|
Classes
|
One line of lyric text, optionally with a known start time. |
|
A user-tagged section in the lyrics markdown. |
|
Full parsed view of the user's lyrics markdown. |
Exceptions
Lyric lines are indented differently, and the parse is about to drop it. |
- class muvid.lyrics.LyricLine(*, text, line_index, section_label='', start_s=None)[source]¶
Bases:
objectOne line of lyric text, optionally with a known start time.
- class muvid.lyrics.LyricSection(*, label, title='', start_s=None, end_s=None, lines=())[source]¶
Bases:
objectA user-tagged section in the lyrics markdown.
Times are optional — if not present, alignment is computed from transcripts; if present, they override.
- class muvid.lyrics.LyricsDoc(*, sections)[source]¶
Bases:
objectFull parsed view of the user’s lyrics markdown.
- exception muvid.lyrics.ShapedLyricsWarning[source]¶
Bases:
UserWarningLyric lines are indented differently, and the parse is about to drop it.
A lyrics file whose lines carry differing leading whitespace is almost always a drawn layout (a concrete poem, an Il pleut), and the default parse strips that whitespace — so the shape is gone before any archetype sees it (muvid#109). This is the signal that it happened. Uniform indentation (every line indented alike) carries no shape and does not warn.
- muvid.lyrics.indentation_varies(indents)[source]¶
True when lyric lines are indented differently: a shape a parse would lose.
- Return type:
>>> indentation_varies(["", " "]), indentation_varies([" ", " "]) (True, False)
- muvid.lyrics.layout_dropped(md)[source]¶
What the default parse flattens, as data:
Nonefor ordinary lyrics.The same test as
ShapedLyricsWarning, for a caller that cannot see a Python warning (an MCP reply, a render’s meta; muvid#165). Does not warn.>>> layout_dropped("one\ntwo\n") >>> layout_dropped("one\n two\n three\n") {'lines': 3, 'indentations': 3}
- muvid.lyrics.line_indents(md)[source]¶
The leading whitespace of each lyric line, aligned with
parse_lyrics_md(md).lines.Reads the shape the default parse strips, without changing the parse.
>>> line_indents("[v]\none\n two\n(aside)\n\tthree\n") ('', ' ', '\t')
- muvid.lyrics.lyrics_from_transcript(transcript)[source]¶
Build a default LyricsDoc from a transcription response.
Heuristic: split lines on punctuation (
. ? !) or on long pauses (>0.6 s gap between consecutive words). One[transcribed]section holds everything; the user is expected to re-tag with real sections.- Return type:
- muvid.lyrics.parse_lyrics_md(md, *, preserve_indent=False)[source]¶
Parse the user-editable lyrics markdown.
Format:
[section_label] optional title line of lyric // 12.5 another line [next section] ...Empty lines are separators between sections.
(instrumental)or any line starting with(and ending with)is treated as a non-lyric placeholder (no LyricLine emitted).Leading whitespace is stripped by default, and the result for every existing input is unchanged by that default (pinned by a golden test). When the lines are indented differently from one another — a drawn layout — stripping destroys the shape, so a
ShapedLyricsWarningsays so.preserve_indent=Truekeeps each line’s leading whitespace inLyricLine.textinstead (trailing whitespace and the//anchor are still removed), whichrender_lyrics_md()writes back verbatim and which anything displaying that text (an alignment’s line text, say) then carries. No lyric-video archetype honours indentation yet; the word tokeniser skips whitespace, so alignment is the same either way.line_indents()reads the indentation without changing the parse.- Return type:
>>> md = "[v]\nIl pleut\n des voix\n" >>> [L.text for L in parse_lyrics_md(md, preserve_indent=True).lines] ['Il pleut', ' des voix']
- muvid.lyrics.render_lyrics_md(doc)[source]¶
Inverse of
parse_lyrics_md. Stable round-trip.- Return type:
- muvid.lyrics.transcribe(audio_path, *, api_key=None, out_path=None, cache=True)[source]¶
Run ElevenLabs Scribe on the audio and (optionally) write the JSON.
Returns the raw response dict (which contains
words: [...]with per-wordtext,start,end,confidence).The on-disk Scribe cache (in
mixing.transcript) is enabled by default, so re-running on the same audio is free. Passcache=Falseto force a fresh round-trip.