Transcribe Audio Locally in Real Time with Whisper.cpp
Stream live microphone audio into accurate offline transcripts with whisper.cpp and zero cloud API calls.
What you'll build
A fully offline speech-to-text pipeline: whisper.cpp captures your microphone and prints live transcripts in the terminal, with no cloud API, no network calls, and no per-minute billing.
Prerequisites
Verified against whisper.cpp v1.9.2 (released August 4, 2026) on macOS 15 (Apple Silicon) and Ubuntu 24.04.
- macOS or Linux with a working microphone. Windows works too, but the commands below are POSIX.
- git, a C/C++ toolchain (Xcode Command Line Tools or
build-essential), and CMake 3.10+. - SDL2 — whisper.cpp uses it for microphone capture. Install it first:
# macOS
brew install sdl2
# Debian/Ubuntu
sudo apt-get install libsdl2-dev
# Fedora
sudo dnf install SDL2 SDL2-devel
- ~500 MB free disk for the repo, build, and the 142 MiB
base.enmodel.
1. Clone and build with streaming enabled
The real-time tool (whisper-stream) is only compiled when you pass -DWHISPER_SDL2=ON — a default build skips it, which is the most common reason people can't find the binary.
git clone https://github.com/ggml-org/whisper.cpp.git
cd whisper.cpp
cmake -B build -DWHISPER_SDL2=ON
cmake --build build -j --config Release
On Apple Silicon this automatically builds with Metal GPU support; on Linux you get a CPU build (add -DGGML_CUDA=1 or -DGGML_VULKAN=1 if you have the GPU toolchains installed). The binaries land in build/bin/.
2. Download a model
Whisper models come pre-converted to ggml format; the bundled script fetches them from Hugging Face:
sh ./models/download-ggml-model.sh base.en
This drops models/ggml-base.en.bin (142 MiB). base.en is the sweet spot for real-time English on modest hardware. If transcription lags behind your speech, switch to tiny.en (75 MiB); if you have GPU headroom and want accuracy, try small.en (466 MiB). Drop the .en suffix for the multilingual variants.
3. Start live transcription
From the repo root:
./build/bin/whisper-stream -m ./models/ggml-base.en.bin -t 8 --step 500 --length 5000
What the flags mean: -t 8 uses 8 CPU threads, --step 500 runs inference on new audio every 500 ms, and --length 5000 keeps a sliding 5-second window so each chunk gets enough context. Smaller --step feels snappier but costs more CPU.
For cleaner output, use VAD (voice activity detection) mode by setting --step 0 — instead of continuously re-transcribing, it waits for you to pause, then transcribes the whole utterance in one shot:
./build/bin/whisper-stream -m ./models/ggml-base.en.bin -t 6 --step 0 --length 30000 -vth 0.6
-vth is the VAD threshold; around 0.6 works in general, and higher values classify silence more aggressively. Add -f transcript.txt to also append everything to a file, and -c <ID> to pick a specific capture device from the list printed at startup.
Verify it works
You should see the capture device list, the model load, then a [Start speaking] prompt. Talk, and text appears within a second or so:
init: found 2 capture devices:
init: - Capture device #0: 'MacBook Pro Microphone'
init: attempt to open default capture device ...
whisper_init_from_file_with_params_no_state: loading model from './models/ggml-base.en.bin'
...
[Start speaking]
This is a test of local real-time transcription.
And it never touches the network.
To prove it's fully offline, turn off Wi-Fi and run it again — nothing changes.
Troubleshooting
Could not find a package configuration file provided by "SDL2" during the cmake configure step — SDL2 isn't installed (or its dev headers aren't). Install it with the command for your OS from Prerequisites, delete the build directory, and re-run both cmake commands.
error: failed to initialize whisper context — the model path in -m doesn't resolve, usually because you're not in the repo root or the download didn't finish. Check that ls -lh models/ggml-base.en.bin shows ~142 MiB and re-run the download script if not.
init: couldn't open an audio device for capture: ... or [Start speaking] appears but no text ever does — on macOS, grant your terminal microphone access (System Settings → Privacy & Security → Microphone), then restart the terminal. On Linux, confirm the mic works with arecord -d 3 test.wav && aplay test.wav.
Repeated or invented phrases during silence — Whisper hallucinates on silent audio. Use VAD mode (--step 0) so silence is never sent to the model, or raise -vth toward 0.8.
Next steps
Read the stream example docs for the full flag list (--keep, -bs beam size, --translate), then explore the repo's other examples: whisper-cli for batch-transcribing files, whisper-server for an HTTP API, and quantized models (e.g. large-v3-turbo-q5_0, 547 MiB) that bring near-large accuracy into real-time range. To embed transcription in your own app, the C header include/whisper.h is the whole API surface, with bindings for Python, Rust, Go, and more linked from the README.
Sources & further reading
- whisper.cpp README — github.com
- whisper.cpp stream example (real-time microphone transcription) — github.com
- whisper.cpp ggml models and sizes — github.com
- whisper.cpp v1.9.2 release — github.com
Priya covers AI frameworks, developer productivity tooling, and the startup ecosystem across South and Southeast Asia, bringing a researcher's rigour and a practitioner's empathy to every story. She is deeply sceptical of benchmarks and asks hard questions so her readers don't have to.
Discussion 0
No comments yet
Be the first to weigh in.