{"id":50815838,"url":"https://github.com/muneebhashone/streamscribe","last_synced_at":"2026-06-13T09:31:00.353Z","repository":{"id":358336843,"uuid":"1240963038","full_name":"muneebhashone/streamscribe","owner":"muneebhashone","description":"Bun + TypeScript CLI for capturing microphone/system audio and streaming live transcription with Deepgram.","archived":false,"fork":false,"pushed_at":"2026-05-16T22:37:44.000Z","size":43,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-16T22:38:34.649Z","etag":null,"topics":["agent-skill","audio-capture","bun","cli","deepgram","ffmpeg","speech-to-text","transcription","typescript","windows-audio"],"latest_commit_sha":null,"homepage":"https://github.com/muneebhashone/streamscribe#readme","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/muneebhashone.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-16T19:42:26.000Z","updated_at":"2026-05-16T22:37:47.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/muneebhashone/streamscribe","commit_stats":null,"previous_names":["muneebhashone/streamscribe"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/muneebhashone/streamscribe","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/muneebhashone%2Fstreamscribe","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/muneebhashone%2Fstreamscribe/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/muneebhashone%2Fstreamscribe/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/muneebhashone%2Fstreamscribe/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/muneebhashone","download_url":"https://codeload.github.com/muneebhashone/streamscribe/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/muneebhashone%2Fstreamscribe/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34279898,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-13T02:00:06.617Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agent-skill","audio-capture","bun","cli","deepgram","ffmpeg","speech-to-text","transcription","typescript","windows-audio"],"created_at":"2026-06-13T09:30:59.657Z","updated_at":"2026-06-13T09:31:00.344Z","avatar_url":"https://github.com/muneebhashone.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# StreamScribe\n\nBun + TypeScript CLI for keeping system playback (any app — Chrome, Zoom, Spotify, a game) and your microphone on separate channels. Runs on **Windows**, **macOS**, and **Linux (Ubuntu, Fedora, Arch, etc.)**.\n\nIt can:\n\n- stream a playback loopback source and a microphone to separate Deepgram live STT websockets and print live transcripts in the terminal\n- save a stereo WAV recording with playback on the left channel and microphone on the right channel\n- run an interactive picker that lists actual capture devices on the current OS (DirectShow / AVFoundation / PulseAudio) and saves the selection — no manual JSON editing\n- auto-decide whether the FFplay monitor is needed (skipped for parallel-tap loopbacks like `virtual-audio-capturer`, Stereo Mix, and PulseAudio `*.monitor` sources; enabled for exclusive sinks like VB-CABLE, BlackHole, and Multi-Output Devices)\n- list audio devices for humans and agents using whichever FFmpeg indev applies on this OS\n\n## One-line install\n\nmacOS/Linux/Git Bash/WSL shell:\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/muneebhashone/streamscribe/main/install.sh | sh\n```\n\nWindows PowerShell:\n\n```powershell\nirm https://raw.githubusercontent.com/muneebhashone/streamscribe/main/install.ps1 | iex\n```\n\nDirect Bun install:\n\n```bash\nbun install -g --force --no-cache github:muneebhashone/streamscribe#\u003cmain-sha\u003e\n```\n\nRerun the same one-line installer command any time to update to the latest `main` version. The installers resolve `main` to the current commit, clear StreamScribe's Bun git cache, and reinstall the global package without touching your saved config or `DEEPGRAM_API_KEY`. Prefer the installers over direct Bun installs because moving git refs can be cached by Bun.\n\nThe one-line installers check for `ffmpeg` and `ffplay`; when either is missing they try to install FFmpeg with the platform package manager (`brew`, `apt-get`, `dnf`, `yum`, `pacman`, `winget`, or Chocolatey). They also check for `DEEPGRAM_API_KEY`; if it is missing, they prompt for a key and save it for future StreamScribe runs. The loopback driver check is platform-aware:\n\n- **Windows (`install.ps1`)** probes for `virtual-audio-capturer` / `CABLE Output` / `Stereo Mix` / `VoiceMeeter`. If none is present, it asks `[Y/n]` and installs `screen-capture-recorder` from its latest GitHub release with a UAC prompt.\n- **macOS (`install.sh`)** probes AVFoundation for `BlackHole` / `Loopback Audio` / `Soundflower` / `Multi-Output Device`. If none is present, it asks `[Y/n]` and runs `brew install blackhole-2ch`, then explains how to set up a Multi-Output Device.\n- **Linux (`install.sh`)** checks for a reachable PulseAudio (or PipeWire-Pulse) server. PulseAudio's monitor sources are native loopback — no extra driver needed. If the server is missing, the installer prints the `apt-get` / `dnf` / `pacman` commands to install it.\n\n### Installer flags\n\n```powershell\n# Print the installed version and exit\n.\\install.ps1 -Version\n# or via piped install:\n$env:STREAMSCRIBE_VERSION = '1'; irm \u003curl\u003e | iex\n\n# Force a clean reinstall, including old bin shims\n.\\install.ps1 -Force\n# or:\n$env:STREAMSCRIBE_FORCE = '1'; irm \u003curl\u003e | iex\n```\n\n```bash\nsh install.sh --version       # print installed version, exit\nsh install.sh --force         # clean old bin shims, then reinstall\n\n# Or via piped install:\nSTREAMSCRIBE_VERSION=1 curl -fsSL \u003curl\u003e | sh\nSTREAMSCRIBE_FORCE=1 curl -fsSL \u003curl\u003e | sh\n```\n\nInstalled commands:\n\n```bash\nstreamscribe help\nstreamscribe live              # picks sources on first run, then starts live\nstreamscribe live --pick       # re-pick sources, then go live\nstreamscribe record            # stereo WAV recording\nstreamscribe record --pick     # re-pick sources, then record\nstreamscribe pick              # picker only — update saved config\nstreamscribe devices           # raw FFmpeg device dump\nstreamscribe init-config       # create a user config file\nstreamscribe --version         # print the installed StreamScribe version\n```\n\n`chrome-mic-stt`, `mic-audio-capture`, and `audio-recorder` are aliases for the same CLI.\n\n## Requirements\n\n1. Bun 1.3+\n2. FFmpeg and FFplay available on `PATH`\n3. A Deepgram API key in `DEEPGRAM_API_KEY`\n4. Microphone permission granted to your terminal (Windows audio privacy / macOS Microphone permission / Linux user in the right audio group)\n5. A playback-capture source per platform (see [Playback capture per platform](#playback-capture-per-platform))\n\nCheck requirements:\n\n```bash\nbun --version\nffmpeg -version\nffplay -version\n```\n\nSet your Deepgram API key in the shell before live mode, or put it in a `.env` file in the directory where you run the CLI. Bun automatically loads `.env`.\n\n```bash\nexport DEEPGRAM_API_KEY=\"your_deepgram_key_here\"\n```\n\n## Playback capture per platform\n\nThe picker enumerates whichever audio devices the current OS exposes via FFmpeg and offers them by kind (playback / microphone). The CLI picks the right FFmpeg input backend automatically: `dshow` on Windows, `avfoundation` on macOS, `pulse` on Linux.\n\n### Windows (DirectShow)\n\n- **screen-capture-recorder** (recommended) — `https://github.com/rdp/screen-capture-recorder-to-video-windows-free`\n  Adds the `virtual-audio-capturer` DirectShow device. Parallel tap on the default render endpoint: captures whatever any app is playing through your default output, and you keep hearing audio normally. No per-app routing, no FFplay monitor needed.\n- **VB-CABLE** — `https://vb-audio.com/Cable/`\n  A virtual sink. Requires per-app routing in Windows Settings → Sound → App volume \u0026 device preferences (set each app you want captured to `CABLE Input`). The auto monitor logic enables FFplay so you can still hear the routed app.\n- **Stereo Mix** — built into some sound cards. Enable in Sound Control Panel → Recording → right-click → Show Disabled Devices → Enable.\n\n### macOS (AVFoundation)\n\nmacOS has no built-in loopback. Install one virtual driver:\n\n- **BlackHole 2ch** (recommended, free, open source) — `brew install blackhole-2ch` (the installer offers this). Manual install: `https://existential.audio/blackhole/`. After install, open **Audio MIDI Setup** → create a **Multi-Output Device** that includes BOTH your speakers/headset AND `BlackHole 2ch`, then set that Multi-Output Device as the macOS System Output. Now whatever your apps play is both audible and captured.\n- **Loopback by Rogue Amoeba** (paid, polished routing UI) — `https://rogueamoeba.com/loopback/`.\n- **Soundflower** — legacy, only if already installed.\n\nmacOS will prompt your terminal app (Terminal / iTerm / VS Code) for **Microphone** permission the first time FFmpeg opens an audio device. Grant it and re-run.\n\n### Linux (PulseAudio / PipeWire-Pulse)\n\nPulseAudio gives you system-audio loopback for free. Every output device has a corresponding `*.monitor` source that captures whatever is being played.\n\n- Ubuntu 22.04+ ships PipeWire by default — install the Pulse compatibility layer: `sudo apt-get install -y pipewire-pulse`.\n- Older Ubuntu/Debian/Fedora/Arch: install `pulseaudio` via the system package manager.\n- Verify: `pactl list sources short | grep monitor` should show entries like `alsa_output.pci-0000_00_1f.3.analog-stereo.monitor`.\n\nIf no loopback source is detected at runtime, the CLI prints platform-specific install guidance and exits without launching anything.\n\n## Quick start\n\nJust go live:\n\n```bash\nstreamscribe live\n```\n\nOn first run, an interactive picker lists your real capture devices and asks you to pick a playback source and a microphone. On Linux for example:\n\n```\nFirst-time setup: pick your audio sources.\n\nPlayback source (any app's audio — Chrome, Zoom, Spotify, etc.):\n  1) alsa_output.pci-0000_00_1f.3.analog-stereo.monitor  [PulseAudio monitor — native loopback, no extra driver needed]\n  c) cancel\n\n\u003e 1\n\nMicrophone (pick one of your attached mics):\n  1) alsa_input.pci-0000_00_1f.3.analog-stereo\n  2) bluez_source.AA_BB_CC_DD.headset_head_unit\n  c) cancel\n\n\u003e 1\n\nSaved to: /home/\u003cyou\u003e/.config/streamscribe/recorder.config.json\n```\n\nThe macOS and Windows lists name AVFoundation and DirectShow devices respectively — same picker, platform-appropriate device names.\n\nThe selection is saved. Subsequent `streamscribe live` runs skip the picker. Use `streamscribe live --pick` or `streamscribe pick` to re-prompt.\n\nLive mode prints final transcript lines to the terminal as `[time] [playback] text` and `[time] [microphone] text`. Press `q`, `Enter`, or `Ctrl+C` to stop.\n\nRecording mode:\n\n```bash\nstreamscribe record\n```\n\nRecordings are written to `recordings/recording-YYYY-MM-DD_HH-mm-ss.wav` with playback on the left channel and microphone on the right channel.\n\n## Configuration\n\nThe CLI reads config in this order:\n\n1. `STREAMSCRIBE_CONFIG`\n2. `MIC_AUDIO_CAPTURE_CONFIG` (legacy)\n3. `AUDIO_RECORDER_CONFIG` (legacy)\n4. `recorder.config.json` in the current working directory\n5. user config at `~/.config/streamscribe/recorder.config.json` or Windows equivalent\n6. package `recorder.config.example.json`\n\nThe picker writes back to the same path it loaded from (cwd config in dev, user config when installed). Edited configs are backed up to `recorder.config.json.bak.\u003ctimestamp\u003e` before overwrite. The picker always resets `monitor.enabled` to `\"auto\"`.\n\nNotable schema fields:\n\n- `browser.backend` and `mic.backend` — FFmpeg input backend, written by the picker:\n  - Windows → `dshow` (or legacy `wasapi` / `wasapi-loopback`)\n  - macOS → `avfoundation`\n  - Linux → `pulse`\n- `browser.device` — playback source name (JSON key is `browser` for backward compat; it captures any app's playback)\n- `mic.device` — microphone device name\n- `monitor.enabled` — `\"auto\"` | `true` | `false`. `\"auto\"` is the default:\n  - **on** for exclusive sinks where the routed app no longer plays through the system output: `CABLE Output`, `BlackHole`, `Multi-Output Device`, `Loopback Audio`.\n  - **off** for parallel taps where the user already hears audio natively: `virtual-audio-capturer`, `Stereo Mix`, PulseAudio `*.monitor` sources, `wasapi-loopback`, and any `pulse` backend.\n\nExample config ships as `recorder.config.example.json`:\n\n```json\n{\n  \"ffmpegPath\": \"ffmpeg\",\n  \"outputDir\": \"recordings\",\n  \"sampleRate\": 48000,\n  \"monitor\": {\n    \"enabled\": \"auto\",\n    \"ffplayPath\": \"ffplay\",\n    \"volume\": 100\n  },\n  \"deepgram\": {\n    \"apiKeyEnv\": \"DEEPGRAM_API_KEY\",\n    \"sttModel\": \"nova-3\",\n    \"sttSampleRate\": 16000,\n    \"language\": \"en-US\",\n    \"interimResults\": true,\n    \"endpointing\": 300,\n    \"punctuate\": true,\n    \"smartFormat\": true,\n    \"printInterim\": false,\n    \"ttsEnabled\": false,\n    \"ttsModel\": \"aura-2-thalia-en\",\n    \"ttsSampleRate\": 24000,\n    \"ttsEncoding\": \"linear16\",\n    \"ttsContainer\": \"wav\",\n    \"speakChannelNames\": false,\n    \"ffplayPath\": \"ffplay\",\n    \"debug\": false\n  },\n  \"browser\": {\n    \"label\": \"System playback (any app)\",\n    \"backend\": \"dshow\",\n    \"device\": \"\",\n    \"channel\": \"left\",\n    \"ttsName\": \"playback\"\n  },\n  \"mic\": {\n    \"label\": \"Microphone\",\n    \"backend\": \"dshow\",\n    \"device\": \"\",\n    \"channel\": \"right\",\n    \"ttsName\": \"microphone\"\n  }\n}\n```\n\nEmpty `device` fields trigger the picker on first run.\n\n## Capturing system audio and still hearing it\n\nThe shape of this depends on whether your loopback source is a **parallel tap** (audio is also still played through your speakers/headset) or an **exclusive sink** (the routed app plays only into the virtual device). The CLI's `monitor.enabled: \"auto\"` mode picks for you.\n\n### Parallel taps (no FFplay monitor needed)\n\nYou keep hearing audio natively, and the CLI captures it in parallel:\n\n- **Windows:** `virtual-audio-capturer` (from screen-capture-recorder), `Stereo Mix`.\n- **Linux:** any PulseAudio `*.monitor` source (e.g. `alsa_output...analog-stereo.monitor`). This is the default Linux experience.\n- **macOS:** a **Multi-Output Device** in Audio MIDI Setup that includes BlackHole AND your speakers. Set this as the macOS System Output and you both hear and capture audio.\n\n### Exclusive sinks (FFplay monitor runs automatically)\n\nThe routed app no longer plays through your default output, so the CLI runs FFplay to play the loopback stream back so you can still hear it:\n\n- **Windows:** VB-CABLE (`CABLE Output`). Route only the app(s) you want captured to `CABLE Input` in Windows Settings → Sound → App volume \u0026 device preferences. Don't set the whole Windows default output to VB-CABLE unless you intentionally want all system audio captured.\n- **macOS:** `BlackHole 2ch` directly (without a Multi-Output Device) or Rogue Amoeba's `Loopback Audio`. The FFplay monitor plays the captured audio back to the default output.\n\n## Agent skill\n\nThis repo ships an agent skill at:\n\n```text\nskills/streamscribe/SKILL.md\n```\n\nInstall the skill through the [skills.sh](https://www.skills.sh/) CLI:\n\n```bash\nnpx skills add muneebhashone/streamscribe\n```\n\nThe skill is advertised in `skills.json` for skills.sh-style registries. Agents can use it to install the CLI, discover devices, configure routing, and operate live transcription or recording safely.\n\nIf your agent supports installing skills from a GitHub repository, point it at this repo or at the skill path above.\n\n## Development\n\nFrom a clone:\n\n```bash\nbun install\nbun test\nbun run typecheck\nbun run check\nbun src/cli.ts help\n```\n\nProject layout:\n\n- `src/cli.ts` — Bun CLI entrypoint (parses `--pick` / `--version`, dispatches commands)\n- `src/lib.ts` — typed config, FFmpeg args, Deepgram websocket, device probe/enumeration, picker plumbing, recorder/live logic\n- `src/picker.ts` — interactive readline picker (number entry, zero new deps)\n- `install.sh` / `install.ps1` — one-line installers (FFmpeg + Bun + driver check on Windows + Deepgram key + CLI)\n- `tests/lib.test.ts` — unit tests for parser, classifier, monitor logic, config helpers, FFmpeg arg builders\n- `tests/distribution.test.ts` — package, installer, and skill distribution tests\n- `skills/streamscribe/SKILL.md` — agent skill\n\n## Commands\n\n```bash\nstreamscribe help              # show usage\nstreamscribe live              # picks sources on first run, then starts live\nstreamscribe live --pick       # re-pick sources, then go live\nstreamscribe record            # stereo WAV recording\nstreamscribe record --pick     # re-pick sources, then record\nstreamscribe pick              # picker only — update saved config\nstreamscribe devices           # raw FFmpeg device dump\nstreamscribe init-config       # create a user config file\nstreamscribe --version         # print the installed StreamScribe version\nbun run check                  # tests + TypeScript typecheck from a clone\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmuneebhashone%2Fstreamscribe","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmuneebhashone%2Fstreamscribe","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmuneebhashone%2Fstreamscribe/lists"}