Skip to main content
ClaudeWave

Local Whisper transcription + speaker diarization for Apple Silicon — who said what, fully offline and on-device

ToolsRegistry oficial5 estrellas0 forks● PythonMITActualizado today
ClaudeWave Trust Score
95/100
✓ Verified
Passed
  • ✓Open-source license (MIT)
  • ✓Actively maintained (<30d)
  • ✓Clear description
  • ✓Topics declared
  • ✓Documented (README)
Last scanned: 10/22/2026
Get started
Method: Clone
Terminal
git clone https://github.com/sblattj/whosaid
1. Clone the repository.
2. Follow the README for installation and usage instructions.
Casos de uso

Resumen de Tools

# whosaid

<!-- mcp-name: io.github.sblattj/whosaid -->

Local, speaker-attributed transcription for Apple Silicon — who said what, on your Mac, nothing
leaves the machine.

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
![Platform: macOS Apple Silicon](https://img.shields.io/badge/platform-macOS%20Apple%20Silicon-lightgrey.svg)

![whosaid demo — speaker-attributed transcription on the terminal](docs/demo.gif)

**whosaid** pairs **Whisper** speech-to-text with **speaker diarization** to turn a meeting,
interview, call, or podcast recording into a transcript that says *who spoke when* — running fully
**offline and on-device** on an Apple Silicon Mac, with no cloud service, no API keys, and no Hugging
Face token. Think of it as `whisper` + speaker labels + voice-based speaker recognition, in one
command.

**Example output** (`meeting.speakers.txt`):

```text
[00:00:04] Alice: Thanks for jumping on, I know it's late for you.
[00:00:11] SPEAKER_01: No problem at all, happy to make it work.
[00:00:19] Alice: Let's start with the roadmap for next quarter.
[00:00:27] SPEAKER_01: Sounds good, I've got a few updates on that.
```

## Why whosaid

- **Meetings, interviews, calls, podcasts** — get a transcript where every turn is attributed to a
  person, not just a wall of text.
- **Privacy by construction** — audio, text, and voice embeddings never leave your Mac. The only
  cloud step is one you opt into: `[summarizer] engine = "claude"` sends each transcript's text to
  Anthropic to draft action items. Leave it unset and nothing is sent.
- **Your name on your own lines** — a one-time ~45s voice enrollment teaches whosaid your voice, so
  your turns read as your name instead of `SPEAKER_00`.
- **Tells you how many people spoke** — the number of distinct speakers is auto-detected and
  reported up front, with per-speaker turn counts and talk time.
- **Speaker cards to identify who's who** — for every speaker, whosaid writes a card of that voice's
  most representative snippets, so you can read a few lines and know who was talking.
- **Remembers people you name** — identify a speaker once with `whosaid relabel`, and their
  voiceprint is saved to a private local registry so they're auto-named in every future transcript.
- **Fast on long recordings** — recordings over ~15 min are diarized in parallel windows and
  stitched back into consistent speakers by voiceprint, so an 80-minute meeting is minutes, not
  tens of minutes, recovering the same speakers as a single-pass run.
- **No accounts, no API keys, no Hugging Face token** — every model comes from an open, ungated
  source.
- **Search everything you have recorded.** `whosaid index` builds a local full-text (and,
  with Ollama, meaning) index over every transcript in a meeting workspace; `whosaid search`
  finds the turn, `whosaid context` shows the minute around it, and `whosaid graph` answers
  who committed to what, when. See [Search your meetings](#search-your-meetings).
- **Hands-free from Voice Memos.** `whosaid watch install` puts a launchd agent on the Voice
  Memos folder (or any folder): stop recording, and a few minutes later the meeting is
  transcribed, summarized, and searchable. See [Hands-free ingest](#hands-free-ingest-whosaid-watch).
- **Usable from an AI agent, too.** `whosaid mcp` exposes transcribe, relabel, doctor, and the
  read-only workspace search tools as MCP tools for Claude Code, Claude Desktop, Kiro, and other
  MCP clients, with the same local-only guarantee as the CLI.

## How it compares

**Looking for a MacWhisper, whisperX, or aTrain alternative?** If you want speaker-attributed
transcription that runs fully offline on Apple Silicon and can put real *names* on voices — not just
`SPEAKER_00` labels — that's the gap whosaid fills. Here's how it stacks up:

| | whosaid | whisperX | plain mlx-whisper | cloud transcription APIs |
|---|---|---|---|---|
| Speaker labels | Yes | Yes | No | Varies by provider |
| Names speakers by voice | Yes (enrollment) | No | No | No |
| Remembers speakers across meetings | Yes — persistent local voiceprint registry | No | No | No |
| Runs fully offline | Yes | Partial — needs a gated model download | Yes | No |
| Parallel diarization on long audio | Yes | No | — (no diarization) | Varies by provider |
| Needs an account / token | No | Yes — Hugging Face token for gated pyannote models | No | Yes — API key |
| Install weight | `ffmpeg` + `uv`, ephemeral environments | `torch` + `pyannote` + the full HF stack | `mlx-whisper` only | None (network client only) |

## Quickstart

```bash
git clone https://github.com/sblattj/whosaid && cd whosaid   # get the code
./bootstrap.sh                                                # check deps, download models, install ~/.local/bin/whosaid
whosaid enroll                                                # ~45s reading a printed passage — teaches whosaid your voice
whosaid path/to/meeting.m4a                                   # transcribe + diarize + label -> meeting.speakers.txt (and friends)
```

If `~/.local/bin` is not on your shell's `PATH`, add it or invoke the installed command by its
absolute path. `WHOSAID_INSTALL_DIR=/another/bin ./whosaid install` selects another install
directory. The installed command is a symlink to the checkout, so updating the checkout updates the
command without copying or duplicating the implementation.

whosaid's helper scripts need Python 3.11 or newer, because `whosaid.toml` is read with `tomllib`.
The launcher picks one interpreter: `$WHOSAID_PYTHON` if it is set, otherwise the first of `python3`,
`python3.13`, `python3.12` and `python3.11` on your `PATH` that is 3.11+, otherwise
`uv python find '>=3.11'`. It skips the stock macOS `python3` (3.9) automatically. If no interpreter
qualifies, commands that run Python stop with an error; `uv python install 3.13` fixes that.
`whosaid doctor` shows which interpreter was picked.

Homebrew is optional when `uv`, `ffmpeg`, and `ffprobe` are already installed. The launcher
and watcher search `~/.local/bin`, `~/bin`, and `~/homebrew/bin` as well as the usual system
prefixes. Setup can install a pinned, checksum-verified Apple Silicon `uv` archive into
`~/.local/bin`. Homebrew FFmpeg installation requires a bottle; a nonstandard prefix will not
silently trigger a source build.

For a Mac without Homebrew, or one where no bottle is available, use:

```bash
./bootstrap.sh --build-ffmpeg
```

This builds pinned FFmpeg source into user-local `ffmpeg` and `ffprobe` executables. It needs
Apple's Command Line Tools (`xcode-select --install` if missing), compilation time, and free
disk space, but no administrator-owned install prefix or GPG installation. The source archive
is checked with macOS `shasum` against a checksum verified from FFmpeg's signed release.
Existing usable tools are retained. Setup then warms the Python environments and downloads
the models as usual.

## Commands

| Command | What it does |
|---|---|
| `./bootstrap.sh [--yes] [--build-ffmpeg]` (also `whosaid setup`) | Capability check, dependency install, model pre-download, and command installation. `--build-ffmpeg` selects the verified user-local source build when FFmpeg tools are missing. Idempotent — safe to re-run. |
| `whosaid install [--force]` | Install/update the command symlink in `~/.local/bin` (or `WHOSAID_INSTALL_DIR`). Refuses to replace an unrelated command, and refuses (unless `--force`) to install from a checkout under `/tmp`, `/private/tmp`, `/var/tmp`, or `$TMPDIR` — that symlink would dangle once the OS cleans the temp directory up. |
| `whosaid enroll [Name]` | Records ~45s from the mic reading a printed passage, saves `voices/<Name>.wav`. See [Speaker identity: enrollment clips vs. the registry](#speaker-identity-enrollment-clips-vs-the-registry). |
| `whosaid enroll <Name> --from FILE [--ss T] [--t D\|--to T] [--force]` | Extracts a clip from an existing recording instead of the mic (extract → verify → save, no interaction). `--ss`/`--t`/`--to` accept seconds or `M:SS`/`H:MM:SS`; same ≥15s/non-silent bar as mic enrollment. |
| `whosaid record [--label L]` | Foreground mic capture to `recordings/<timestamp>[-label].m4a`, then transcribes automatically. |
| `whosaid record --app A [--no-mic] [--label L]` | Capture one app's audio (Zoom, a browser, ...) through ScreenCaptureKit, plus the mic, to a stereo `recordings/<timestamp>[-label].m4a` (left = mic, right = the app), then transcribe it. `A` is a bundle ID, an app name, or a unique part of either; `whosaid record --list-apps` lists them. Needs macOS 15+, Xcode Command Line Tools (a small Swift helper, `lib/record_app.swift`, is built on first use into `~/.cache/whosaid`) and Screen & System Audio Recording permission for your terminal. No virtual audio device. `--no-mic` records the app alone. With `--me NAME` (or `$WHOSAID_OWNER`), the voice heard only on the mic is named NAME and app-side voices never are. If macOS kills the capture it restarts in place. |
| `whosaid <audio>… [flags]` | The default command: transcribe + diarize + label one or more audio files. `--reuse-asr` skips Whisper when `<out>/<base>.json` already exists and re-diarizes only (errors if the json is missing; not valid with `--no-diarize`). `whosaid transcribe <audio>…` is the same command written explicitly (matching the `whosaid_transcribe` MCP tool name). |
| `whosaid relabel <base> SPEAKER_02=Jane …` | Put real names on clusters after reading the speaker cards. Rewrites the transcript + cards and saves each named voiceprint to the local registry for future transcripts — refusing (unless `--force`) to overwrite an existing registry entry the new cluster doesn't match (similarity below the match threshold, default 0.50). No re-transcription. |
| `whosaid relabel <base> SPEAKER_04=Alice --blend` | Average the cluster into Alice's saved print instead of replacing it, to strengthen the print from a new recording. Same similarity guard as a normal relabel. Se
apple-silicondiarizationmacosmeeting-transcriptionmlxmlx-whisperofflineon-deviceprivacypyannotesherpa-onnxspeaker-diarizationspeaker-identificationspeaker-recognitionspeech-to-texttranscriptionvoice-recognitionwhisperwhisper-diarization

Lo que la gente pregunta sobre whosaid

¿Qué es sblattj/whosaid?

+

sblattj/whosaid es tools para el ecosistema de Claude AI. Local Whisper transcription + speaker diarization for Apple Silicon — who said what, fully offline and on-device Tiene 5 estrellas en GitHub y su última actualización registrada es del 2026-10-22.

¿Cómo se instala whosaid?

+

Puedes instalar whosaid clonando el repositorio (https://github.com/sblattj/whosaid) o siguiendo las instrucciones del README en GitHub. ClaudeWave también te ofrece bloques de instalación rápida en esta misma página.

¿Es seguro usar sblattj/whosaid?

+

Nuestro agente de seguridad ha analizado sblattj/whosaid y le ha asignado un Trust Score de 95/100 (tier: Verified). Revisa el desglose completo de comprobaciones superadas y flags en esta página.

¿Quién mantiene sblattj/whosaid?

+

sblattj/whosaid es mantenido por sblattj. La última actividad registrada en GitHub es del 2026-10-22, con 3 issues abiertos.

¿Hay alternativas a whosaid?

+

Sí. En ClaudeWave puedes explorar tools similares en /categories/tools, ordenados por popularidad o actividad reciente.

Despliega whosaid en tu cloud

Lleva este repo a producción en minutos. Cada plataforma genera su propio entorno con variables de entorno editables.

¿Mantienes este repo? Añade un badge a tu README

Pega el badge en tu README de GitHub para mostrar que está auditado por ClaudeWave. Cada badge enlaza de vuelta a esta página y muestra el Trust Score actual.

Featured on ClaudeWave: sblattj/whosaid
[![Featured on ClaudeWave](https://claudewave.com/api/badge/sblattj-whosaid)](https://claudewave.com/repo/sblattj-whosaid)
<a href="https://claudewave.com/repo/sblattj-whosaid"><img src="https://claudewave.com/api/badge/sblattj-whosaid" alt="Featured on ClaudeWave: sblattj/whosaid" width="320" height="64" /></a>

Más Tools

Alternativas a whosaid
multica-ai
andrej-karpathy-skills
6mo ago

A single CLAUDE.md file to improve Claude Code behavior, derived from Andrej Karpathy's observations on LLM coding pitfalls.

222k22.3k
ToolsInstall
nextlevelbuilder
ui-ux-pro-max-skill
today

An AI skill that provides design intelligence for building professional UI/UX across multiple platforms.

138.6k14.7kPython
Toolsai-skillsantigravityInstall
JuliusBrussee
caveman
today

🪨 why use many token when few token do trick. Viral skill + proxy for coding agents that cuts 65% of tokens by talking like a caveman.

114.2k6.6kGo
ToolsaianthropicInstall
Alishahryar1
free-claude-code
today

Use Claude Code, Codex, VSCode, Pi, and OpenCode (and 6 other harnesses) for free (1.3B+ free tokens) from your terminal, app, IDE, or phone, and now from the browser with native browser sessions (multi-harness + multi-model) like OpenClaw (voice supported + ToS friendly)

62.5k9.8kPython
ToolsInstall
BerriAI
litellm
today

The fastest, litest AI Gateway. Rust core with Python SDK. Call 100+ LLM APIs in OpenAI (or native) format with cost tracking, guardrails, load balancing, and logging [Bedrock, Azure, OpenAI, Anthropic, OpenAI, VertexAI, vLLM, Nvidia NIM]

61.8k12.6kPython
Toolsai-gatewayanthropicInstall
router-for-me
CLIProxyAPI
today

Wrap Antigravity, ChatGPT Codex, Claude Code, Grok Build, Muse Code, Devin as an OpenAI/Gemini/Claude/Codex compatible API service, allowing you to enjoy the free Gemini Series, GPT Series, Grok Series, Claude model through API

55.9k8.5kGo
Toolsantigravityclaude-codeInstall