Add audio visualizer with spectrogram, beat-reactive art, and device selection
- New audio_analyzer service: loopback capture via soundcard + numpy FFT - Real-time spectrogram bars below album art with accent color gradient - Album art and vinyl pulse to bass energy beats - WebSocket subscriber pattern for opt-in audio data streaming - Audio device selection in Settings tab with auto-detect fallback - Optimized FFT pipeline: vectorized cumsum bin grouping, pre-serialized JSON broadcast - Visualizer config: enabled/fps/bins/device in config.yaml - Optional deps: soundcard + numpy (graceful degradation if missing) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -59,8 +59,32 @@ async def lifespan(app: FastAPI):
|
||||
await ws_manager.start_status_monitor(controller.get_status)
|
||||
logger.info("WebSocket status monitor started")
|
||||
|
||||
# Start audio visualizer (if enabled and dependencies available)
|
||||
analyzer = None
|
||||
if settings.visualizer_enabled:
|
||||
from .services.audio_analyzer import get_audio_analyzer
|
||||
|
||||
analyzer = get_audio_analyzer(
|
||||
num_bins=settings.visualizer_bins,
|
||||
target_fps=settings.visualizer_fps,
|
||||
device_name=settings.visualizer_device,
|
||||
)
|
||||
if analyzer.available:
|
||||
if analyzer.start():
|
||||
await ws_manager.start_audio_monitor(analyzer)
|
||||
logger.info("Audio visualizer started")
|
||||
else:
|
||||
logger.warning("Audio visualizer failed to start (no loopback device?)")
|
||||
else:
|
||||
logger.info("Audio visualizer unavailable (install soundcard + numpy)")
|
||||
|
||||
yield
|
||||
|
||||
# Stop audio visualizer
|
||||
await ws_manager.stop_audio_monitor()
|
||||
if analyzer and analyzer.running:
|
||||
analyzer.stop()
|
||||
|
||||
# Stop WebSocket status monitor
|
||||
await ws_manager.stop_status_monitor()
|
||||
logger.info("Media Server shutting down")
|
||||
|
||||
Reference in New Issue
Block a user