Real-time speech-to-subtitle tool powered by whisper.cpp. Captures microphone audio in short chunks, transcribes and translates it (Japanese → English by default), and displays live subtitles — either overlaid on a video feed (Linux/GStreamer) or in an Electron GUI window (macOS/Linux).
id_subtitle_deamon.py— core Python daemon; records audio chunks, runs whisper.cpp for translation, and emits subtitleselectron-subtitle-app/— optional Electron GUI that wraps the daemon with a config panel and floating subtitle window
- Build whisper.cpp from source and download a model (small/base/medium/large).
git clone https://github.com/ggerganov/whisper.cpp
cd whisper.cpp
cmake -B build && cmake --build build --config Release
bash models/download-ggml-model.sh small # or base, medium, large- Python 3.9+ is required for the daemon. Install runtime dependencies with:
pip3 install -r requirements.txtThe daemon respects these environment variables (alternatively pass flags):
WHISPER_BIN— path to the whisper.cpp binary (or use--whisper-binflag)MODEL_PATH— path to the ggml model (or use--modelflag)AUDIO_DEVICE— platform-dependent audio capture deviceMIN_AUDIO_RMS— minimum RMS to treat audio as speech
Tip: when running the Electron GUI, set the Python executable path in the app settings (defaults to python3). Packaged apps may not inherit your shell PATH, so use an absolute Python path (e.g. /usr/bin/python3) if you see spawn ENOENT errors.
# Audio capture and (optional) GStreamer overlay
brew install ffmpeg pygobject3 gobject-introspection gst-plugins-base gstreamer
# Python dependencies (or use the repo requirements file)
pip3 install -r requirements.txt# Audio capture (arecord) and GStreamer overlay
sudo apt-get install -y \
alsa-utils \
python3-gi \
gir1.2-gstreamer-1.0 \
gstreamer1.0-tools \
gstreamer1.0-plugins-base \
gstreamer1.0-plugins-good
# Python dependencies
pip3 install -r requirements.txtRequires Node.js 18+.
cd electron-subtitle-app
npm installRun the daemon directly (no GUI):
python3 id_subtitle_deamon.py \
--whisper-bin /path/to/whisper.cpp/build/bin/whisper-cli \
--model /path/to/whisper.cpp/models/ggml-small.bin \
--source-language ja \
--no-overlay \
--emit-jsonKey runtime environment variables (the daemon reads these if present):
WHISPER_BIN,MODEL_PATH,AUDIO_DEVICE,MIN_AUDIO_RMS,FFMPEG_BIN
Start the Electron GUI in development mode:
cd electron-subtitle-app
npm startIn the GUI's settings panel set:
- Whisper binary (
whisperBin) and model path (modelPath) - Audio device and source language
- Python executable path (
pythonPath) — defaults topython3. If the app showsspawn python ENOENT, set this to the absolute Python path (for example/usr/bin/python3) because packaged apps may not inherit your shell PATH.
Yes, this is supported.
- On macOS, audio capture uses ffmpeg AVFoundation selectors (
AUDIO_DEVICEin format:<index>). - In the Electron app, click
List Audio Inputsto print available input devices in Logs. - Set
Audio Deviceto one of the listed indices (example::1).
For TV/system audio routing on macOS, use a virtual loopback device:
- Install BlackHole (or similar virtual audio driver).
- Open Audio MIDI Setup and create a Multi-Output Device (your speakers + BlackHole).
- Set your media output to that Multi-Output Device.
- In Spider Subtitler, choose the BlackHole input index via
List Audio Inputs.
This lets subtitles follow internal audio directly without relying on room loudness.
The GUI launches the Python daemon with --emit-json so it can parse structured events.
Build a distributable from electron-subtitle-app:
cd electron-subtitle-app
npm install
npm run distNote: packaging requires electron-builder and a configured environment. Packaged apps may need absolute paths for external binaries (Python, ffmpeg, whisper) in the app settings or environment because the runtime PATH can differ.
python3 id_subtitle_deamon.py \
--test-translate /path/to/audio.wav \
--whisper-bin /path/to/whisper-cli \
--model /path/to/ggml-small.bin- On macOS, PyGObject/GStreamer is optional; the daemon falls back to
--no-overlaymode automatically if not installed. - Adjust
--chunk-seconds(default:2) to tune latency vs. accuracy. - Set
MIN_AUDIO_RMSlower to pick up quieter audio, or higher to reduce false triggers. - A
.gitignorehas been added to ignorenode_modules/anddist/directories when committing.