Local-first meeting transcription for phone recordings and exported audio/video files.
This app is intentionally small: drop an .m4a, .mp3, .mp4, .wav, etc. into a local web UI or run the CLI, then get a Markdown transcript with speaker labels that is easy to paste into AI agents.
- Private batch transcription of iPhone Voice Memos / meeting recordings.
- Speaker diarization with
pyannote.audio. - Apple Silicon inference with
mlx-whisper. - NVIDIA/CUDA inference with
faster-whisperfor machines such as an RTX 5090. - Language hints for multilingual calls, especially English, Turkish, and Hungarian.
- Exact speaker-count hints when you know the call had 1, 2, or 3 speakers.
For best multilingual meeting quality:
- ASR: Whisper large-v3 full for important calls.
- Fast ASR: Whisper large-v3-turbo for quick drafts.
- Apple Silicon runtime:
mlx-whisper. - NVIDIA runtime:
faster-whisper/ CTranslate2 withfloat16. - Diarization:
pyannote/speaker-diarization-3.1. - Best practical setting: set the language mode and exact speaker count when known. For code-switched calls, use
tr-enorhu-eninstead of forcing only one language.
For English-only benchmarking on NVIDIA GPUs, also test NVIDIA Parakeet/Canary outside this app. They are promising, but Whisper large-v3 remains the safest baseline for multilingual meeting notes.
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .envEdit .env and set HF_TOKEN. You must accept the Hugging Face terms for:
pyannote/speaker-diarization-3.1pyannote/segmentation-3.0
Start the local UI:
./run.shOpen http://127.0.0.1:8765. The server only binds to localhost.
To expose the UI only on a trusted private interface such as Tailscale, set the host explicitly:
TRANSCRIBER_HOST=100.x.y.z ./run.shFor remote use, also set TRANSCRIBER_ACCESS_TOKEN in .env. The browser will
ask for HTTP Basic Auth with username transcriber and that token as password.
On Linux with a recent NVIDIA driver:
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements-cuda.txt
cp .env.example .envSet:
WHISPER_ENGINE=faster-whisper
FASTER_WHISPER_DEVICE=cuda
FASTER_WHISPER_COMPUTE_TYPE=float16For RTX 5090 / Blackwell, requirements-cuda.txt pins PyTorch 2.11.0+cu128
from the official PyTorch cu128 wheel index so torch recognizes sm_120.
For RTX 4090 / Ada, use the pyannote-compatible CUDA stack:
pip install -r requirements-cuda-rtx40.txtCLI example for a two-person investor call:
./cli.sh --engine faster-whisper --quality full --lang tr-en --speakers 2 call.m4aWeb UI:
./run.shTailscale/LAN UI:
TRANSCRIBER_HOST=100.x.y.z ./run.shSet TRANSCRIBER_ACCESS_TOKEN first when binding to anything other than
127.0.0.1.
CLI:
./cli.sh --lang en --quality turbo meeting.m4a
./cli.sh --lang tr-en --quality full --speakers 2 investor-call.m4a
./cli.sh --engine faster-whisper --quality full --speakers 2 meeting.m4aOutputs are saved under ./transcripts/.
The first use of a model downloads weights into the Hugging Face cache. That cache survives app restarts, but a first full-v3 run may spend several minutes downloading about 3 GB before transcription starts.
Download the quality-first MLX model ahead of time:
./prefetch.sh --quality fullDownload both MLX models:
./prefetch.sh --quality allturbomaps tomlx-community/whisper-large-v3-turboon MLX andlarge-v3-turboon faster-whisper.fullmaps tomlx-community/whisper-large-v3-mlxon MLX andlarge-v3on faster-whisper.- Turkish/Hungarian important calls should usually use
--quality fullplus--lang tror--lang hu. - Mixed Turkish/English or Hungarian/English calls should use
--lang tr-enor--lang hu-en; this avoids over-forcing one language while still giving Whisper meeting context. - Speaker labels improve when you pass
--speakers 2for two-person calls. - MLX disables
condition_on_previous_textby default because it can cause long repetition loops on difficult audio. SetMLX_CONDITION_ON_PREVIOUS_TEXT=1only if you specifically want to experiment. - Obvious Whisper repetition loops are rejected instead of being saved as finished transcripts.
This is not a Fireflies/Otter/Vexa-style meeting bot that joins Zoom, Google Meet, or Teams. It is the local, high-quality file transcription core. Projects like Vexa solve live meeting bot infrastructure; this project focuses on local files from your phone and high-quality transcripts for AI context.
app/main.py- FastAPI server.app/transcribe.py- ffmpeg, diarization, ASR, speaker assignment, Markdown output.static/index.html- local drag-and-drop UI.cli.py/cli.sh- one-shot transcription without the web server.requirements.txt- Apple Silicon default.requirements-cuda.txt- NVIDIA/CUDA default for RTX 50-series.requirements-cuda-rtx40.txt- NVIDIA/CUDA default for RTX 40-series.
The repo ignores:
.env.venv/uploads/transcripts/- caches and bytecode
Do not commit real recordings, transcripts, or Hugging Face tokens.