Headless Raspberry Pi recorder triggered by a Bluetooth HID clicker (or any keyboard) and optionally indicating state via a TP-Link Kasa smart bulb. Audio is captured with arecord and encoded on-the-fly to MP3 using lame. Designed for fast, reliable single-action start/stop with clear visual feedback and easily accessible files (optionally via SMB share).
Designed and tested primarily on a Raspberry Pi Zero 2 W (sufficient CPU for real-time MP3 at preset extreme). It should run on any full-size Raspberry Pi. NOTE: The original Pi Zero W (v1) often cannot keep up with live MP3 encoding at the current quality setting.
- Bluetooth clicker / wireless keyboard toggle (no GPIO wiring)
- MP3 pipeline:
arecord->lame --preset extreme - Auto USB audio capability probing
- Kasa smart bulb tally (solid red while recording) with state restore
- Auto-discovery of bulb named "Recording Light" (same subnet)
- Safe timestamped filenames (
audio-recorder-YYYY-MM-DD-HH-MM-SS.mp3) - Date-based folder organization (
YYYY/MMby default) - Auto-stop on Bluetooth device reconnection
- Systemd friendly, concise logging (
/var/log/audio-recorder.log) - Tested with Kasa KL125 color bulb
git clone https://github.com/pseudosavant/ps-audio-recorder.git
cd ps-audio-recorder
chmod +x setup.sh upgrade.sh
sudo ./setup.shThe script:
- Installs required APT packages (ALSA, BlueZ, lame, etc.)
- Installs/updates Python deps from
ps-audio-recorder/requirements.txt - Creates
/srv/recordingswith group permissions - Touches/permissions the log file
- Installs & enables the systemd service
- Creates
/etc/ps-audio-recorder/ps-audio-recorder.envfor runtime config overrides (preserved on rerun) - Installs ReplayGain watcher service (mp3gain + inotify-tools) that monitors
/srv/recordings
Recommended (one command from repo root):
./upgrade.shEquivalent manual flow:
git pull --ff-only
sudo ./setup.sh --upgradeUpgrade mode refreshes Python dependencies and restarts managed services.
After running setup, pair your Bluetooth clicker (most show up as a HID keyboard). If pairing wasn’t done automatically inside the script, you can still use bluetoothctl manually; usually no config changes are needed if the remote emits key code 115 (F14). If not, set PS_AUDIO_TRIGGER_KEY_CODE in /etc/ps-audio-recorder/ps-audio-recorder.env and restart the service.
A generic Bluetooth “selfie” / presentation clicker works (appears as a tiny keyboard). These are inexpensive (typically < $5). Example model used for testing: Amazon product link.
Most send a single key code (often 115) which the recorder treats as the toggle.
Automatically searches the local subnet for a TP-Link Kasa bulb whose alias matches Recording Light (Config.BULB_NAME). Tested with KL125. Other color Kasa models should work.
Manual run (same script systemd uses):
~/ps-audio-recorder/ps-audio-recorder/start-recorder.shThis script loads /etc/ps-audio-recorder/ps-audio-recorder.env, creates/activates the virtual environment, and launches the recorder.
- Press the Bluetooth remote button (mapped key code 115) or spacebar (if interactive TTY) to toggle recording.
- MP3 files appear in
/srv/recordings/YYYY/MM/by default.
Systemd service (installed/enabled by setup.sh):
sudo systemctl status ps-audio-recorder
journalctl -u ps-audio-recorder -f- Service name:
ps-replaygain - Watches:
/srv/recordings(recursive) - Processes:
.mp3files only, skips temp/hidden - Tool:
mp3gain(track mode, clipping protection, undo metadata)
Commands:
sudo systemctl status ps-replaygain
sudo journalctl -u ps-replaygain -fConfig file (optional): ~/ps-audio-recorder/replaygain-watcher.env
See ps-audio-recorder/replaygain-watcher.env.example for fields:
- WATCH_PATH (default
/srv/recordings) - RECURSIVE (1)
- LOG_LEVEL (info|debug|error)
- PROCESS_MODE (track|album)
- EXCLUDE_REGEX (temp/partial patterns)
- NICE_LEVEL, IONICE_CLASS (resource knobs)
echo 'LOG_LEVEL=debug' | sudo tee -a ~/ps-audio-recorder/replaygain-watcher.env
sudo systemctl restart ps-replaygain
sudo journalctl -u ps-replaygain -n 100 --no-pagerAdjust:
PS_AUDIO_SAMPLE_RATE/PS_AUDIO_AUDIO_FORMATfallbackPS_AUDIO_TRIGGER_KEY_CODE(remote key)PS_AUDIO_BULB_NAME(defaultRecording Light)PS_AUDIO_RECORDING_EXTENSION(mp3)PS_AUDIO_TIMESTAMP_FORMAT/PS_AUDIO_RECORDING_PREFIXPS_AUDIO_RECORDING_SUBDIR_FORMAT(default%Y/%m)PS_AUDIO_RECORDING_DIR/PS_AUDIO_LOG_FILE
Apply changes:
sudo systemctl restart ps-audio-recorderPipeline example:
arecord -r 48000 -t wav -f S32_LE -c 2 ... | lame --ignorelength --preset extreme --silent - file.mp3- Remote not toggling: run
sudo evtestto confirm key code; updatePS_AUDIO_TRIGGER_KEY_CODEin/etc/ps-audio-recorder/ps-audio-recorder.envand restart the service. - Audio device:
arecord -lto verify card presence. - Empty/short MP3: check log for early
arecordorlameexit. - Bulb not found: confirm alias, same subnet, run
python -m kasa discover. - ReplayGain: ensure packages
mp3gainandinotify-toolsare installed; verify watch path exists and owned bypi.
- Zero 2 W and larger Pis: OK at
--preset extreme. - Original Zero W: likely too slow; lower quality (e.g.
-V5) or record WAV then transcode offline.
MIT (see LICENSE).
© John Paul Ellis (https://github.com/pseudosavant)
