# meetcap
Offline meeting recorder & summarizer for macOS
## Features
- Records both system audio and microphone simultaneously
- 100% offline operation - no network connections
- Local transcription using Whisper
- Local summarization using Qwen3-4B via llama.cpp
- Simple CLI workflow: start recording → stop with hotkey → get transcript & summary
## Installation
### Prerequisites
1. **Install ffmpeg**:
```bash
brew install ffmpeg
```
2. **Install BlackHole** (for system audio capture):
- Download from: https://github.com/ExistentialAudio/BlackHole
- Install the 2ch version
> **Why BlackHole?** macOS doesn't provide a native way to capture system audio (sounds from other apps, video calls, etc.) as an input source. BlackHole creates a virtual audio device that routes system output into an input that meetcap can record.
3. **Configure Audio Routing**:
Open **Audio MIDI Setup** (Applications → Utilities) and create two devices:
**Step 1: Multi-Output Device** (so you can hear AND record system audio):
- Click "+" → Create Multi-Output Device
- Check: **Built-in Output** (or your preferred speakers/headphones)
- Check: **BlackHole 2ch**
- Right-click this device → "Use This Device For Sound Output"
- Name it "Multi-Output Device" (or similar)
**Step 2: Aggregate Device** (combines system audio + microphone):
- Click "+" → Create Aggregate Device
- Check: **BlackHole 2ch** (captures system audio routed from step 1)
- Check: **Your Microphone** (Built-in Microphone, USB mic, etc.)
- Set your microphone as **clock source** (right-click → Use This Device as Clock Source)
- Check **Drift Correction** for your microphone
- Name it "Aggregate Device" (or similar)
> **How it works:** System audio flows to Multi-Output → BlackHole → Aggregate Device, where it combines with your microphone for recording.
4. **Models** (selected and downloaded during setup):
- **Whisper models**: large-v3 (default), large-v3-turbo, or small
- **Vosk models** (with speaker identification): small (507MB), standard (1.8GB), or gigaspeech (3.3GB)
- **LLM models**: Qwen3-4B-Thinking (default), Qwen3-4B-Instruct, or GPT-OSS-20B
### Install meetcap
**macOS (Apple Silicon recommended):**
```bash
pip install "meetcap[mlx-stt]"
```
**Other platforms or Intel Macs:**
```bash
pip install "meetcap[stt]"
```
**With Vosk for speaker identification:**
```bash
pip install "meetcap[vosk-stt]"
```
**First-time setup:**
```bash
# Run interactive setup wizard (downloads models, tests permissions)
meetcap setup
# Quick system verification
meetcap verify
# See all available commands
meetcap --help
```
> **Note:** The `mlx-stt` extra includes MLX Whisper for faster transcription on Apple Silicon. The `stt` extra uses faster-whisper which works on all platforms.
## Usage
### Basic Recording
```bash
# Start recording (uses default/best audio device)
meetcap record
# Press ⌘+⇧+S or Ctrl-C to stop recording
```
### Process Existing Audio Files
```bash
# Transcribe and summarize an existing audio file
meetcap summarize path/to/meeting.m4a
# Specify output directory
meetcap summarize recording.m4a --out ./results
```
### Reprocess Recordings
```bash
# Reprocess both transcript and summary with different models
meetcap reprocess 2025_Jan_15_TeamStandup
# Reprocess only the summary (keep existing transcript)
meetcap reprocess 2025_Jan_15_TeamStandup --mode summary
# Use a different STT engine for transcription
meetcap reprocess /path/to/recording --stt mlx
# Use a custom LLM model for summarization
meetcap reprocess recording_dir --llm ~/.meetcap/models/custom_model.gguf
# Skip confirmation prompt
meetcap reprocess recording_dir --yes
```
The reprocess command allows you to regenerate transcripts and summaries with different models, useful for:
- Testing different STT engines (faster-whisper vs mlx-whisper)
- Trying different LLM models for better summaries
- Fixing issues with previous processing
- Experimenting with model settings
### Commands
```bash
# First-time setup (interactive wizard)
meetcap setup
# List available audio devices
meetcap devices
# Quick system verification
meetcap verify
# Start recording a meeting
meetcap record --device "Aggregate Device" --out ~/MyRecordings
# Process existing audio file (m4a, wav, mp3, etc.)
meetcap summarize samples/meeting.m4a --out ./processed
# Reprocess a recording with different models
meetcap reprocess 2025_Jan_15_TeamStandup --mode stt
```
### Configuration
Edit `~/.meetcap/config.toml` to customize:
- Default audio device
- STT engine selection (faster-whisper, mlx-whisper, vosk)
- Model settings (defaults to auto-downloaded models)
- LLM context size (16k, 32k, 64k, or 128k tokens)
- Hotkey combinations
- Output directories
Models are automatically downloaded to `~/.meetcap/models/` on first use.
#### STT Engine Options
meetcap supports multiple speech-to-text engines:
1. **Faster-Whisper** (default on Intel Macs):
- Best accuracy for general transcription
- Models: large-v3, large-v3-turbo, small
- Use: `--stt fwhisper`
2. **MLX-Whisper** (default on Apple Silicon):
- Optimized for Apple Silicon performance
- Models: large-v3-turbo, large-v3-mlx, small-mlx
- Use: `--stt mlx`
3. **Vosk** (speaker identification):
- Offline speech recognition with speaker diarization
- Identifies different speakers in the meeting
- Models: small (507MB), standard (1.8GB), gigaspeech (3.3GB)
- Use: `--stt vosk`
- Enable diarization in config:
```toml
[models]
stt_engine = "vosk"
enable_speaker_diarization = true
```
Speaker identification improves summaries by attributing statements to specific speakers.
#### Context Size Settings
The LLM context size determines how much transcript text can be processed at once:
- **16k tokens**: ~30 minute meetings
- **32k tokens**: ~1 hour meetings (default)
- **64k tokens**: ~2 hour meetings
- **128k tokens**: 3+ hour meetings
You can configure this during `meetcap setup` or manually edit `~/.meetcap/config.toml`:
```toml
[llm]
n_ctx = 32768 # Context size in tokens
```
**Automatic Batching**: When a transcript exceeds the configured context size, meetcap automatically:
1. Splits the transcript into overlapping chunks that fit within the context
2. Generates summaries for each chunk independently
3. Merges all chunk summaries into a final comprehensive summary
This ensures even very long meetings (4+ hours) can be processed, though larger context sizes provide better results by maintaining more continuity.
## Permissions
Grant these permissions to your terminal app:
1. **Microphone**: System Preferences → Privacy & Security → Microphone
2. **Input Monitoring**: System Preferences → Privacy & Security → Input Monitoring
## Troubleshooting
### Audio Setup Issues
**No audio devices found:**
- Ensure BlackHole is installed and Audio MIDI Setup devices are created
- Run `meetcap devices` to list available devices
- Try restarting your terminal or system after setup
**Can't hear system audio during recording:**
- Check that Multi-Output Device is set as system output (right-click in Audio MIDI Setup)
- Ensure Built-in Output is checked in your Multi-Output Device
- Test by playing music - you should hear it through your speakers
**Recording only captures microphone or only system audio:**
- Verify Aggregate Device includes both BlackHole 2ch AND your microphone
- Check that microphone is set as clock source in Aggregate Device
- Ensure Drift Correction is enabled for your microphone
- Use `meetcap record --device "Aggregate Device"` to specify the device explicitly
**Volume control keys causing errors:**
- This is a known compatibility issue with some pynput versions - the app should continue working normally despite the error message
## Output Files
Each recording session creates a dedicated folder with all meeting artifacts organized together:
```
~/Recordings/meetcap/
├── 2025_Jan_15_TeamStandup/
│ ├── recording.wav # Audio recording
│ ├── recording.transcript.txt # Plain text transcript
│ ├── recording.transcript.json # Transcript with timestamps
│ └── recording.summary.md # Meeting summary with AI-generated insights
├── 2025_Jan_16_ProductReview/
│ └── ... (same structure)
└── ...
```
### Folder Naming Convention
Meeting folders are automatically named using:
- **Date**: `YYYY_MMM_DD` format (e.g., `2025_Jan_15`)
- **Title**: AI-generated from meeting content in PascalCase (e.g., `TeamStandup`)
The AI analyzes your meeting transcript to generate a concise, descriptive title that captures the main topic discussed.
### Configuring Output Directory
The default output directory is `~/Recordings/meetcap/`. You can change this:
1. **During setup**: Run `meetcap setup` and specify your preferred directory
2. **In config file**: Edit `~/.meetcap/config.toml`:
```toml
[paths]
out_dir = "~/Documents/MyMeetings" # Your custom path
```
3. **Via environment variable**:
```bash
export MEETCAP_OUT_DIR="~/Documents/MyMeetings"
```
## License
MIT
Raw data
{
"_id": null,
"home_page": null,
"name": "meetcap",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": null,
"keywords": "macos, meeting, recorder, summarization, transcription",
"author": null,
"author_email": "Juan <juan@example.com>",
"download_url": "https://files.pythonhosted.org/packages/40/88/c9fbfd49a9dd12ba6d0022a6a2f5bba656957b55a945a04d12c5e55239ce/meetcap-1.2.0.tar.gz",
"platform": null,
"description": "# meetcap\n\nOffline meeting recorder & summarizer for macOS\n\n## Features\n\n- Records both system audio and microphone simultaneously\n- 100% offline operation - no network connections\n- Local transcription using Whisper\n- Local summarization using Qwen3-4B via llama.cpp\n- Simple CLI workflow: start recording \u2192 stop with hotkey \u2192 get transcript & summary\n\n## Installation\n\n### Prerequisites\n\n1. **Install ffmpeg**:\n ```bash\n brew install ffmpeg\n ```\n\n2. **Install BlackHole** (for system audio capture):\n - Download from: https://github.com/ExistentialAudio/BlackHole\n - Install the 2ch version\n\n > **Why BlackHole?** macOS doesn't provide a native way to capture system audio (sounds from other apps, video calls, etc.) as an input source. BlackHole creates a virtual audio device that routes system output into an input that meetcap can record.\n\n3. **Configure Audio Routing**:\n\n Open **Audio MIDI Setup** (Applications \u2192 Utilities) and create two devices:\n\n **Step 1: Multi-Output Device** (so you can hear AND record system audio):\n - Click \"+\" \u2192 Create Multi-Output Device\n - Check: **Built-in Output** (or your preferred speakers/headphones)\n - Check: **BlackHole 2ch**\n - Right-click this device \u2192 \"Use This Device For Sound Output\"\n - Name it \"Multi-Output Device\" (or similar)\n\n **Step 2: Aggregate Device** (combines system audio + microphone):\n - Click \"+\" \u2192 Create Aggregate Device\n - Check: **BlackHole 2ch** (captures system audio routed from step 1)\n - Check: **Your Microphone** (Built-in Microphone, USB mic, etc.)\n - Set your microphone as **clock source** (right-click \u2192 Use This Device as Clock Source)\n - Check **Drift Correction** for your microphone\n - Name it \"Aggregate Device\" (or similar)\n\n > **How it works:** System audio flows to Multi-Output \u2192 BlackHole \u2192 Aggregate Device, where it combines with your microphone for recording.\n\n4. **Models** (selected and downloaded during setup):\n - **Whisper models**: large-v3 (default), large-v3-turbo, or small\n - **Vosk models** (with speaker identification): small (507MB), standard (1.8GB), or gigaspeech (3.3GB)\n - **LLM models**: Qwen3-4B-Thinking (default), Qwen3-4B-Instruct, or GPT-OSS-20B\n\n### Install meetcap\n\n**macOS (Apple Silicon recommended):**\n```bash\npip install \"meetcap[mlx-stt]\"\n```\n\n**Other platforms or Intel Macs:**\n```bash\npip install \"meetcap[stt]\"\n```\n\n**With Vosk for speaker identification:**\n```bash\npip install \"meetcap[vosk-stt]\"\n```\n\n**First-time setup:**\n```bash\n# Run interactive setup wizard (downloads models, tests permissions)\nmeetcap setup\n\n# Quick system verification\nmeetcap verify\n\n# See all available commands\nmeetcap --help\n```\n\n> **Note:** The `mlx-stt` extra includes MLX Whisper for faster transcription on Apple Silicon. The `stt` extra uses faster-whisper which works on all platforms.\n\n## Usage\n\n### Basic Recording\n\n```bash\n# Start recording (uses default/best audio device)\nmeetcap record\n\n# Press \u2318+\u21e7+S or Ctrl-C to stop recording\n```\n\n### Process Existing Audio Files\n\n```bash\n# Transcribe and summarize an existing audio file\nmeetcap summarize path/to/meeting.m4a\n\n# Specify output directory\nmeetcap summarize recording.m4a --out ./results\n```\n\n### Reprocess Recordings\n\n```bash\n# Reprocess both transcript and summary with different models\nmeetcap reprocess 2025_Jan_15_TeamStandup\n\n# Reprocess only the summary (keep existing transcript)\nmeetcap reprocess 2025_Jan_15_TeamStandup --mode summary\n\n# Use a different STT engine for transcription\nmeetcap reprocess /path/to/recording --stt mlx\n\n# Use a custom LLM model for summarization\nmeetcap reprocess recording_dir --llm ~/.meetcap/models/custom_model.gguf\n\n# Skip confirmation prompt\nmeetcap reprocess recording_dir --yes\n```\n\nThe reprocess command allows you to regenerate transcripts and summaries with different models, useful for:\n- Testing different STT engines (faster-whisper vs mlx-whisper)\n- Trying different LLM models for better summaries\n- Fixing issues with previous processing\n- Experimenting with model settings\n\n### Commands\n\n```bash\n# First-time setup (interactive wizard)\nmeetcap setup\n\n# List available audio devices\nmeetcap devices\n\n# Quick system verification\nmeetcap verify\n\n# Start recording a meeting\nmeetcap record --device \"Aggregate Device\" --out ~/MyRecordings\n\n# Process existing audio file (m4a, wav, mp3, etc.)\nmeetcap summarize samples/meeting.m4a --out ./processed\n\n# Reprocess a recording with different models\nmeetcap reprocess 2025_Jan_15_TeamStandup --mode stt\n```\n\n### Configuration\n\nEdit `~/.meetcap/config.toml` to customize:\n- Default audio device\n- STT engine selection (faster-whisper, mlx-whisper, vosk)\n- Model settings (defaults to auto-downloaded models)\n- LLM context size (16k, 32k, 64k, or 128k tokens)\n- Hotkey combinations\n- Output directories\n\nModels are automatically downloaded to `~/.meetcap/models/` on first use.\n\n#### STT Engine Options\n\nmeetcap supports multiple speech-to-text engines:\n\n1. **Faster-Whisper** (default on Intel Macs):\n - Best accuracy for general transcription\n - Models: large-v3, large-v3-turbo, small\n - Use: `--stt fwhisper`\n\n2. **MLX-Whisper** (default on Apple Silicon):\n - Optimized for Apple Silicon performance\n - Models: large-v3-turbo, large-v3-mlx, small-mlx\n - Use: `--stt mlx`\n\n3. **Vosk** (speaker identification):\n - Offline speech recognition with speaker diarization\n - Identifies different speakers in the meeting\n - Models: small (507MB), standard (1.8GB), gigaspeech (3.3GB)\n - Use: `--stt vosk`\n - Enable diarization in config:\n ```toml\n [models]\n stt_engine = \"vosk\"\n enable_speaker_diarization = true\n ```\n\nSpeaker identification improves summaries by attributing statements to specific speakers.\n\n#### Context Size Settings\n\nThe LLM context size determines how much transcript text can be processed at once:\n- **16k tokens**: ~30 minute meetings\n- **32k tokens**: ~1 hour meetings (default)\n- **64k tokens**: ~2 hour meetings\n- **128k tokens**: 3+ hour meetings\n\nYou can configure this during `meetcap setup` or manually edit `~/.meetcap/config.toml`:\n```toml\n[llm]\nn_ctx = 32768 # Context size in tokens\n```\n\n**Automatic Batching**: When a transcript exceeds the configured context size, meetcap automatically:\n1. Splits the transcript into overlapping chunks that fit within the context\n2. Generates summaries for each chunk independently\n3. Merges all chunk summaries into a final comprehensive summary\n\nThis ensures even very long meetings (4+ hours) can be processed, though larger context sizes provide better results by maintaining more continuity.\n\n## Permissions\n\nGrant these permissions to your terminal app:\n1. **Microphone**: System Preferences \u2192 Privacy & Security \u2192 Microphone\n2. **Input Monitoring**: System Preferences \u2192 Privacy & Security \u2192 Input Monitoring\n\n## Troubleshooting\n\n### Audio Setup Issues\n\n**No audio devices found:**\n- Ensure BlackHole is installed and Audio MIDI Setup devices are created\n- Run `meetcap devices` to list available devices\n- Try restarting your terminal or system after setup\n\n**Can't hear system audio during recording:**\n- Check that Multi-Output Device is set as system output (right-click in Audio MIDI Setup)\n- Ensure Built-in Output is checked in your Multi-Output Device\n- Test by playing music - you should hear it through your speakers\n\n**Recording only captures microphone or only system audio:**\n- Verify Aggregate Device includes both BlackHole 2ch AND your microphone\n- Check that microphone is set as clock source in Aggregate Device\n- Ensure Drift Correction is enabled for your microphone\n- Use `meetcap record --device \"Aggregate Device\"` to specify the device explicitly\n\n**Volume control keys causing errors:**\n- This is a known compatibility issue with some pynput versions - the app should continue working normally despite the error message\n\n## Output Files\n\nEach recording session creates a dedicated folder with all meeting artifacts organized together:\n\n```\n~/Recordings/meetcap/\n\u251c\u2500\u2500 2025_Jan_15_TeamStandup/\n\u2502 \u251c\u2500\u2500 recording.wav # Audio recording\n\u2502 \u251c\u2500\u2500 recording.transcript.txt # Plain text transcript\n\u2502 \u251c\u2500\u2500 recording.transcript.json # Transcript with timestamps\n\u2502 \u2514\u2500\u2500 recording.summary.md # Meeting summary with AI-generated insights\n\u251c\u2500\u2500 2025_Jan_16_ProductReview/\n\u2502 \u2514\u2500\u2500 ... (same structure)\n\u2514\u2500\u2500 ...\n```\n\n### Folder Naming Convention\n\nMeeting folders are automatically named using:\n- **Date**: `YYYY_MMM_DD` format (e.g., `2025_Jan_15`)\n- **Title**: AI-generated from meeting content in PascalCase (e.g., `TeamStandup`)\n\nThe AI analyzes your meeting transcript to generate a concise, descriptive title that captures the main topic discussed.\n\n### Configuring Output Directory\n\nThe default output directory is `~/Recordings/meetcap/`. You can change this:\n\n1. **During setup**: Run `meetcap setup` and specify your preferred directory\n2. **In config file**: Edit `~/.meetcap/config.toml`:\n ```toml\n [paths]\n out_dir = \"~/Documents/MyMeetings\" # Your custom path\n ```\n3. **Via environment variable**:\n ```bash\n export MEETCAP_OUT_DIR=\"~/Documents/MyMeetings\"\n ```\n\n## License\n\nMIT\n",
"bugtrack_url": null,
"license": null,
"summary": "Offline meeting recorder & summarizer for macOS",
"version": "1.2.0",
"project_urls": null,
"split_keywords": [
"macos",
" meeting",
" recorder",
" summarization",
" transcription"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "171e5c816a2b1b667eaa54dbb6b6a9a50afd9cfddb042c886253c776bfa94cd8",
"md5": "89b3051447e26605fde9d82c7848d85e",
"sha256": "b3c7bb655a86caff472db732e5640f18f9776c89540d9579ab0507a7dad227fd"
},
"downloads": -1,
"filename": "meetcap-1.2.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "89b3051447e26605fde9d82c7848d85e",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10",
"size": 47690,
"upload_time": "2025-08-12T04:09:20",
"upload_time_iso_8601": "2025-08-12T04:09:20.216412Z",
"url": "https://files.pythonhosted.org/packages/17/1e/5c816a2b1b667eaa54dbb6b6a9a50afd9cfddb042c886253c776bfa94cd8/meetcap-1.2.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "4088c9fbfd49a9dd12ba6d0022a6a2f5bba656957b55a945a04d12c5e55239ce",
"md5": "37397e8022d9c5791c3925a9b1d6c836",
"sha256": "dd3cd54a259b14b04728ebf50d340513a61b8cc86fe2c542bb1f7ff433f9d138"
},
"downloads": -1,
"filename": "meetcap-1.2.0.tar.gz",
"has_sig": false,
"md5_digest": "37397e8022d9c5791c3925a9b1d6c836",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 87335,
"upload_time": "2025-08-12T04:09:21",
"upload_time_iso_8601": "2025-08-12T04:09:21.192582Z",
"url": "https://files.pythonhosted.org/packages/40/88/c9fbfd49a9dd12ba6d0022a6a2f5bba656957b55a945a04d12c5e55239ce/meetcap-1.2.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-12 04:09:21",
"github": false,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"lcname": "meetcap"
}