fegger 098d9b63fa whisper-server: Debian trixie base — Mesa 25 for the R9700 (RDNA 3.5)
bookworm's Mesa 22.3 has no gfx1151 (Strix Halo) support in RADV, so
the container silently fell back to CPU despite gpu=auto: whisper
logged 'whisper_backend_init_gpu: no GPU found'. trixie ships Mesa
25.0.7, which supports the R9700; whisper.cpp builds unchanged on it.
2026-09-08 22:36:19 +02:00

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).

Library tab (GUI)

The desktop GUI has Record and Library tabs like the mobile app. The Library tab browses the server's recordings with summary, agenda coverage and the full transcript, and auto-refreshes every 10 s — record on the phone, and the meeting appears on the desktop while the tab is open:

MEETREC_LIBRARY_URL=http://100.103.83.12:8090 python meetrec_gui.py

(The URL can also be typed into the tab's Library URL field.)

  • --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%