To transcribe a recording without sending it to a service, run OpenAI's Whisper speech model on your own machine. It is free, it is good, and there are three practical ways to run it: whisper.cpp in a terminal, OpenAI's own Python command, or a web page that runs it inside the browser.
Drop the recording, transcribe it, read it as a document. Nothing is uploaded.
On a Mac with Homebrew, install it and fetch an English model once:
brew install whisper-cpp
curl -LO https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-base.en.bin
Then transcribe a WAV and write subtitles next to it:
whisper-cli -m ggml-base.en.bin -f interview.wav -osrt
It prints each line with its time and saves interview.wav.srt. A phone
recording (.m4a) has to become a WAV first; see below.
What the commands actually produce
The test clip was 12.8 seconds of English speech made with macOS say, on an
M4 Pro Mac (macOS 26.5). With whisper.cpp 1.9.5 and ggml-base.en.bin:
[00:00:00.000 --> 00:00:01.680] Thanks for joining the call.
[00:00:01.680 --> 00:00:04.000] Before we start, a quick reminder,
[00:00:04.000 --> 00:00:06.480] the draft budget is due on Friday.
[00:00:06.480 --> 00:00:08.660] Maria will send the figures to the whole team
[00:00:08.660 --> 00:00:10.440] by Wednesday afternoon.
[00:00:10.440 --> 00:00:12.960] If anything is missing, tell me before then.
Every word is right. The first run took six seconds, most of it setting up the
graphics chip; after that the same clip took a third of a second. The .srt it
wrote starts like this:
1
00:00:00,000 --> 00:00:01,680
Thanks for joining the call.
2
00:00:01,680 --> 00:00:04,000
Before we start, a quick reminder,
The other switches you are likely to want:
-otxtplain text,-ovttWebVTT for web video. Combine them freely.-of meetingnames the outputmeeting.srtinstead ofinterview.wav.srt.-npprints only the transcript, without the loading chatter.-lsets the language, and it defaults to English. With a multilingual model (one without.en, such asggml-base.bin), pass-l nlfor Dutch, or-l autoto let it detect.
brew install whisper-cpp still works, but the formula is now called
whisper.cpp, and the command it installs is whisper-cli. Older guides that
say ./main or whisper-cpp predate that.
Turn a phone recording into a WAV
whisper-cli reads WAV, MP3, FLAC and OGG. Given an .m4a, which is what Voice
Memos and most phones save, it stops with failed to read audio file. Whisper
wants 16 kHz mono anyway, so convert to exactly that.
A Mac already has the converter, afconvert:
afconvert -f WAVE -d LEI16@16000 -c 1 memo.m4a memo.wav
Anywhere with ffmpeg:
ffmpeg -i memo.m4a -ar 16000 -ac 1 -c:a pcm_s16le memo.wav
Both gave a WAV that transcribed to the same six lines as above.
OpenAI's whisper command
The original, in Python. It decodes any format ffmpeg can (so .m4a is fine),
and it needs ffmpeg installed. It also pulls in PyTorch, which is a large
download.
pip install openai-whisper
whisper memo.m4a --model base.en --output_format srt
Without --model, it uses turbo, which is a 1.6 GB download and slow
without a graphics card. Without --output_format, it writes five files (txt,
vtt, srt, tsv and json).
On the same clip (openai-whisper 20250625, PyTorch 2.14.1 on the processor, in
a Linux container), it downloaded the base.en model to ~/.cache/whisper, warned
that FP16 is not supported on CPU; using FP32 instead (harmless), and wrote
the same six lines with times a few hundredths of a second different. It took
34 seconds including the download. whisper.cpp is the quicker of the two, by a
long way on a Mac.
Transcribe in the browser
The Audio Transcriber runs the same Whisper model in the page, with WebGPU (the graphics chip) in Chrome and Edge, and WebAssembly on the processor elsewhere. The recording is converted and transcribed on your computer; the only download is the model.
- Open the Audio Transcriber and drop one or more recordings on the page, or choose Add audio. MP3, WAV, M4A, OGG, FLAC, WEBM and MP4 all work.
- Choose Settings and pick the Whisper model. Tiny is the default and fine for clear speech; Base and Small are more accurate and slower.
- Set Language to the language spoken, or to Auto-detect. It starts on English. Detection can guess wrong on a short or noisy clip.
- Timestamps are shown by default. Hide timestamps, in the same panel, takes them out of the page and out of what you copy or save.
- Press Transcribe. The first time, the model downloads; after that the model picker says on this device and it starts straight away.
- The transcript opens under its file. Press Copy, or TXT to save
memo.txt. With several files, All TXT saves them in one text file.
What it gives you is plain text. With timestamps shown, each line starts with
its start time, as [00:04], one per phrase rather than per word. That is enough to find a quote in the
recording. It is not a subtitle file: for SRT or VTT, use one of the commands
above.
What it downloads
The sizes in the model picker are smaller than what is actually fetched. The model is two files, and which versions load depends on the browser:
| Model | Listed | Fetched with WebAssembly | Fetched with WebGPU |
|---|---|---|---|
| Tiny | ~44 MB | about 64 MB | about 152 MB |
| Base | ~78 MB | about 136 MB | about 291 MB |
| Small | ~250 MB | about 510 MB | about 968 MB |
These are the sizes of the files on Hugging Face that the tool asks for. It is a one-off: the model stays in the browser's cache, and a later visit only checks it is there. Clearing the site's data removes it.
Long recordings
The whole recording is decoded into memory before Whisper starts: an hour of audio becomes about 230 MB of samples, on top of the model. A long interview works on a desktop. On a phone, or for anything over an hour or two, split the file first, or use whisper.cpp.
Which to use
- Subtitles, or many recordings: whisper.cpp. It is fast, writes SRT and VTT, and a shell loop does a whole folder.
- You already use Python, or need M4A without converting: OpenAI's
whisper, with--modelset. - One recording, no installing, any device: the Audio Transcriber. Copy the text or save it as TXT.
Whichever you pick, read the transcript against the recording before you quote from it. Whisper is good, but names, numbers and crosstalk are where it slips, and it never marks a guess as a guess.