Initial commit: Nat20 Notes — TTRPG session transcription & summarization
This commit is contained in:
91
README.md
Normal file
91
README.md
Normal file
@@ -0,0 +1,91 @@
|
||||
# Nat20 Notes
|
||||
|
||||
Turn a recorded tabletop RPG session (audio or video) into two documents:
|
||||
a full GM/DM session log, and a spoiler-free player recap — using local
|
||||
transcription (WhisperX) and either a local LLM (Ollama) or any
|
||||
OpenAI-compatible hosted API for summarization.
|
||||
|
||||
## Requirements
|
||||
|
||||
- Docker + Docker Compose
|
||||
- An NVIDIA GPU with drivers + [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html) installed on the host (for transcription; CPU-only works but is much slower)
|
||||
- A free [HuggingFace token](https://huggingface.co/settings/tokens) — needed for speaker diarization. You'll also need to accept the terms on the gated pyannote model page it links you to on first run.
|
||||
- Either: [Ollama](https://ollama.com) running somewhere reachable from this app (local or LAN), **or** an API key for a hosted LLM (OpenAI, or any OpenAI-compatible provider)
|
||||
|
||||
## Quick start
|
||||
|
||||
```bash
|
||||
git clone <this-repo>
|
||||
cd nat20-notes
|
||||
# Review docker-compose.yml — see Configuration below for env vars
|
||||
docker compose up -d --build
|
||||
```
|
||||
|
||||
Then open `http://<your-server>:8020` (yes, that port's a nod to the d20) and follow the setup wizard:
|
||||
|
||||
1. Choose a Whisper model size based on your GPU's available VRAM (guidance shown in-app)
|
||||
2. Choose local Ollama or a hosted API for summarization, and paste your HF token
|
||||
3. Optionally paste campaign/world context (NPC names, places) so summaries recognize them correctly
|
||||
|
||||
A reference compose file using named volumes only (no host paths) is at
|
||||
[`docker-compose.example.yml`](./docker-compose.example.yml).
|
||||
|
||||
## Using it
|
||||
|
||||
1. **Upload** a recording (audio or video — video is auto-converted, audio-only files skip that step and are much faster). Files over **90 MB** are auto-chunked with 3-way concurrent uploads.
|
||||
2. **Transcribe** — runs in the background. On completion you're **automatically taken** to the speaker-naming screen.
|
||||
3. **Name your speakers** — a waveform-style "session reel" shows each detected speaker's segments; click any point to jump the audio there and hear who's talking, then type in their name. Use the checkboxes to **merge** speakers (e.g. when diarization over-splits one person into `SPEAKER_00`, `SPEAKER_05`, etc.).
|
||||
4. **Generate notes** — click "Done naming" and confirm; notes generation starts automatically and you're taken to the job progress screen. When finished, navigate to the notes viewer.
|
||||
5. **Review & tweak** — regenerate notes, rename speakers, or delete jobs/sessions from the session detail page.
|
||||
|
||||
## Data layout
|
||||
|
||||
The app stores everything under `/data` (inside the container), which by default
|
||||
is a [bind mount](./docker-compose.yml) to a host path of your choice:
|
||||
|
||||
| Directory / File | Contents |
|
||||
|---|---|
|
||||
| `audio/` | Uploaded recordings and extracted audio |
|
||||
| `transcriptions/` | Per-session transcript JSON files |
|
||||
| `notes/` | Generated notes (GM log + player recap) |
|
||||
| `app.db` | SQLite database (sessions, speakers, settings, jobs) |
|
||||
|
||||
## Configuration
|
||||
|
||||
### Prefilling the setup wizard
|
||||
|
||||
Set `NAT20_*` environment variables under the `backend` service in
|
||||
`docker-compose.yml` — the wizard will pick them up as defaults:
|
||||
|
||||
```yaml
|
||||
environment:
|
||||
NAT20_HF_TOKEN: "hf_..."
|
||||
NAT20_WHISPER_MODEL: medium
|
||||
NAT20_OLLAMA_HOST: http://192.168.0.16:11434
|
||||
NAT20_WORLD_CONTEXT_PATH: /data/campaign-context.txt
|
||||
```
|
||||
|
||||
See the `environment:` block in `docker-compose.yml` for the full list.
|
||||
|
||||
### Campaign context
|
||||
|
||||
You can paste context directly in the Settings page, or point to a file
|
||||
inside the container using the `world_context_path` setting (or the
|
||||
`NAT20_WORLD_CONTEXT_PATH` env var). The file path version is useful for
|
||||
large campaign bibles that you update independently.
|
||||
|
||||
## Notes on hardware
|
||||
|
||||
Transcription is GPU-bound and by far the slowest step for long sessions.
|
||||
Summarization is comparatively light — a 7-8B parameter local model is
|
||||
sufficient for most groups; only step up in size if you have the VRAM
|
||||
headroom after Whisper's footprint (they don't run at the same time, so
|
||||
you only need enough VRAM for whichever is currently running, plus normal
|
||||
system overhead from other GPU-using services).
|
||||
|
||||
## Architecture
|
||||
|
||||
- `backend/` — FastAPI, SQLite (no external DB needed), WhisperX as a library (no nested Docker), in-process `ThreadPoolExecutor` background jobs (no Redis/Celery)
|
||||
- `frontend/` — React 18 + Vite + Tailwind, served via nginx (listens on port **8020**) which proxies `/api` to the backend
|
||||
|
||||
Both run as standard Docker Compose services — no special orchestration needed beyond GPU passthrough for the backend.
|
||||
Reference in New Issue
Block a user