114 lines
3.9 KiB
Markdown
114 lines
3.9 KiB
Markdown
# Settings Page & Remote Whisper Design
|
|
|
|
**Date:** 2026-04-01
|
|
|
|
## Goal
|
|
|
|
Give each Linux client a settings page to configure audio device (via PipeWire/pactl) and remote server URLs (Whisper + Ollama). Beastix runs faster-whisper-server and Ollama; clients point their config at it.
|
|
|
|
## Architecture
|
|
|
|
```
|
|
┌─────────────────┐ ┌─────────────────────────────┐
|
|
│ Client (Linux) │ │ Beastix (LAN) │
|
|
│ │ WAV │ │
|
|
│ sounddevice │ ──────► │ faster-whisper-server │
|
|
│ PipeWire src │ │ :8000 (OpenAI-kompatibel) │
|
|
│ localhost:8765 │ Text │ │
|
|
│ Browser UI │ ◄────── │ Ollama :11434 │
|
|
└─────────────────┘ └─────────────────────────────┘
|
|
```
|
|
|
|
Default: `whisper.base_url` leer → lokale faster-whisper-Instanz. Gesetzt → HTTP-Upload an Beastix.
|
|
|
|
## Settings Page (`/settings`)
|
|
|
|
Nur für Admins sichtbar (Gear-Icon im Header). Zwei Abschnitte:
|
|
|
|
### Abschnitt 1 — Audio
|
|
|
|
- Dropdown: alle verfügbaren PipeWire-Sources (live via `pactl list sources short`)
|
|
- Button "Combined Source erstellen" → App führt pactl-Kommandos aus, Combined Source erscheint in der Liste
|
|
- Gewähltes Device → `config.toml [audio] device = "..."`
|
|
- sounddevice nutzt diesen Device-Namen beim nächsten Start einer Aufnahme
|
|
|
|
### Abschnitt 2 — Verarbeitung
|
|
|
|
- Whisper `base_url`: leer = lokal, sonst z.B. `http://beastix:8000`
|
|
- Whisper `model`: Freitextfeld (default: `large-v3`)
|
|
- Ollama `base_url`: z.B. `http://beastix:11434`
|
|
- Ollama `model`: Dropdown gefüllt via `GET {ollama_base_url}/api/tags`
|
|
|
|
Änderungen werden sofort in `config.toml` gespeichert (PUT /config).
|
|
|
|
## Remote Whisper (transcription.py)
|
|
|
|
```python
|
|
if cfg["whisper"].get("base_url"):
|
|
# OpenAI-kompatibler Upload
|
|
POST {base_url}/v1/audio/transcriptions
|
|
multipart: file=<wav>, model=<model>, language=<lang>
|
|
→ response.text
|
|
else:
|
|
# Lokal wie bisher
|
|
WhisperModel(model_name, device=device).transcribe(...)
|
|
```
|
|
|
|
## Neue API-Endpoints
|
|
|
|
| Method | Path | Beschreibung |
|
|
|--------|------|--------------|
|
|
| GET | `/settings` | Liefert settings.html |
|
|
| GET | `/audio/devices` | pactl sources geparst → JSON-Liste |
|
|
| POST | `/audio/combined` | Erstellt PipeWire Combined Source via pactl |
|
|
|
|
PUT `/config` ist bereits vorhanden — wird um `audio.device` und `whisper.base_url` erweitert.
|
|
|
|
## Config-Schema Erweiterung
|
|
|
|
```toml
|
|
[audio]
|
|
device = "" # leer = Systemstandard, sonst PipeWire-Source-Name
|
|
|
|
[whisper]
|
|
model = "large-v3"
|
|
language = "de"
|
|
device = "auto"
|
|
base_url = "" # leer = lokal, sonst http://beastix:8000
|
|
```
|
|
|
|
## PipeWire Combined Source
|
|
|
|
Beim Klick auf "Combined Source erstellen":
|
|
|
|
```bash
|
|
pactl load-module module-null-sink \
|
|
sink_name=transkriptor-combined \
|
|
sink_properties=device.description="Transkriptor\ Combined"
|
|
|
|
pactl load-module module-loopback \
|
|
source=<mic-device> sink=transkriptor-combined
|
|
|
|
pactl load-module module-loopback \
|
|
source=<default-output>.monitor sink=transkriptor-combined
|
|
```
|
|
|
|
Ergebnis: `transkriptor-combined.monitor` erscheint als aufnehmbare Source in der Liste.
|
|
|
|
Die Module-IDs werden in `config.toml` gespeichert damit sie beim App-Stop sauber entladen werden können (`pactl unload-module <id>`).
|
|
|
|
## Beastix Setup (einmalig)
|
|
|
|
```bash
|
|
pip install faster-whisper-server
|
|
faster-whisper-server --host 0.0.0.0 --port 8000 --model large-v3
|
|
```
|
|
|
|
Oder als systemd user service. Clients tragen dann `whisper.base_url = "http://beastix:8000"` ein.
|
|
|
|
## Nicht in diesem Scope
|
|
|
|
- Nutzer-Verwaltung über Settings (eigene Seite)
|
|
- Automatischer Neustart wenn Config sich ändert
|
|
- Windows-Support
|