Files
Captioneer/README.md
T
kato 45e4bce2a0 refactor: reorganize monolithic main package into focused packages
Move the executable entry point to `src/cmd/captioneer` and split audio, capture, config, caption, and model logic into separate packages under `src/`. Update README with new build/run commands and a package-overview section.
2026-07-16 12:12:01 +03:00

4.1 KiB

Captioneer

Local, live English captions for the audio playing through your default PulseAudio/PipeWire output device. It captures that output's monitor source, runs the Parakeet TDT v2 model locally, and writes captions to the terminal.

Everything runs on your machine after the one-time model download. No audio is uploaded anywhere.

Requirements

  • Linux on amd64 / x86_64
  • Go 1.26.2 or newer
  • pactl and parec available on PATH (on Debian/Ubuntu: sudo apt install pulseaudio-utils)
  • curl and tar to download the models
  • A working PulseAudio-compatible server, including PipeWire's PulseAudio compatibility layer

The application listens to the monitor of the current default audio sink. Check it with:

pactl get-default-sink

Setup

Clone the project, then download the required models once:

git clone <your-repository-url>
cd captioneer
./scripts/download-models.sh

The download installs the Parakeet TDT v2 int8 model and Silero VAD into models/. They are intentionally not committed to Git because they are large.

Run

Use VAD mode for normal live captions. It shows a temporary caption while speech is active, then prints a timestamped final caption after 0.5 seconds of silence:

go run ./src/cmd/captioneer --mode=vad

Use fixed mode to decode exact time slices, even through silence:

go run ./src/cmd/captioneer --mode=fixed --chunk-duration=1s

Build a reusable executable instead of using go run:

go build -o captioneer ./src/cmd/captioneer
./captioneer --mode=vad

Press Ctrl+C to stop. Pending audio is flushed before exit.

Options

--mode is required. All other options have defaults.

Option Default Description
--mode=vad Speech-aware captions. This is the recommended everyday mode.
--mode=fixed Decode every fixed-duration audio chunk.
--chunk-duration=1s 1s Fixed chunk length, or VAD preview refresh interval. Go duration syntax is used, e.g. 500ms, 1s, 2s.
--models-dir=models models Directory containing parakeet-tdt-v2/ and silero_vad_v5.onnx.
--threads=2 2 CPU threads used by Parakeet and VAD. Increase only if your CPU has spare capacity.
--preview-threshold-dbfs=-45 -45 RMS level that begins a provisional VAD caption. Raise it (for example, -35) if background audio starts previews; lower it (for example, -55) if quiet speech does not.

Examples:

# Faster fixed chunks
go run ./src/cmd/captioneer --mode=fixed --chunk-duration=500ms

# Fewer VAD preview redraws and four CPU threads
go run ./src/cmd/captioneer --mode=vad --chunk-duration=2s --threads=4

# Store or reuse models outside this repository
go run ./src/cmd/captioneer --mode=vad --models-dir=/path/to/models

There are no environment variables to configure. All supported configuration is supplied with command-line options.

Source layout

All Go code lives in src/ as focused packages:

  • cmd/captioneer is the executable entrypoint.
  • config defines command-line options.
  • audio contains PCM conversion and audio calculations.
  • capture reads the default system-audio monitor.
  • models owns Parakeet and Silero model resources.
  • captions handles fixed chunks, VAD segments, and terminal output.

Output and troubleshooting

Final captions go to standard output in this form:

[12.34s-15.67s] This is a completed caption.

Startup messages and overload warnings go to standard error, so you can save final captions separately:

go run ./src/cmd/captioneer --mode=vad > captions.txt
  • Missing model files: run ./scripts/download-models.sh again.
  • pactl or parec not found: install pulseaudio-utils and start a PulseAudio-compatible audio server.
  • No captions while audio plays: verify the default sink with pactl get-default-sink; the app records that sink's .monitor source.
  • Overload warning: recognition is behind real time. Try --threads=4 (or another suitable value) or --chunk-duration=2s.

Verify changes

go test ./...
go build -o captioneer ./src/cmd/captioneer