Real-time and batch speaker-diarized transcription. Local, open-source, Apple Silicon-accelerated.
- Capture audio from the mic (live) or a file (batch)
- Identify who is speaking when (anonymous:
Speaker 1,Speaker 2, ...) - Transcribe what they said
- Output: live web UI + saved
.txt/.json/.vtt/.srt+ archived.wav
| Job | Tool |
|---|---|
| ASR (live) | whisper.cpp (small/medium, Metal) |
| ASR (batch) | whisper.cpp (large-v3) |
| Diarization | pyannote.audio 3.x (batch) |
| Diarization live | diart (streams pyannote) |
| Web UI | FastAPI + WebSocket + vanilla JS |
| CLI | typer |
| Env | uv, Python 3.11 |
# 1. Install uv if needed: https://docs.astral.sh/uv/
uv sync # creates .venv with all deps
./scripts/download_models.sh # ~5.5 GB to ./models/The pyannote models are gated — accept the user agreement at
https://huggingface.co/pyannote/segmentation-3.0 and
https://huggingface.co/pyannote/speaker-diarization-3.1 with the HF
account whose token lives at ~/.cache/huggingface/token.
# Batch: process a file
uv run listener transcribe path/to/audio.wav
uv run listener transcribe path/to/audio.wav --speakers 4 --label poker-night
# Live: starts mic capture and serves UI at http://localhost:8765
# Opens browser automatically; Ctrl-C stops and writes the final transcript.
uv run listener live --label "poker-night"
uv run listener live --no-open --port 9000 # custom port, no browser
# Web UI only (no mic), to review past sessions
uv run listener serveEach run creates sessions/<timestamp>_<label>/ containing audio.wav,
transcript.txt, transcript.json, transcript.vtt, transcript.srt.
Example output (transcript.txt from a 16s synthetic two-speaker clip):
[00:00:00.050] Speaker 1: Hello there. I am the first speaker in this short test recording.
[00:00:03.480] Speaker 2: Greetings. I am the second speaker, and my voice is rather different.
[00:00:07.839] Speaker 1: Yes, quite different. We will see if the diarizer picks this up.
[00:00:11.900] Speaker 2: Indeed. Two speakers, alternating, with clean audio.
uv run pytest # all tests
uv run pytest -m "not slow" # unit tests only (~2s)
uv run pytest -m slow # end-to-end pipeline test (~10s, needs models)See docs/architecture.md.