Intermediate16 min read

Transcribe a recording on your computer

Run Faster Whisper on a short recording, save timestamped notes, and add them to a searchable collection.

On this page

Prepare a short recording

Record yourself saying “The library opens at nine on Tuesday. Ask for a blue card at the front desk.” Save it as sample.wav, or use the filename and format your recorder produced. Start with one speaker and a quiet room.

Use a new Python virtual environment. These versions were tested together with Python 3.13 on macOS. Pinning PyAV keeps the audio decoder compatible with this Faster Whisper version.

python3 -m venv .venv
source .venv/bin/activate
python -m pip install "faster-whisper==1.2.1" "av==16.1.0"

On Windows PowerShell, create the environment with py -3 -m venv .venv and use .\.venv\Scripts\python.exe in place of python in the install and run commands.

Run the transcriber

Download the script beside your recording. The first run fetches the English tiny.en weights. The model processes your audio on the CPU and saves the text as sample.transcript.md.

Download transcribe_notes.py
View transcribe_notes.py
import argparse
from pathlib import Path

from faster_whisper import WhisperModel


def timestamp(seconds):
    minutes, seconds = divmod(int(seconds), 60)
    hours, minutes = divmod(minutes, 60)
    return f"{hours:02d}:{minutes:02d}:{seconds:02d}"


def transcribe(model, audio, language="en", vad_filter=False):
    segments, info = model.transcribe(str(audio), language=language, beam_size=3, vad_filter=vad_filter)
    lines = [(segment.start, segment.text.strip()) for segment in segments if segment.text.strip()]
    return lines, info.language


def main():
    parser = argparse.ArgumentParser(description="Transcribe an English recording locally.")
    parser.add_argument("audio", type=Path)
    parser.add_argument("--output", type=Path)
    args = parser.parse_args()

    if not args.audio.is_file():
        parser.error(f"Audio file not found: {args.audio}")
    output = args.output or args.audio.with_name(args.audio.stem + ".transcript.md")
    if output.exists():
        parser.error(f"{output} already exists. Choose a new path with --output.")

    model = WhisperModel("tiny.en", device="cpu", compute_type="int8")
    lines, _ = transcribe(model, args.audio)
    if not lines:
        raise SystemExit("No speech was transcribed. Try a clear recording with one speaker.")
    paragraphs = [f"[{timestamp(start)}] {text}" for start, text in lines]
    try:
        with output.open("x", encoding="utf-8") as transcript:
            transcript.write("\n\n".join(paragraphs) + "\n")
    except OSError as error:
        raise SystemExit(f"Could not save {output}: {error}") from None
    print(f"Wrote {output}")


if __name__ == "__main__":
    main()
python transcribe_notes.py sample.wav
You’re ready when

The Markdown file has at least one timestamped passage. Check that it mentions Tuesday and a blue card. It may render “nine” as “9,” and punctuation may vary.

Search the transcript and retry offline

Put the transcript in your notes folder. Rebuild the text index and search for “blue card.” Use the timestamp as a cue to replay and verify the source. Once the weights are cached, you can repeat the run with the Hub’s offline setting and a new output path.

HF_HUB_OFFLINE=1 python transcribe_notes.py sample.wav --output sample-offline.md

In PowerShell, set $env:HF_HUB_OFFLINE = "1" before the command. For other languages, choose a multilingual model such as tiny and pass the correct language code, or omit the language setting to use detection. Check names, numbers, and dates against the audio.

Check your understanding

What does the timestamp tell you?

It gives the approximate start of a recognized segment so you can find it in the recording.

Sources

Search the guide