muvid.facade¶
Top-level facade — the verbs the CLI / skill / UI all call.
These are the same functions, just packaged so each one takes a
project root path (string) instead of a MusicVideoProject. They
are deliberately thin: each one resolves the project, then delegates
to the underlying module.
Functions
|
|
|
|
|
|
|
Build |
|
|
|
|
|
Interactive curate driven by a pre-recorded decisions JSON. |
|
Where a project called |
|
Return a |
|
Human-readable rendering of |
|
|
|
Create a new music video project. |
|
|
|
Render every shot. |
|
|
|
|
|
Return a summary dict of the project's current state. |
|
Run ElevenLabs Scribe on the project's song. |
|
- muvid.facade.align_lyrics(root, *, aligner='scribe-greedy', **aligner_kwargs)[source]¶
Build
lyrics/alignment.annotfrom transcript + lyrics.md.alignerselects the alignment strategy (seemuvid.align.list_aligners()); extra kwargs are forwarded to the chosen aligner. Defaults toscribe-greedy.Returns the path to the alignment store.
- Return type:
- muvid.facade.curate_character_interactive(root, name, *, decisions, k=8, recipe='person_mock', present=6, max_rounds=20)[source]¶
Interactive curate driven by a pre-recorded decisions JSON.
decisionsis either a path to a JSON file or an in-memory list, each element shaped like{"keep": [<image_id>], "reject": [...], "stop": false}. The decisions are applied in order, one per round. Useful for skill-driven flows: the agent shows the user the candidates, collects their answers, writes a JSON, and re-runs.
- muvid.facade.default_project_root(name)[source]¶
Where a project called
namebelongs by default, as an absolute path.rootis a required positional on every other verb here and onmuvid.project.MusicVideoProject, deliberately — a pipeline that guessed which project it was operating on would be worse than one that asks. But required everywhere left no code answering where a NEW project should go, so the only written-down answer lived in prose: themuvidskill and theREADMEboth said~/muvid/<song-stem>, which put a real project’s 36 MB in an app-named directory under$HOMEthat nothing owns. This is that answer in code, where it can be tested and where callers — the skill, the README, the CLI, a script — can ask instead of restating it. It creates nothing.The CLI’s
serveis the one exception to “required”: it defaultsrootto the cwd. Seemuvid/paths.py— the default is right, and it was the UI’s missing is-this-a-project precondition that made it write.- Return type:
- muvid.facade.estimate_render_cost(root, *, quality='balanced', force=False)[source]¶
Return a
muvid.cost.CostRollupfor the project’s pending shots.“Pending” is the renderer’s own definition (hash +
force), so pass the sameforceyou will render with to price what that run will actually do.
- muvid.facade.format_status(status_dict)[source]¶
Human-readable rendering of
status()’s output.Single-screen-ish: title, song, stage checkmarks, render progress bar, alignment quality summary. No colour (we don’t pull in a TTY library).
- Return type:
- muvid.facade.init_project(root, *, title='', song=None)[source]¶
Create a new music video project. Returns the absolute root path.
- Return type:
- muvid.facade.render(root, *, quality='balanced', force=False, budget=None, allow_unpriced=False)[source]¶
Render every shot. Returns the produced mp4 paths.
budget(USD): when set, refuses to start ifestimate_render_cost()exceeds it — **or if any part of the project could not be priced at all**. PassNone(CLI:--budget=-1) to skip the gate entirely.allow_unpriced: proceed despite unpriceable work, after reading what it is. The gate is otherwise TWO conditions, and the second is the one muvid#47 was filed about: a price this code could not determine contributes nothing tototal_amount, so comparing the number alone let an unpriceable shot clear any budget. Unknown is not zero.The escape exists because a threshold and an approval are different things. A hard refusal with no way past it would make
--budgetunusable for a project containing one exotic model — so the default refuses, and a caller who has read the names can accept them. What it must never become is a silent default.
- muvid.facade.status(root)[source]¶
Return a summary dict of the project’s current state.
Useful for the skill / UI to show the user where they are in the pipeline. No side effects.
Returns a structured shape with stage progression, per-shot render status, and (when an alignment store exists) a word-confidence histogram. Stable enough to be programmatic; pass through
format_status()for human-readable text.- Return type:
- muvid.facade.transcribe_song(root, *, api_key=None)[source]¶
Run ElevenLabs Scribe on the project’s song.
Writes the raw response to
lyrics/transcript.jsonand a draftlyrics/lyrics.mdwith auto-detected line breaks. The user is expected to editlyrics.mdto fix mishears and add real section tags. Returns the path to the lyrics markdown.- Return type: