A small, resumable pipeline for turning a large podcast (or any large audio) archive into something you can actually search and ask questions of — transcription, structured summaries, semantic search, and grounded Q&A, all scripted around the OpenAI API.

Built to process 230 episodes (~145 hours of audio) for about $33 total.

Full write-up of how it works and what broke along the way: see

technical-blog.html (open it directly in a

browser, or publish it wherever you like).

Feeding a large transcript archive into an LLM's context window doesn't scale, and reading it yourself doesn't either. This pipeline gives you three ways to actually use a large audio archive:

- Structured summaries — a fast, cheap overview per episode (topics, quotes, takeaways, tone)

- Semantic search — embed everything once, then find the exact passage relevant to any question in milliseconds

- RAG-based Q&A — ask a natural-language question and get an answer grounded in, and cited to, the actual source material — no hallucinated advice

transcribe.py mp3s → transcripts/*.txt

build_index.py transcripts → index/ (embeddings + metadata)

summarize.py transcripts → summaries/*.json

ask.py question → cited answer (stdout)

analyze_themes.py summaries → themes.json (cross-corpus synthesis)

Every script only reads from the previous stage's output directory and only writes to its own — nothing is ever mutated in place, and every script skips work that's already done. That means you can kill any stage mid-run, add more source files later, or swap models between batches, and just rerun.

python3 -m venv .venv

source .venv/bin/activate

pip install -r requirements.txt

brew install ffmpeg # or your platform's equivalentCreate a .env file in the project root:

OPENAI_API_KEY=sk-...

# 1. Drop your audio files into audio-files/, then:

python transcribe.py

# 2. Generate per-episode structured summaries:

python summarize.py

# 3. Build the semantic search index:

python build_index.py

# 4. Ask questions grounded in the transcripts:

python ask.py "what did they say about X?"

# 5. (Optional) synthesize themes across the whole corpus:

python analyze_themes.pysummarize.py and analyze_themes.py both have a short constant near the

top (SHOW_DESCRIPTION, FOCUS_THEMES) you should edit to match your own

show and what you actually want extracted — they ship with generic

placeholders, not any specific podcast's content.

- Transcription defaults to gpt-4o-mini-transcribe;whisper-1also works and may transcribe slightly better for noisy audio, at roughly double the per-minute cost.

- Source files get chunked to ~15-minute, 64kbps mono segments before upload — this keeps you well under API file-size limits and works for any audio length.

- Concurrency is capped at two levels (files × chunks-per-file) to stay

under provider rate limits without going fully sequential. Tune

FILE_WORKERS/CHUNK_WORKERS_PER_FILEintranscribe.pyfor your own rate limit tier.

- The search index is a single numpyarray + JSON metadata file — no vector database needed until you're well past tens of thousands of chunks.

The actual transcripts, summaries, and embeddings produced by running this against a real show aren't included — that's someone else's copyrighted audio content, even in text form. This repo is the workflow, not any particular show's content. Point it at your own audio.

MIT — see LICENSE.