Capture macOS system audio from video lectures and transcribe locally using whisper.cpp. No cloud. No subscription. Supports English and Brazilian Portuguese via auto-detection.
- Routes system audio through BlackHole 2ch virtual driver
- Records sessions as 16kHz mono WAV via ffmpeg
- Transcribes with whisper-cli (default: large-v3-turbo with Metal GPU acceleration on Apple Silicon)
- Outputs
.txt(required), optionally.srtand.vtt - Garbage collects old recordings on schedule via launchd
brew tap jmcoimbra/tap
brew install sound2transcriptThis installs stream-transcribe and sound2transcript-gc into your PATH, and pulls in ffmpeg and whisper-cpp as dependencies automatically.
After installing, complete the one-time setup:
# 1. Install the virtual audio driver
brew install --cask blackhole-2ch
# 2. Download the Whisper model (1.5 GB)
curl -L --progress-bar \
-o "$(brew --prefix)/var/sound2transcript/models/ggml-medium.bin" \
"https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-medium.bin"
# 3. Configure audio routing (required)
open docs/SETUP.md # or see Audio Routing belowgit clone https://github.com/jmcoimbra/sound2transcript.git
cd sound2transcript
make install
make download-modelRequires Homebrew and macOS 13+.
brew update
brew upgrade sound2transcriptThat's it. Homebrew handles fetching the new version and replacing the binaries.
Your transcripts, recordings, model, and config are untouched - they live in the data directory, not in the Homebrew prefix.
cd sound2transcript
git pull
make installRe-runs the install, copying updated scripts over the existing ones. Your data and config are preserved.
brew uninstall sound2transcript
brew untap jmcoimbra/tap # optional: remove the tapmake uninstallBoth methods leave your data at ~/sound2transcript/ intact. Remove it manually if you no longer need it:
rm -rf ~/sound2transcriptSee docs/SETUP.md - required one-time setup to route system audio through BlackHole before first use.
See docs/MODELS.md for model comparison, architecture-specific install instructions (Apple Silicon vs Intel), and thread tuning.
Apple Silicon users: Make sure you're using ARM Homebrew (/opt/homebrew/bin/brew), not Intel Homebrew (/usr/local/bin/brew). Intel Homebrew runs under Rosetta 2 and produces binaries with no Metal GPU access - transcription will be 10-20x slower.
Start recording:
stream-transcribePress Ctrl+C to stop. Transcription runs automatically. Output goes to ~/sound2transcript/transcripts/.
Keep the WAV file after transcription:
stream-transcribe --keepTo always keep recordings, set KEEP_RECORDINGS="1" in your config.
Check version:
stream-transcribe --versionmake install-launchdRuns daily at 03:30, removing old WAV files and enforcing disk caps.
~/sound2transcript/
├── models/ # whisper model files
├── recordings/ # intermediate WAV files (deleted after transcription unless --keep)
├── transcripts/ # output .txt / .srt / .vtt
├── logs/ # session and gc logs
└── config/ # config.env
All settings are in ~/sound2transcript/config/config.env:
| Variable | Default | Description |
|---|---|---|
BLACKHOLE_DEVICE_NAME |
BlackHole 2ch |
Audio loopback device name |
MODEL_PATH |
~/sound2transcript/models/ggml-large-v3-turbo-q5_0.bin |
Whisper model path (guide) |
LANG |
auto |
Language: auto, en, or pt |
OUTPUT_TXT |
1 |
Generate .txt output |
OUTPUT_SRT |
1 |
Generate .srt subtitles |
OUTPUT_VTT |
0 |
Generate .vtt subtitles |
RECORDINGS_RETENTION_DAYS |
3 |
Days to keep WAV files |
TRANSCRIPTS_RETENTION_DAYS |
90 |
Days to keep transcripts (0 = forever) |
RECORDINGS_MAX_GB |
10 |
Max disk for recordings |
WHISPER_THREADS |
4 |
CPU threads for transcription |
SILENCE_THRESHOLD_DB |
-50 |
Volume threshold (dB) below which recording is flagged silent |
KEEP_RECORDINGS |
0 |
Keep WAV after transcription (1=keep, 0=delete). Override with --keep |
LOG_LEVEL |
info |
Log verbosity: info, warn, or error |
make lint # shellcheck + shfmt
make test # bats-core tests
make check # lint + test- Bump the version in
VERSION - Commit:
git commit -am "Bump version to X.Y.Z" - Tag and push:
make release - Create the GitHub release:
gh release create vX.Y.Z - Update the SHA in the homebrew-tap formula