Generate conversational podcasts from documents using AI
Project description
gencast
Generate conversational podcasts from documents using AI. A cost-effective, customisable, local-first alternative to NotebookLM.
gencast notebook.yaml -> podcast.m4a (with embedded subtitles)
Install
pip install gencast
System dependency: ffmpeg (for audio combining and M4A muxing).
API keys (export or use gencast init to be prompted):
export OPENAI_API_KEY="sk-..." # required (TTS + Whisper)
export ANTHROPIC_API_KEY="sk-ant-..." # required (default outline + transcript)
export MISTRAL_API_KEY="..." # optional (better PDF extraction)
Quickstart
gencast init # interactive notebook wizard
gencast preview notebook.yaml # outline-only dry run (free)
gencast generate notebook.yaml # full pipeline -> out/<basename>.m4a
Or one-shot from a markdown file (uses default profiles):
gencast generate path/to/lecture.md
Three-axis profile system
Each notebook composes three orthogonal profiles:
speaker_profile: revision-duo # WHO speaks (1-4 voices, personas)
episode_profile: exam-revision # WHAT kind of podcast (briefing, segments, models)
room_profile: small-room # HOW it sounds (spatial pipeline)
List bundled profiles:
gencast list-profiles --type speakers
gencast list-profiles --type episodes
gencast list-profiles --type rooms
Profiles cascade: ./gencast/profiles/<kind>/<name>.yaml (project)
~/.config/gencast/profiles/<kind>/<name>.yaml(XDG) bundled defaults. Override per-notebook viaoverrides:block in the notebook YAML.
Worked example
./photosynthesis/notebook.yaml:
title: Photosynthesis revision
sources:
- lectures/photosynthesis.md
- lectures/calvin-cycle.md
speaker_profile: revision-duo
episode_profile: exam-revision
room_profile: small-room
output:
basename: photosynthesis-revision
formats: [m4a]
overrides:
briefing_suffix: |
Pay specific attention to the distinction between the light-dependent
reactions and the Calvin cycle. Include one worked Q&A on this distinction.
gencast generate photosynthesis/notebook.yaml
# -> photosynthesis/out/photosynthesis-revision.m4a
Cost
Typical 10-min podcast (~5K-token source, 6 segments, 2 speakers):
| Component | Default model | Cost |
|---|---|---|
| Outline | claude-haiku-4-5 |
~$0.005 |
| Transcript (with prompt cache) | claude-sonnet-4-5 |
~$0.10 |
| TTS | openai/tts-1-hd |
~$0.06 |
| Subtitles | native (no Whisper) | $0.00 |
| Total | ~$0.17 |
Use --model overrides or different episode profiles to trade quality for cost.
Caches
- TTS cache --
~/.cache/gencast/tts/-- always on. Re-runs cost only changed sentences. - LLM cache --
~/.cache/gencast/llm/-- opt-in via--cache-llm. Off by default since dialogue is non-deterministic. - PDF extract cache --
~/.cache/gencast/extract/-- always on for Mistral PDF extraction.
Manage:
gencast cache status
gencast cache clear --type tts --yes
CLI reference
gencast NB.yaml generate (alias for `gencast generate NB.yaml`)
gencast init [--copy NB] [--minimal] interactive notebook wizard
gencast preview NB.yaml outline-only dry run
gencast generate NB.yaml full pipeline -> m4a + sidecars
gencast estimate NB.yaml [--json] [--no-suggestions]
predict USD cost before running. +-25% uncertainty.
gencast estimate --rates-only [--json]
dump per-1k-token rates for bundled-default models.
gencast list-profiles [--type X] enumerate profiles in cascade
gencast subtitle audio.mp3 re-subtitle external audio (Whisper)
gencast cache status [--type X] inspect cache sizes
gencast cache clear [--type X] [--yes]
Verbosity: -v, -vv, -q, --silent, --log-file PATH.
Cost preview
Predict cost before generating:
gencast estimate my-lecture.yaml
# gencast estimate -- my-lecture.yaml
# ================================================================
# Source: 12,840 tokens (1 file)
#
# Stage breakdown est. USD
# ------------------------------------------------------ --------
# Extract $0.00
# Outline claude-haiku-4-5 . 13.0k in $0.04
# Transcript claude-sonnet-4-5 . 6 segs/~1.4k $0.18
# TTS openai/tts-1-hd . ~4,500 chars $0.14
# Whisper whisper-1 . ~6.0 min $0.04
# --------
# Total: $0.40
# +-25%
#
# Cheaper alternatives
# transcript claude-sonnet-4-5 -> claude-haiku-4-5 saves ~$0.13 (-72%)
# (quality trade-off -- see docs)
For scripts and skills, use --json:
gencast estimate my-lecture.yaml --json
For the rate table only (used by Claude Code skills via dynamic context injection):
gencast estimate --rates-only --json
gencast estimate --rates-only --provider anthropic --json
gencast estimate --rates-only --all-models --json # all ~2,700 LiteLLM models
Tests
pytest tests/unit # fast, no API calls
pytest tests/component # vcrpy cassettes, no keys needed once recorded
GENCAST_TEST_E2E=1 pytest tests/e2e # real API calls, costs a few cents
GENCAST_TEST_AUDIO=1 pytest tests/audio # TTS + spatial audio (requires OPENAI_API_KEY)
Specs and design
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 gencast-1.1.0.tar.gz.
File metadata
- Download URL: gencast-1.1.0.tar.gz
- Upload date:
- Size: 49.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cb14a403be244e137bf27866ae3734430e039d0faa1e0231512362831a3daddd
|
|
| MD5 |
69edc35b5c37f87130f1e5b943e93ec9
|
|
| BLAKE2b-256 |
5432294335ce0d41c4825c70a8d1880670e0b21891fae89cd30ed8a74ec227bc
|
Provenance
The following attestation bundles were made for gencast-1.1.0.tar.gz:
Publisher:
release.yml on cadrianmae/gencast
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gencast-1.1.0.tar.gz -
Subject digest:
cb14a403be244e137bf27866ae3734430e039d0faa1e0231512362831a3daddd - Sigstore transparency entry: 1487079917
- Sigstore integration time:
-
Permalink:
cadrianmae/gencast@64e73988dce85c236242a846a77d33bf64edc97c -
Branch / Tag:
refs/tags/v1.1.0 - Owner: https://github.com/cadrianmae
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@64e73988dce85c236242a846a77d33bf64edc97c -
Trigger Event:
push
-
Statement type:
File details
Details for the file gencast-1.1.0-py3-none-any.whl.
File metadata
- Download URL: gencast-1.1.0-py3-none-any.whl
- Upload date:
- Size: 64.5 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 |
e7ce902d2ce88660b0519992c8ba794d6e0f40610f7b80db11c98faa0fc905c3
|
|
| MD5 |
38f42741d25a60e4466db534f2135d77
|
|
| BLAKE2b-256 |
c120b2795dfe8ad947afc7f55c0e79e1cc84d95068c0a37d1ec4c38ef9f98bda
|
Provenance
The following attestation bundles were made for gencast-1.1.0-py3-none-any.whl:
Publisher:
release.yml on cadrianmae/gencast
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gencast-1.1.0-py3-none-any.whl -
Subject digest:
e7ce902d2ce88660b0519992c8ba794d6e0f40610f7b80db11c98faa0fc905c3 - Sigstore transparency entry: 1487079935
- Sigstore integration time:
-
Permalink:
cadrianmae/gencast@64e73988dce85c236242a846a77d33bf64edc97c -
Branch / Tag:
refs/tags/v1.1.0 - Owner: https://github.com/cadrianmae
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@64e73988dce85c236242a846a77d33bf64edc97c -
Trigger Event:
push
-
Statement type: