I'm finding that I sometimes don't have time to take notes when I need to, but I often times can record audio. Maybe it's just a random thought I need to capture, or a full conversation crafting a complex system, it doesn't really matter what but if I'm not actively taking notes I'm forgetting things. Fortunately there are always solutions, and automatic speech recognition has gotten stupidly good recently. While I might not love OpenAI their whisper ASR is absurdly good and lightweight. So much so that I can just throw it on any old random box I happen to have at hand.
I've technically been able to do that for a while, I could have paid for some type of software subscription prior to the creation of whisper, but I wouldn't have. I don't like the idea of private audio being fed into someone else's system to be processed. In my mind this is a net win on the privacy front, unlocking a useful workflow without trading away my privacy in the process.
And it's stupidly easy to setup.
Assuming you're on Alpine you only really need two packages installed, everything else is covered by busybox.
apk add ffmpeg whisper.cpp
And a quick and dirty shell script gets you 90% of the way there. All this is really missing is some usage information and a couple of guard rails, but it seriously does boil down to fetching a model, converting the audio to WAV, and letting whisper do its thing.
#!/bin/ash
m4a=$1
cached=~/.local/share/transcribe
repo=https://huggingface.co/ggerganov/whisper.cpp/resolve/main/
model=ggml-large-v3-turbo.bin
if [ ! -f $cached/$model ]; then
if [ ! -d $cached ]; then
mkdir -p $cached
fi
wget $repo/$model \
-O $cached/$model \
-U "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
fi
if [ ! -f $cached/$m4a.wav ]; then
ffmpeg \
-i $m4a \
-ar 16000 \
-ac 1 \
-c:a pcm_s16le \
$cached/$m4a.wav
fi
whisper-cli \
-m $cached/$model \
-f $cached/$m4a.wav \
-t $(($(nproc) - 1)) -l en -otxt
I tested this one two different systems and got roughly similar results. On my Kimsuffi I have an Intel(R) Xeon(R) CPU E3-1270 v6 which is what the output below derives from. I fed about 50 minutes of audio into the model and it took about 15 minutes longer to process. I ran the same test on a more modest i5-8500T desktop and got roughly the same results.
output_txt: saving output to '/root/.local/share/transcribe/20261019_120025.m4a.wav.txt'
whisper_print_timings: load time = 477.05 ms
whisper_print_timings: fallbacks = 0 p / 0 h
whisper_print_timings: mel time = 4163.97 ms
whisper_print_timings: sample time = 96280.29 ms / 76416 runs ( 1.26 ms per run)
whisper_print_timings: encode time = 2972497.00 ms / 174 runs ( 17083.32 ms per run)
whisper_print_timings: decode time = 15572.55 ms / 712 runs ( 21.87 ms per run)
whisper_print_timings: batchd time = 524741.75 ms / 74837 runs ( 7.01 ms per run)
whisper_print_timings: prompt time = 325581.84 ms / 39076 runs ( 8.33 ms per run)
whisper_print_timings: total time = 3942936.50 ms
What's neat though is that this workflow is super efficient, the more cores you can throw at it the faster it'll run, and if you have a gpu it's probably stupidly fast. I haven't actually tested that since the system in my homelab with an actual GPU in it is way too noisy for silly experimental automation.
real 1h 5m 43s
user 7h 35m 38s
sys 1m 15.23s
Now the down side is that the transcription is only as accurate as your audio quality, vocabulary, and pronunciation allows. It stumbles a lot on technology terms from what I've seen, but it guesses phonetically so you can generally get close enough of a transcription to correct after the fact, or to grep through and find our when in a multi hour recording you discussed a certain topic so you can re-listen to it.
Honestly just a cool little tool with an immediately obvious use case and impact, so I figured I'd share.