Gerris home
Gerris

Chris Abraham: technical consulting, AI tools, and technical SEO

Home › Guides › Private Transcription on Linux

How to transcribe recordings privately on your own Linux machine

Doodle: a padlocked laptop drawn in red, a green speech bubble going in, and a blue page of lines coming out

Cloud transcription services all ask for the same thing: your recording, on their servers. Client calls, interviews, and internal meetings carry material with no reason to leave your building. Two free command line tools, ffmpeg and Whisper, produce a written transcript entirely offline on ordinary Linux hardware, with speaker labels when you need them. I run this on a ThinkPad W520 from 2011, and it finishes an hour of talk in about thirty minutes.

On this page
  1. What you need
  2. Before you start: the terminal
  3. Install the tools
  4. Reduce the recording to speech
  5. Transcribe it
  6. Choose a model
  7. Speed it up on older hardware
  8. Label the speakers
  9. Make it a routine
  10. Troubleshooting

What you need

Before you start: the terminal

Every step below is a command typed into the Linux terminal. On Linux Mint, Ctrl+Alt+T opens it; on Ubuntu, the same shortcut works, or search the app menu for Terminal. Copy a command from this page, paste it at the prompt with Ctrl+Shift+V (the terminal ignores plain Ctrl+V), and press Enter. Wait for the prompt ending in $ to come back before pasting the next one.

Install the tools

Refresh the package list, then install ffmpeg, the converter, and pipx, the installer for Python programs:

sudo apt update
sudo apt install ffmpeg pipx
pipx ensurepath

The first sudo line asks for the password you log in with. The terminal shows no dots or stars as you type, by design, so type it blind and press Enter. When apt lists what it will install and asks whether to continue, press Y and Enter. pipx ensurepath adds pipx's program folder to your search path, which only takes hold in terminals opened afterward, so close this window and open a fresh one. Then install the transcriber:

pipx install whisper-ctranslate2

whisper-ctranslate2 is a command line front end for faster-whisper. It takes the same arguments as OpenAI's original Whisper program and runs up to four times faster on a CPU at equal accuracy. pipx gives it a private environment, so it never disturbs the Python your operating system relies on.

Check both tools before going further:

ffmpeg -version
whisper-ctranslate2 --help

The first prints a version banner and the second a long page of options. If either answers "command not found," repeat its install step; for the transcriber, opening a new terminal after pipx ensurepath is the usual fix.

Reduce the recording to speech

Point the terminal at the folder holding the recording. Meeting exports and screen recordings tend to end up in Videos or Downloads:

cd ~/Downloads
ls

ls shows the folder's contents, so you can copy the file name exactly. In the Linux Mint file manager, a right click on empty space inside a folder and Open in Terminal lands you in the same place.

Whisper hears every file as a single channel at 16 kHz, so converting to exactly that before transcribing loses nothing and saves a great deal of disk and transfer:

ffmpeg -i "meeting.mp4" -vn -ac 1 -ar 16000 -c:a libopus -b:a 24k -application voip "meeting.opus"

The flags remove the picture, mix to mono, set the sample rate, and encode with Opus tuned for voices. An hour lands near 11 MB; my 5.9 GB screen recording shrank by more than 99 percent. Whisper also reads video directly, but the small audio file is quicker to move, back up, and keep.

Use your own file name in place of meeting, in both spots, inside the quotes. A status line ticks forward with a time= counter during the conversion. When the prompt returns, ls -lh shows the new file and its size.

Transcribe it

whisper-ctranslate2 "meeting.opus" --model small --language en --output_format txt

The first run fetches the model from Hugging Face and prints a warning about unauthenticated requests, which you can ignore. After that it stays silent until it finishes and writes meeting.txt next to the audio. Add --verbose True to watch lines arrive with their timestamps.

Open the finished transcript in the terminal with less "meeting.txt", scroll with the arrow keys, and press q to leave. Or double click it in the file manager to open it in the text editor.

Other formats are one flag away:

Choose a model

Pass --language en whenever you know the language. Without it, Whisper guesses from the opening thirty seconds, and a wrong guess spoils the entire transcript.

Speed it up on older hardware

nice -n 19 whisper-ctranslate2 "meeting.opus" --model small --language en --output_format txt --threads 8 --vad_filter True --compute_type int8

Label the speakers

Speaker labels come from pyannote.audio, which also runs locally. Its models sit behind a free Hugging Face account.

  1. Create a free account at Hugging Face, then confirm it from the email they send.
  2. Go to the access tokens page, also reachable from your profile picture, Settings, Access Tokens. Choose Create new token, pick the Read type, name it after the computer, and create it. The token begins with hf_ and appears only this once, so copy it immediately and keep it somewhere private until step 4.
  3. While signed in, accept the terms on pyannote/speaker-diarization-community-1. Older releases of whisper-ctranslate2 use speaker-diarization-3.1 and segmentation-3.0, so accept those too. Each page asks for a company name and a website before it unlocks; use your organization's name and address.
  4. Add pyannote.audio to the transcriber's environment and store the token in your shell profile. The first line downloads more than a gigabyte and may look stuck for several minutes; leave it running. Before pressing Enter on the second line, swap hf_yourtokenhere for your real token and keep the single quotes around it.
pipx inject whisper-ctranslate2 pyannote.audio
echo 'export HF_TOKEN=hf_yourtokenhere' >> ~/.bashrc
source ~/.bashrc

echo $HF_TOKEN should now print the token. Then pass it with each run:

whisper-ctranslate2 "meeting.opus" --model small --language en --output_format txt --hf_token "$HF_TOKEN"

Every line comes back tagged [SPEAKER_00], [SPEAKER_01], and onward. The install brings in PyTorch, which is over a gigabyte, and labeling is a second complete pass over the audio, so a run takes roughly twice as long. The token only authorizes the model download; the audio itself stays on the machine. Keep the token out of shared scripts and code repositories.

Make it a routine

Two functions at the end of ~/.bashrc reduce the job to two short commands. That file holds the settings each new terminal loads. Edit it with nano, the plain editor built into the terminal:

nano ~/.bashrc

Arrow down past the last line, paste both functions below with Ctrl+Shift+V, write the file with Ctrl+O and Enter, and leave nano with Ctrl+X:

toaudio() { ffmpeg -i "$1" -vn -ac 1 -ar 16000 -c:a libopus -b:a 24k -application voip "${1%.*}.opus"; }
transcribe() { nice -n 19 whisper-ctranslate2 "$1" --model small --language en --output_format txt --vad_filter True --threads 8 --output_dir ~/Documents/Transcripts --hf_token "$HF_TOKEN"; }

Make the folder the transcripts will collect in, and reload the settings in the window you have open:

mkdir -p ~/Documents/Transcripts
source ~/.bashrc

From now on, each recording takes:

toaudio "meeting.mp4"
transcribe "meeting.opus"

To work through a folder of recordings overnight:

for f in ~/Recordings/*.mp4; do
  toaudio "$f" && transcribe "${f%.*}.opus"
done

--output_dir gathers every transcript in one folder. When that folder syncs between your own computers with a tool like Syncthing, every transcript follows you without touching a third party's cloud. Searching all of them is a single line:

grep -ril "renewal" ~/Documents/Transcripts

Drop the -l to print the matching lines themselves.

Troubleshooting

References