# Diarize + Transcribe (Local Drag-and-Drop)

A desktop app that combines state-of-the-art speaker diarization and transcription:

- **pyannote `speaker-diarization-community-1`** (pyannote.audio 4.x) — the best open-source diarization model in 2026, with improved speaker assignment and counting over `3.1`.
- **faster-whisper (CTranslate2)** with `large-v3` by default — fast, accurate transcription with word-level timestamps and built-in VAD filtering.
- **Word-level speaker attribution**: single-pass full-file transcription is aligned against the diarization timeline to assign a speaker to every word (using the `exclusive_speaker_diarization` output when available).

Outputs (written to `<input>_transcript_<timestamp>/`):
- `capspeaker.html` — interactive, clickable transcript synced to media playback
- `capspeaker.txt` — speaker-labeled plain text
- `diarization.json` — raw diarization turns
- `run_meta.json` — run parameters
- `audio_16k_mono.wav` — extracted audio
- `media.*` — a copy of the original media (or `media.mp3` for YouTube)

## Requirements

- Windows 10/11
- Python 3.10+ (the `py` launcher should work)
- A Hugging Face account + token

You must accept the model terms on Hugging Face before the token will work:
- `pyannote/speaker-diarization-community-1` (default)
- …or `pyannote/speaker-diarization-3.1` if you choose the older model

## Install

1. Extract the ZIP anywhere.
2. Double-click `setup.bat`
3. When it finishes, double-click `run.bat`

## Use

1. Drag and drop a media file into the input field
   - Supported: mp4, mov, mkv, webm, mp3, wav, m4a, flac, ogg
2. Or paste a YouTube URL.
3. Paste your Hugging Face token (starts with `hf_...`)
4. Pick settings:
   - **Whisper model**: `large-v3` (recommended), `large-v3-turbo` (faster, slightly less accurate), `distil-large-v3` (fastest English), or smaller `medium`/`small`/`base`/`tiny`
   - **Device**: `auto` picks CUDA if available, else CPU
   - **Compute type**: `auto` picks `float16` on CUDA, `int8` on CPU — the fastest safe defaults
   - **Language**: `auto` detects automatically; otherwise force a language code
5. Click **Run**
6. Click **Open output** when done
7. Open `capspeaker.html` in your browser

## GPU vs CPU

`faster-whisper` runs on CTranslate2 and is independent of PyTorch at inference time. The app auto-selects the best compute type:

- CUDA GPU → `float16` (fastest, full quality)
- CPU → `int8` (quantized, much faster than `float32`)

Diarization (pyannote) still uses PyTorch. It will use CUDA if your Torch build supports it:

1. Activate the venv: `.\.venv\Scripts\activate`
2. Install a CUDA Torch build from https://pytorch.org/get-started/locally/
3. Re-run `run.bat`

## Pipeline (what the app actually does)

1. `ffmpeg` extracts a mono 16 kHz WAV from the input.
2. `pyannote/speaker-diarization-community-1` produces speaker turns (and a non-overlapping `exclusive` timeline).
3. `faster-whisper` transcribes the entire WAV in one pass with `word_timestamps=True` and `vad_filter=True`.
4. Each word is assigned to the speaker with the largest temporal overlap.
5. Consecutive same-speaker words are grouped into blocks and rendered into the interactive HTML.

This replaces the older "prepend silence, slice per diarization segment, transcribe each slice" approach, which was a workaround for OpenAI-Whisper's warm-up artifacts and is no longer needed with VAD-filtered faster-whisper.

## Troubleshooting

### 1) "Hugging Face token is required"
Paste a real token like `hf_...` into the app.

### 2) `401 Unauthorized` / "You must accept the terms"
Open the model page on Hugging Face (`pyannote/speaker-diarization-community-1`) and accept the terms, then try again. Community-1 may request additional gated model acceptances.

### 3) `Failed to load diarization pipeline`
Usually means the token lacks access to the model. Re-accept terms and re-generate the token.

### 4) ffmpeg errors
This app uses `imageio-ffmpeg`. If conversion fails, update it:
- Activate venv then run: `pip install -U imageio-ffmpeg`

### 5) Slow runs
- Use a smaller / faster Whisper model (`distil-large-v3`, `large-v3-turbo`, or `medium`)
- Use a CUDA Torch build for diarization
- For CPU-only machines, `compute_type=int8` is already the default
