66ecf55ea9
Fügt generierte OpenWiki-Docs (Architektur, Domain, Betrieb, Tests, Workflows) sowie den GitHub-Actions-Workflow zur automatischen Aktualisierung hinzu. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
72 lines
4.2 KiB
Markdown
72 lines
4.2 KiB
Markdown
---
|
|
type: Workflow
|
|
title: Aufnahme-Zyklus (Push-to-Talk)
|
|
description: "Der Kern-Workflow von whisper-local: Hotkey drücken → Audio aufnehmen → Medien pausieren → Hotkey loslassen → transkribieren → Text einfügen → Medien fortsetzen. Sowie Mikrofon-Überwachung und Config-Reload."
|
|
tags: [workflow, push-to-talk, recording, transcription, media-pause, microphone-monitor]
|
|
---
|
|
|
|
# Aufnahme-Zyklus (Push-to-Talk)
|
|
|
|
Der zentrale Workflow wird durch die `App`-Klasse in [`__main__.py`](../../whisper_local/__main__.py) orchestriert. Die beiden Callbacks `on_press` und `on_release` bilden den vollständigen Zyklus.
|
|
|
|
## Push-to-Talk-Flow
|
|
|
|
```
|
|
Hotkey gedrückt (on_press)
|
|
1. Tray.set_state(RECORDING) — Icon wird rot
|
|
2. await media.pause() — alle Playing-Sessions pausieren
|
|
3. recorder.start() — sounddevice.InputStream öffnet
|
|
|
|
Hotkey losgelassen (on_release)
|
|
1. recorder.stop() — Stream schließen, Audio-Array zurück
|
|
2. await media.resume() — pausierte Sessions fortsetzen (im finally-Block)
|
|
3. Wenn audio == None → Tray WAITING, return
|
|
4. Tray.set_state(TRANSCRIBING) — Icon wird gelb
|
|
5. transcriber.transcribe(audio) — faster-whisper transkribiert lokal
|
|
6. await inserter.insert(text) — Text ins aktive Textfeld einfügen
|
|
7. Tray.set_state(WAITING) — Icon wird grau
|
|
```
|
|
|
|
### Mindestdauer-Filter
|
|
|
|
`Recorder.stop()` verwirft Aufnahmen kürzer als `min_duration` (Standard: 0,5 s). In diesem Fall gibt `stop()` `None` zurück und der Zyklus wird abgebrochen — keine Transkription, kein Einfügen. Das verhindert versehentliche Trigger bei kurzen Hotkey-Berührungen.
|
|
|
|
### Text-Einfügung mit Clipboard-Restaurierung
|
|
|
|
Beide Inserter-Backends (Wayland und Win32) folgen demselben Muster:
|
|
|
|
1. Alten Clipboard-Inhalt sichern.
|
|
2. Transkribierten Text ins Clipboard setzen.
|
|
3. `Ctrl+V` simulieren (ydotool unter Wayland, pynput unter Windows).
|
|
4. Kurz warten (`PASTE_DELAY = 0.2s`).
|
|
5. Alten Clipboard-Inhalt wiederherstellen (im `finally`-Block).
|
|
|
|
Dadurch bleibt der bisherige Clipboard-Inhalt des Nutzers erhalten. Details siehe [Plattform-Abstraktionen → Inserter](../domain/platform-abstractions.md#inserter).
|
|
|
|
## Medien-Pause während Aufnahme
|
|
|
|
Wenn `pause_media_during_recording = true` (Standard), pausiert der [MediaController](../domain/platform-abstractions.md#mediacontroller) alle aktiv wiedergebenden Sessions bei Aufnahmestart und setzt nur diejenigen fort, die er selbst pausiert hat. Der Circuit-Breaker deaktiviert die Funktion dauerhaft, wenn D-Bus (Linux) oder SMTC (Windows) nicht verfügbar ist.
|
|
|
|
## Mikrofon-Überwachung
|
|
|
|
Der `MicrophoneMonitor` läuft als Hintergrund-Task und überwacht Audio-Geräte-Änderungen:
|
|
|
|
- **Gerät entfernt**: Wenn das konfigurierte Mikrofon getrennt wird, wechselt `App._on_configured_microphone_missing` auf das Standard-Gerät, zeigt eine Desktop-Benachrichtigung via [notify-py](../../whisper_local/tray/_notification.py) und setzt eine Tray-Warnung (`set_warning("Mikrofon nicht gefunden")`).
|
|
- **Gerät hinzugefügt**: Wenn das konfigurierte Mikrofon wieder verfügbar wird, stellt `App._on_microphone_added` es wieder her, benachrichtigt den Nutzer und entfernt die Tray-Warnung.
|
|
- **Start-Check**: Beim Start meldet `PollMonitor` sofort, wenn das konfigurierte Gerät nicht gefunden wird.
|
|
|
|
Windows verwendet `IMMNotificationClient` (COM Core Audio API) für Event-basierte Benachrichtigungen mit automatischem Polling-Fallback. Linux verwendet den `PollMonitor` (2,5 s Intervall). Details siehe [Plattform-Abstraktionen → Mikrofon-Monitor](../domain/platform-abstractions.md#mikrofon-monitor).
|
|
|
|
## Config-Reload zur Laufzeit
|
|
|
|
`App._on_config_reload` wird vom [Einstellungs-Dialog](../../whisper_local/tray/_settings.py) aufgerufen und tauscht alle dynamischen Komponenten ohne Neustart aus:
|
|
|
|
1. Neue Config übernehmen.
|
|
2. Recorder neu instanziieren (neues Mikrofon/Sample-Rate).
|
|
3. Mikrofon-Monitor stoppen und neu starten.
|
|
4. Tray-Warnung zurücksetzen.
|
|
5. Alten Media-Controller fortsetzen, neuen erstellen.
|
|
6. Hotkey-Listener stoppen und neu starten (`_restart_hotkey`).
|
|
|
|
Der Hotkey-Restart benötigt ein kurzes `await asyncio.sleep(0.1)` zwischen Stop und Start, um den alten Listener sauber abzubauen.
|