MeetRec

Record an in-person meeting and transcribe it with Whisper.

Meetrec captures audio from any input (microphone, USB conference mic, USB audio interface, or a Pulse/PipeWire sink monitor) and produces transcripts in txt, srt, and json. It runs fully locally — no audio ever leaves your machine.

Two desktop interfaces plus an Android app:

  • meetrec.py — CLI: record, optionally show a live rolling transcript, and on Ctrl+C run a final higher-quality pass.
  • meetrec_gui.py — Qt (PySide6) GUI: device/model/language selection, level meter, live transcript, and one-click Stop & transcribe.
  • android/ — native Kotlin app with the same on-device functionality, built on whisper.cpp via JNI (see android/README.md).

Output files

With output stem -o meeting:

File Contents
meeting.wav raw recording (mono WAV at the input's native rate)
meeting.live.srt live rolling transcript (only with --live > 0)
meeting.txt final transcript
meeting.srt final transcript with timestamps
meeting.json final transcript, structured (language, segments)

Recording always uses the input device's native sample rate; audio is resampled to Whisper's 16 kHz automatically (both for the live window and the final pass).

Requirements

  • Linux with an audio backend: PipeWire (or PulseAudio/ALSA). On Arch: sudo pacman -S pipewire pipewire-pulse
  • Python 3.10+
  • Python packages (installed for you by the install script): numpy, sounddevice, faster-whisper, pyside6 (GUI only)
  • A GPU (CUDA) is optional — transcription falls back to CPU.

Installation

Quick install

./install.sh

This:

  1. copies the app to ~/.local/share/meetrec,
  2. creates a venv and installs all dependencies,
  3. installs the meetrec (GUI) and meetrec-cli launchers into ~/.local/bin,
  4. installs the XDG desktop entry and icon (app menu shows MeetRec with its own red mic icon),
  5. pre-downloads the small Whisper model (first run is otherwise slow).

Options:

./install.sh --model base        # pre-download a different model (tiny/base/small/medium/large-v3)
./install.sh --whisper-cpp       # also build whisper.cpp with its Vulkan GPU backend
./install.sh --no-model          # skip the model pre-download
./install.sh --uninstall         # remove everything the installer created
PREFIX=/opt/meetrec ./install.sh # install into a different prefix

On an AMD GPU (e.g. Ryzen AI 300 laptops with a Radeon iGPU), use --whisper-cpp and select the whisper-cpp engine — see Engines below. The build needs git, cmake, g++, and Vulkan headers (sudo pacman -S vulkan-headers on Arch).

Manual install (venv)

sudo pacman -S python pipewire pipewire-pulse
python3 -m venv .venv && source .venv/bin/activate
pip install numpy sounddevice faster-whisper pyside6

Usage

GUI

meetrec            # after ./install.sh
# or from a checkout:
python meetrec_gui.py

Pick a microphone (or type a name substring), model, language, and compute device/precision (switching model, device, or precision between recordings reloads the model automatically), press Record, watch the live transcript, then press Stop & transcribe.

CLI

meetrec-cli --list-sources                                  # find your input devices
meetrec-cli -s "Conference Mic" --model small --live 8 -o meeting
meetrec-cli -s monitor --model base --language en           # record system audio
meetrec-cli --engine whisper-cpp -o meeting                 # transcribe on the GPU (Vulkan)
MEETREC_SERVER_URL=http://100.103.83.12:8085 \
  meetrec-cli --engine whisper-server -o meeting             # transcribe on a remote server
python meetrec.py --help                                    # all options

Key options:

Option Meaning
--engine transcription backend: faster-whisper (default), whisper-cpp, or whisper-server
--server-url whisper-server base URL, e.g. http://100.103.83.12:8085 (or MEETREC_SERVER_URL)
-s, --source default or a substring of a device name (--list-sources)
-m, --model tiny / base / small / medium / large-v3 (default small)
-o, --output output file stem (default meeting)
--live SEC live-transcription interval in seconds; 0 disables (default 8)
--language force a language code, e.g. en, de (default: autodetect)
--device auto / cpu / cuda (default auto); faster-whisper only
--compute-type int8 / int8_float16 / float16 / float32 (default int8); faster-whisper only
--agenda-file text file with agenda items, one per line — uploaded for the coverage check
--diarize-url tinydiarize server URL → transcript gets Sprecher 1/2: labels (or MEETREC_DIARIZE_URL)
--library-url meetrec-server URL → uploads the recording and triggers summary + agenda check (or MEETREC_LIBRARY_URL)

Ctrl+C stops recording and runs the final transcription.

Tips

  • Record system audio: sink monitors appear as <sink name>.monitor; use -s monitor (or a matching substring).
  • Model size vs. speed/accuracy: tiny/base are fast and rough, small is a good default, medium/large-v3 are most accurate but much slower on CPU.
  • Models are cached in ~/.cache/huggingface (faster-whisper) and ~/.cache/meetrec/whisper-cpp (whisper.cpp) and shared between the CLI and the GUI.

Engines

Meetrec supports two interchangeable transcription backends — --engine on the CLI, the Engine dropdown in the GUI:

Engine Backend GPU support
faster-whisper (default) CTranslate2 NVIDIA CUDA (--device cuda); otherwise CPU
whisper-cpp whisper.cpp AMD / Intel / NVIDIA via Vulkan; falls back to CPU
whisper-server remote whisper.cpp HTTP server whatever the server has — see server/whisper-server/ (Docker Compose, Vulkan GPU, Tailscale)

On AMD hardware (e.g. the Radeon iGPU in Ryzen AI 300 laptops) the faster-whisper path is CPU-only — use the whisper-cpp engine there, which runs on the GPU when whisper.cpp is built with -DWHISPER_VULKAN=ON (./install.sh --whisper-cpp does this for you). The whisper-server engine moves the work to a server entirely (ideal for slow clients such as phones) and can run large-v3 on a GPU.

Notes on whisper-cpp:

  • The whisper-cli binary is looked up in WHISPER_CPP_BIN, then PATH, then ~/.local/share/meetrec/whisper-cpp/bin/whisper-cli (where install.sh --whisper-cpp puts it).
  • GGML models (ggml-*.bin) download automatically to ~/.cache/meetrec/whisper-cpp on first use.
  • VAD works like on faster-whisper: whisper.cpp's Silero VAD model (~1 MB) downloads automatically and is used for both live and final passes.
  • Live mode spawns whisper-cli for every rolling-window pass, so the GGML model is reloaded on each live tick — slightly heavier than faster-whisper, which loads once per recording.

Notes on whisper-server:

  • The model lives on the server — --model, --device, --compute-type do not apply; beam size is a server-start setting in whisper.cpp v1.9.3 (no per-request override).
  • Run your own with the Docker Compose stack in server/whisper-server/ — Vulkan GPU (AMD/NVIDIA/Intel), model auto-download, Tailscale-only binding.
  • The server has no authentication: keep it on Tailscale or behind a VPN/firewall.
  • verbose_json reports language names ("german") rather than ISO codes.

Meeting protocol (library, summary, agenda, speakers)

The desktop app has feature parity with the Android app's M3 set:

MEETREC_SERVER_URL=http://100.103.83.12:8085 \
MEETREC_LIBRARY_URL=http://100.103.83.12:8090 \
MEETREC_DIARIZE_URL=http://100.103.83.12:8086 \
  meetrec-cli --engine whisper-server --agenda-file agenda.txt -o meeting
  • --library-url uploads the WAV + transcripts after the final pass; the server then generates the German summary (Ollama, gemma4:12b) and checks which agenda items were discussed (browse everything in the Android app's Library tab).
  • --agenda-file supplies the agenda items (one per line).
  • --diarize-url adds a second tinydiarize pass whose speaker-turn times are merged onto the transcript as Sprecher 1:/Sprecher 2: labels (2 speakers, best-effort on non-English audio; failures keep the transcript unlabeled).
  • The GUI has the same options as fields (Library URL, Diarize URL, agenda editor).
  • --device / --compute-type do not apply (GPU vs. CPU is decided by the whisper.cpp build).

Project layout

meetrec.py            CLI: recording + live & final transcription
meetrec_gui.py        PySide6 GUI (reuses meetrec.py's logic)
requirements.txt      Python dependencies
install.sh            install / uninstall into a local prefix
bin/meetrec           GUI launcher (installed into ~/.local/bin)
bin/meetrec-cli       CLI launcher (installed into ~/.local/bin)
share/applications/meetrec.desktop   XDG desktop entry
share/icons/hicolor/                app icon (SVG + PNG fallbacks)
android/              native Android app (Kotlin + whisper.cpp JNI)

Privacy

Everything runs locally. The only network access is the one-time Whisper model download from Hugging Face.

S
Description
No description provided
Readme 699 KiB
Languages
Kotlin 54.6%
Python 35.6%
Shell 5.1%
C++ 2.9%
CMake 0.9%
Other 0.9%