Monitors DMR (Digital Mobile Radio) WAV recordings, converts them to Opus/OGG, and transcribes them via Whisper (Groq or OVH) into PostgreSQL.
bun install
cp env.sample .env # configure paths, DB, and API keys
psql -f setup.sql # creates dmrids and msgs tablesTo populate the dmrids table from a RadioID CSV dump (user.csv):
cd scripts && ./update_dmrids.shbun index.ts # Start watcher daemon (inotify with polling fallback)
bun index.ts --all [--limit=N] # Batch process existing WAV files in WATCH_PATH
bun index.ts --fill [--limit=N] # Backfill missing OVH transcriptions from DB
bun index.ts --dryrun # Test processing & STT without DB writes or file moves- Detection: Watches
WATCH_PATHfor{src}-{timestamp}-{dmr_id}.wav(e.g.,B-1699123456789-1234567.wav, wheresrcmaps toALBUMSlikeBfor FreeDMR530 /Ofor ZL-TRBO). - Filtering: Files <50ms or corrupted are discarded. Files <1000ms are treated as kerchunks (logged as
silent = TRUE, STT skipped). - Audio Pipeline: Converts to 8 kHz mono Opus at 32 kbps with FFmpeg (
highpass=f=150,dynaudnorm=f=75:g=25:p=0.95,volume=0.8) and archives toAUDIO_BASE_DIR/YYYY/MM/DD/{src}-{ts}-{id}.ogg. - Contextual Whisper Prompt: Injects transmitter callsign/name (cached from
dmrids), talkgroup name, and up to 2 recent talkgroup callsigns to improve transcription accuracy. - Storage: Appends STT text, response time, and confidence metrics to
msgs.txts(JSONB) allowing mulitple transcriptions for each transmission.
Located in scripts/:
update_dmrids.sh— Upsertsuser.csvintodmrids.silence_update.ts— Re-evaluates audio silence inmsgsusing FFmpegsilencedetect.whisper_analysis.ts— Transcription quality diagnostics and benchmarking.migrate_db.sql(root) — Adds unique constraint onmsgs(src, ts, id)for existing databases.