Skip to main content

Turn any note into a narrated video. scribecast façade + vidkit engine (HyperFrames / Manim / Remotion), edge-tts narration, ffmpeg mux. CLI + library + MCP server.

Project description

scribecast

Turn any note — from gbrain, PraxVault, ksum, a file, stdin, or several merged — into a narrated video. scribecast is the façade; vidkit is the engine. Both ship in ONE pip-installable, delete-proof wheel (this repo).

note ref ──► resolver ──► script (cards) ──► render (engine) ──► narrate (edge-tts) ──► mux ──► mp4
             gbrain/vault/                    hyperframes/                              (vidkit, video
             ksum/file/stdin/merge            manim/remotion                            duration authoritative)

scribecast imports vidkit (from vidkit_core import ...) — it never shells out to a vendored copy. Note sources are read by calling the existing local CLIs (gbrain/ksum/praxvault-ask) as subprocess for note resolution only.

Install (delete-proof wheel — NOT editable)

pip install .                 # ships vidkit_core + vqkit + scribecast in one wheel
pip install .[narrate]        # + edge-tts narration
pip install .[manim]          # + manim engine (heavy, opt-in)
pip install .[all]            # narrate + manim
pip install .[test]           # pytest + pytest-xdist + coverage (for the test suite)

After install you can delete this source dir — the scribecast and vidkit CLIs keep working (verified by the delete-proof scenario; see scenarios/run_scenarios.py::s10_delete_proof). The Remotion engine additionally needs Node.js + the remotion_kit (with npm install run).

Use — three interfaces, one core

CLI (humans, Raycast, scripts):

scribecast render file:notes.md -o out.mp4              # render a file note
scribecast render gbrain:two-brain-architecture          # render a gbrain page
scribecast render file:a.md --merge file:b.md file:c.md  # merge notes into one video
scribecast render file:n.md --engine manim --voice en-GB-RyanNeural
scribecast render file:n.md --engine remotion            # 1080p React/Remotion engine
scribecast recommend file:n.md       # advisory engine pick (user always decides)
scribecast sources                   # list note sources + availability
scribecast config                    # effective config + where each value came from
scribecast -v render file:n.md       # -v = INFO logs, -vv = DEBUG (to stderr)

Library (Python):

from scribecast import render_note, resolve, recommend_engine
res = render_note("file:notes.md", out="out.mp4")        # -> RenderResult(output, engine, duration, ...)
text = resolve(["gbrain:slug-a", "file:b.md"])           # merge
rec  = recommend_engine(text)                            # advisory

MCP (any agent — Claude/Hermes/Cursor/workers):

python -m scribecast.mcp        # stdio JSON-RPC: render_note_video, recommend_engine, list_sources, list_voices

Zero mcp-sdk dependency (minimal stdio JSON-RPC) so it installs with the base wheel. Logs go to stderr (stdout is the JSON-RPC transport).

Obsidian plugin (obsidian-plugin/): render the current note from inside Obsidian. It is a thin consumer of the installed scribecast CLI (no vendoring). Commands: "Render active note to video", "Recommend engine for active note"; settings for binary path / engine / voice / output dir. Build: cd obsidian-plugin && npm install && npm run build, then copy manifest.json + main.js into <vault>/.obsidian/plugins/scribecast/.

Logging

The package uses the stdlib logging framework with library-correct discipline: importing scribecast is silent (a NullHandler is attached), so it never pollutes a host application's output. Logging is enabled by the entry points:

  • CLI: -v (INFO) / -vv (DEBUG) — records go to stderr.
  • MCP: always configured to stderr on server start.
  • env: SCRIBECAST_LOG_LEVEL=DEBUG|INFO|WARNING|ERROR. Every important path logs: note resolution (+ subprocess run/timeout/failure), engine selection, each render stage (script → render → narrate → mux → probe → done), and MCP tool dispatch + errors.

Configurable (flag > env > config-file > default)

  • config file: $SCRIBECAST_CONFIG or ~/.scribecast/config.toml
  • env: SCRIBECAST_ENGINE, SCRIBECAST_VOICE, SCRIBECAST_SOURCE, SCRIBECAST_OUT_DIR, ...
  • flags: --engine --voice --source -o ...
  • scribecast config shows the effective value AND which layer set it.

Engine selection — recommend, never decide

The selector RECOMMENDS one of hyperframes | manim | remotion from note content (math/LaTeX → manim, web/React → remotion, else hyperframes). The user's explicit --engine always wins — the recommendation is advisory and is always shown for transparency. (Heuristic today; an LLM recommender can be added without changing the user-wins contract.)

Default engine: hyperframes (cards)

The default renderer builds titled text cards with Pillow → an ffmpeg image-sequence mp4 → narration → mux. Needs only Pillow + ffmpeg (no browser, no Manim). All three engines work:

  • hyperframes (default, dep-light): Pillow text-cards → ffmpeg, 1280×720.
  • manim (opt-in [manim]): cinematic via vqkit.CinematicScene (MovingCameraScene + MathTex), 1280×720. Math/LaTeX spans render as real equations; prose renders as Text.
  • remotion (opt-in): React/Remotion ScribecastCards composition (spring entrances, gradient), 1920×1080. Needs Node + remotion_kit. License-gated for orgs > 3 (Remotion License v1).

A forced --engine that lacks its dependency raises a clear error — never a silent fallback.

Sources

source how tool
file read a local path
stdin piped text
gbrain gbrain get <slug> gbrain
vault praxvault-ask <query> praxvault-ask
ksum ksum <url|file> --no-save ksum
openmemory openmemory get <id> openmemory (optional)
merge multiple refs → one video

A missing source tool raises a clear ResolverError (never silent-empty).

Tests

pytest -q                     # 126 fast unit tests in ~1s (real-render tests deselected)
pytest -q --run-slow          # full 163 tests incl. real manim/remotion/ffmpeg renders
pytest -q --run-slow -n auto  # full set in parallel (pytest-xdist)
coverage run --source=scribecast -m pytest --run-slow && coverage report   # 100% (692/692)
python scenarios/run_scenarios.py   # 10 realistic end-to-end scenarios (pass/fail + evidence)
python scenarios/benchmark.py       # per-engine timing baseline -> scenarios/baseline.json

Real-render tests are auto-marked slow (see tests/conftest.py) and deselected by default for a fast dev loop; --run-slow runs them and the coverage gate enforces 100%. The mux-truncation regression test (tests/test_mux_no_truncation.py) proves a short narration never truncates a longer video — the bug this project fixed.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

scribecast-0.1.0.tar.gz (79.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

scribecast-0.1.0-py3-none-any.whl (68.2 kB view details)

Uploaded Python 3

File details

Details for the file scribecast-0.1.0.tar.gz.

File metadata

  • Download URL: scribecast-0.1.0.tar.gz
  • Upload date:
  • Size: 79.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.9

File hashes

Hashes for scribecast-0.1.0.tar.gz
Algorithm Hash digest
SHA256 ffd9e21cf1c0d7d704d5bf088f776061b5e01f964ad01e569d9eb93c810374a1
MD5 0e8cfd38d47b2cadad78e99132e28a79
BLAKE2b-256 2e468fd2012751e2847535e73aa2fade9627665d5c79204db1fc9d5ce29f6789

See more details on using hashes here.

File details

Details for the file scribecast-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: scribecast-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 68.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.9

File hashes

Hashes for scribecast-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 bece5f8eafed9f0b3f429bb0e0c726d84bbdcf7ee9d791cbcbafa075183988ac
MD5 d6f65829cf26e21b32020549092b1e27
BLAKE2b-256 eaf7e487b1f952b639860c539d91be7d7c58fb970c9c2f9c395824c48ab43ac6

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page