Make long audio searchable. podscope transcribes a podcast or recording, splits it into chapters at semantic topic boundaries, and builds a local semantic index so you can ask "when do they talk about X" and jump to the exact moment.
It combines speech recognition (Whisper) with NLP (embedding-based topic segmentation and retrieval) so a long recording becomes navigable rather than a wall of text.
podscope chapters samples/podcast.wav 00:00 Machine Learning and Software Development
00:15 Best Practices for Data Security
podscope search samples/podcast.wav "when do they talk about protecting data with encryption?" [00:15] (score 0.703) Finally, we discuss security. Always encrypt your sensitive data ...
[00:00] (score 0.551) Welcome to the Tech Podcast. Today we cover three topics.
The query says "protecting data with encryption"; the audio says "encrypt your sensitive data". Different words, same meaning — semantic search finds it where a keyword grep would miss.
audio
|
v
Whisper (segment timestamps) segments: text + start/end
|
+--> chapterize embed segments; place a boundary where
| (topic segmentation) consecutive similarity drops (topic shift);
| LLM titles each chapter
|
+--> SemanticIndex embed each segment once; cosine-match a
(jump to the moment) query and return timestamped hits
Rather than cutting every N minutes, podscope finds topic shifts: it embeds each transcript segment and places a chapter boundary where consecutive segments become semantically dissimilar (a similarity drop below a threshold), with a minimum gap to avoid over-splitting. This is a lightweight, embedding-based take on text segmentation. Each chapter gets a short LLM-generated title.
Each segment is embedded once. A query is embedded and matched by cosine similarity, returning the best segments with timestamps — meaning-based retrieval over a recording, not keyword search.
git clone https://github.com/qazasd2518995/podscope.git
cd podscope
python -m venv venv && source venv/bin/activate
pip install -e .
cp .env.example .env # add your Groq key (https://console.groq.com/keys)# list chapters
podscope chapters episode.mp3
# tune the topic-boundary sensitivity (lower = more chapters)
podscope chapters episode.mp3 --threshold 0.5
# jump to the moment
podscope search episode.mp3 "the part about funding" --top-k 3from podscope import process_audio
ep = process_audio("episode.wav")
print(ep.chapters_markdown())
for hit in ep.search("when do they mention the deadline?"):
print(hit.timestamp, hit.segment.text)| Variable | Default | Purpose |
|---|---|---|
GROQ_API_KEY |
— | required |
PODSCOPE_ASR_MODEL |
whisper-large-v3 |
use …-v3-turbo for speed |
PODSCOPE_CHAT_MODEL |
llama-3.1-8b-instant |
chapter titling |
Embeddings use fastembed (BAAI/bge-small-en-v1.5, CPU, no API).
pip install -e . pytest
pytest -q # 9 tests, fully offline (embeddings injected)Tests cover topic-boundary placement (and that coherent audio is not split), the minimum-gap guard against over-splitting, chapter titling, and semantic-search ranking.
podscope/
transcribe.py Whisper segment-level transcription
chapters.py embedding-based topic segmentation + LLM titles
search.py semantic index over segments (jump to the moment)
episode.py end-to-end: transcribe -> chapterize -> searchable
llm.py Groq chapter titling
cli.py podscope chapters | search
tests/ offline tests (embeddings injected)
samples/ a short multi-topic podcast clip
MIT