Files
whisper-local/openwiki/workflows/recording-cycle.md
T
info 66ecf55ea9 docs: OpenWiki-Dokumentation und Auto-Update-Workflow hinzufügen
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>
2026-07-23 14:53:30 +02:00

4.2 KiB

type, title, description, tags
type title description tags
Workflow Aufnahme-Zyklus (Push-to-Talk) 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.
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 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.

Medien-Pause während Aufnahme

Wenn pause_media_during_recording = true (Standard), pausiert der 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 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.

Config-Reload zur Laufzeit

App._on_config_reload wird vom Einstellungs-Dialog 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.