SlideStream
Turn a Markdown file, a PowerPoint deck or a document into a narrated video presentation, an editable PowerPoint, or both.
Website · Documentation · Desktop app · Changelog
SlideStream writes narration that a presenter would say (not the bullets read aloud), voices it, optionally in your own cloned voice, adds pictures and a presenter in the corner, and assembles the video. It works with no account and no API keys: the voice runs offline, and every AI service is optional.
What it does
- Sources: Markdown decks (code blocks and tables included), PowerPoint
files with speaker notes, or a text, Word or PDF document turned into a
deck with
draft(the web UI also starts from a one-line idea). - Narration: written by an LLM of your choice (local Ollama or a cloud model), taken from speaker notes, or from your own script.
- Voice: offline Kokoro by default; your own cloned voice through a self-hosted Voicebox or Chatterbox server; or ElevenLabs and OpenAI.
- Pictures: text cards, your own folder, stock photos, or AI images from a local SwarmUI server or a cloud service.
- Presenter: a mascot or photo in the corner, from a still image to full lip-sync on your own GPU.
- Outputs: an MP4 video, or an editable
.pptxwith the narration in the speaker notes. - Design (experimental): designed slides through a self-hosted Presenton, with a check that the design kept your content; or keep your own PowerPoint's look.
- Check first:
slide-stream doctorestimates length, cost and render time and warns about problems before you render.
Interfaces: the slide-stream command, a web UI (slide-stream serve), a
desktop app for macOS, Windows and Linux, and a Docker image for hosting.
Install
pip install "slide-stream[all]"
[all] includes every AI provider, the offline voice, the web UI and
document import. Python 3.10 or newer. FFmpeg comes with the package; a
system install is optional. Smaller installs and every extra are listed in
the user guide.
Prefer no terminal? Download the desktop app.
Quick start
Write a deck. Each # heading starts a slide:
# Hash Tables
- Find a value without searching
- Week 6, Data Structures
# A Hash Function
```python
def bucket_for(key: str, n: int) -> int:
return hash(key) % n
```
Render it:
slide-stream create deck.md talk.mp4 # narrated video
slide-stream create deck.md deck.pptx # editable PowerPoint, narration in the notes
slide-stream create slides.pptx talk.mp4 # narrate an existing PowerPoint
That works as is. To go further, write a config file and switch providers on:
slide-stream init # a starter slidestream.yaml that works with no keys
slide-stream doctor deck.md
# slidestream.yaml
providers:
llm:
provider: ollama # writes the narration; or claude, openai, gemini, ...
model: qwen3:4b
images:
provider: swarmui # or text, local, pexels, dalle3, gemini, ...
base_url: http://localhost:7801
tts:
provider: voicebox # your cloned voice; falls back to Kokoro offline
base_url: http://localhost:17493
voice_sample: ./my_voice.wav
API keys come from the environment, never the file.
Commands
| Command | Does |
|---|---|
create IN OUT |
Render a video (.mp4) or a deck (.pptx) |
doctor IN |
Preflight: estimates and warnings, no rendering |
draft DOC OUT.md |
Turn a text, Word, PDF or PowerPoint file into a Markdown deck |
enrich IN DIR |
Add a picture (and optionally AI speaker notes) to every slide |
presenton IN OUT |
Designed deck through Presenton (experimental) |
scan DIR |
Name a folder of pictures so slides can find them |
serve |
Web UI in the browser |
init |
Write a config file |
providers, voices, avatars |
List what is available |
slide-stream COMMAND --help lists every option.
Documentation
- Use cases: recipes for common jobs (your own voice, a presenter, PowerPoint with notes, designed decks, self-hosting)
- User guide: install, configuration, deck format, every command
- Providers: every voice, picture, LLM, presenter and design option
- Services: the self-hosted engines, their licences and how they are checked
- Roadmap and user stories
- Hosting with Docker
Privacy
Everything can run on your own machine or servers. A voice sample or photo you upload is used for that render only and then deleted, on your server and in the web UI. The only network calls are to the services you configure.
Contributing
Development uses uv:
git clone https://github.com/michael-borck/slide-stream.git
cd slide-stream
uv sync --all-extras --group dev
uv run pytest && uv run ruff check . && uv run basedpyright
See the development workflow and the architecture decisions.
Acknowledgements
SlideStream builds on MoviePy, python-pptx, Kokoro, Pygments, pypdfium2, Typer and Rich, and can call Presenton, Voicebox, ComfyUI, SwarmUI and Ollama. Credits and licences for every engine are in SERVICES.
License
MIT. See LICENSE.
Metadata
Release files for slide-stream 2.16.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| slide_stream-2.16.1.tar.gz | 1.1 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| slide_stream-2.16.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 1.5 MB
Release files / slide_stream-2.16.1.tar.gz
| Download URL | slide_stream-2.16.1.tar.gz |
|---|---|
| Size | 1.1 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
27170fb4b0f582c638f229c67fa25dad321e7df92f081ebeca8c5e9cfb2f1c71
|
|
BLAKE2b-256 checksum How to use checksums |
eebfe8946b42969c20a5dc70241ae3baae93a885f9f345f103e6521f94493e16
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.0
|
Release files / slide_stream-2.16.1-py3-none-any.whl
| Download URL | slide_stream-2.16.1-py3-none-any.whl |
|---|---|
| Size | 469.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f6e0dc780b394fda04c0ac4103337cffe4a65eaa2898f2c9c40e93d09c729ee1
|
|
BLAKE2b-256 checksum How to use checksums |
6dde6bf6a103ac1bc3c20f70efc9217817d469273e20c0ef916ea6b0c58c34a1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.0
|