On-demand audio visualizer capture + UI fixes
- Audio capture starts only when first client subscribes, stops when last client unsubscribes (saves CPU/battery) - Add lifecycle lock to AudioAnalyzer for thread-safe start/stop - Status badge uses local visualizer state instead of server flag - Fix script name vertical text break on narrow screens - Fix script grid minimum column width on small viewports Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -53,6 +53,7 @@ class AudioAnalyzer:
|
||||
self._running = False
|
||||
self._thread: threading.Thread | None = None
|
||||
self._lock = threading.Lock()
|
||||
self._lifecycle_lock = threading.Lock()
|
||||
self._data: dict | None = None
|
||||
self._current_device_name: str | None = None
|
||||
|
||||
@@ -88,24 +89,26 @@ class AudioAnalyzer:
|
||||
|
||||
def start(self) -> bool:
|
||||
"""Start audio capture in a background thread. Returns False if unavailable."""
|
||||
if self._running:
|
||||
return True
|
||||
if not self.available:
|
||||
return False
|
||||
with self._lifecycle_lock:
|
||||
if self._running:
|
||||
return True
|
||||
if not self.available:
|
||||
return False
|
||||
|
||||
self._running = True
|
||||
self._thread = threading.Thread(target=self._capture_loop, daemon=True)
|
||||
self._thread.start()
|
||||
return True
|
||||
self._running = True
|
||||
self._thread = threading.Thread(target=self._capture_loop, daemon=True)
|
||||
self._thread.start()
|
||||
return True
|
||||
|
||||
def stop(self) -> None:
|
||||
"""Stop audio capture and cleanup."""
|
||||
self._running = False
|
||||
if self._thread:
|
||||
self._thread.join(timeout=3.0)
|
||||
self._thread = None
|
||||
with self._lock:
|
||||
self._data = None
|
||||
with self._lifecycle_lock:
|
||||
self._running = False
|
||||
if self._thread:
|
||||
self._thread.join(timeout=3.0)
|
||||
self._thread = None
|
||||
with self._lock:
|
||||
self._data = None
|
||||
|
||||
def get_frequency_data(self) -> dict | None:
|
||||
"""Return latest frequency data (thread-safe). None if not running."""
|
||||
|
||||
Reference in New Issue
Block a user