Turn a list of HTML slides + narration into a narrated MP4. Headless-browser screenshots, pluggable text-to-speech, ffmpeg stitching. Bring your own slide design and voice.
Project description
slidecast
Turn a list of HTML slides + narration into a narrated MP4.
You bring the slide design — any HTML you like — and the words. slidecast screenshots each slide with a headless browser, narrates it with a pluggable text-to-speech provider, and stitches the frames into one MP4 with ffmpeg. It has no opinion about how your slides look and no hard dependency on a specific voice or browser: every piece is swappable.
Install
pip install slidecast # core (requests only)
pip install slidecast[playwright] # default renderer (headless Chromium)
pip install slidecast[gtts] # Google Translate TTS
pip install slidecast[ffmpeg] # bundled ffmpeg binary (no system install)
After installing the Playwright extra, fetch the browser once:
playwright install chromium
You also need ffmpeg — on PATH, via $SLIDECAST_FFMPEG, or the [ffmpeg]
extra's bundled binary.
Library
from slidecast import Reel, KokoroTTS
reel = Reel(width=1280, height=720, tts=KokoroTTS(voice="af_heart"))
reel.add("<!doctype html><h1>Hello</h1>", "Hello, and welcome.")
reel.add("<!doctype html><h1>Goodbye</h1>", "Thanks for watching.", tail_pad=0.8)
reel.render("out.mp4", make_poster=True)
A slide with empty narration becomes a silent hold (min_duration seconds). When
the TTS provider reports a clip duration, the segment is padded to fit the speech
exactly; when it can't (e.g. MP3), the audio drives the length.
CLI
slidecast render reel.yaml -o out.mp4 --poster
width: 1280
height: 720
fps: 25
tts:
provider: kokoro # kokoro | gtts | silent
url: http://127.0.0.1:8021/v1/audio/speech
voice: af_heart
response_format: wav
slides:
- html_file: intro.html
narration: "Before any of this, here's why it matters."
tail_pad: 0.8
- html: "<!doctype html><h1>Step one</h1>"
narration: "" # silent slide
min_duration: 3
The swappable pieces
Text-to-speech — anything with synthesize(text, path) -> seconds | None:
KokoroTTS— any OpenAI-compatible/v1/audio/speechendpoint (Kokoro, OpenAI, LocalAI, …). Defaults to WAV so the clip length is measurable.GTTSTTS— Google Translate TTS (gtts).SilentTTS— a silent track of a fixed length. No dependencies; the default, so a reel renders end to end with nothing configured.
Pass phonetic={r"\bSOC\b": "sock"} to rewrite how tricky tokens are spoken
without changing the on-screen text.
Renderer — a context manager exposing screenshot(html, path, *, width, height):
PlaywrightRenderer— headless Chromium, launched once per reel (default).ChromeBinaryRenderer— drive an existing Chrome/Chromium binary by path.
ffmpeg steps are exposed directly (build_segment, concat, poster) and
take an injectable runner, so you can compose your own pipeline or test command
construction without invoking ffmpeg.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file slidecast-0.2.1.tar.gz.
File metadata
- Download URL: slidecast-0.2.1.tar.gz
- Upload date:
- Size: 18.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
12c6bea372a8ed47911df6e8488145fc2c7785746992c3d5a8947a6415db0ce0
|
|
| MD5 |
1d7d8aa5009d226cfb7abb30c1aa8bfe
|
|
| BLAKE2b-256 |
3b562a287f90993ed1a78bdbd2e2c016ff549947047c1641ba3be8f4d62d3408
|
Provenance
The following attestation bundles were made for slidecast-0.2.1.tar.gz:
Publisher:
publish.yml on vinayvobbili/slidecast
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
slidecast-0.2.1.tar.gz -
Subject digest:
12c6bea372a8ed47911df6e8488145fc2c7785746992c3d5a8947a6415db0ce0 - Sigstore transparency entry: 2003650044
- Sigstore integration time:
-
Permalink:
vinayvobbili/slidecast@b20ac385118e97c6f1e3af8a072ee2293be24d32 -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/vinayvobbili
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b20ac385118e97c6f1e3af8a072ee2293be24d32 -
Trigger Event:
push
-
Statement type:
File details
Details for the file slidecast-0.2.1-py3-none-any.whl.
File metadata
- Download URL: slidecast-0.2.1-py3-none-any.whl
- Upload date:
- Size: 17.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cabe71c6ee00f2ea8e919071e27e6e4f1a64eb564e0815253f783ebf5a4dba45
|
|
| MD5 |
17dc6ed6b9c4ff4549f2bd192a722b02
|
|
| BLAKE2b-256 |
0072e9ca1582bcd50b23122ded26ef75a2dcfd5ebb88e17142de77ccac97190d
|
Provenance
The following attestation bundles were made for slidecast-0.2.1-py3-none-any.whl:
Publisher:
publish.yml on vinayvobbili/slidecast
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
slidecast-0.2.1-py3-none-any.whl -
Subject digest:
cabe71c6ee00f2ea8e919071e27e6e4f1a64eb564e0815253f783ebf5a4dba45 - Sigstore transparency entry: 2003650151
- Sigstore integration time:
-
Permalink:
vinayvobbili/slidecast@b20ac385118e97c6f1e3af8a072ee2293be24d32 -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/vinayvobbili
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b20ac385118e97c6f1e3af8a072ee2293be24d32 -
Trigger Event:
push
-
Statement type: