From 4a798748071d0f76b5e1f55ba7cef155fe321663 Mon Sep 17 00:00:00 2001 From: sirmrak Date: Thu, 21 May 2026 19:26:53 +0300 Subject: [PATCH] =?UTF-8?q?feat:=20Web=20Client=20=E2=80=94=20canvas=20?= =?UTF-8?q?=D0=B2=D0=B8=D0=B7=D1=83=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0=D1=86?= =?UTF-8?q?=D0=B8=D1=8F=20=D0=BE=D1=82=20satellite=20RMS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Изменения: - Удалён локальный микрофон (initMicVisualizer) - Canvas рисует RMS историю от satellite - 64 столбика с градиентом (зелёный → красный) - Меньше логов (только если RMS > 0.05) Преимущества: - ✅ Показывает реальную громкость satellite - ✅ Нет зависимости от микрофона браузера - ✅ Меньше спама в логах --- web-client/client.html | 81 ++++++++++++++-------------------- wyoming_satellite/satellite.py | 4 ++ 2 files changed, 37 insertions(+), 48 deletions(-) diff --git a/web-client/client.html b/web-client/client.html index 95726f1..ea9728f 100644 --- a/web-client/client.html +++ b/web-client/client.html @@ -281,7 +281,7 @@
- ⚡ LVA • NEXUS + ⚡ Wyoming Droid Assistant ⚡
@@ -482,7 +482,9 @@ // Audio level events if(eventType === 'audio-level') { if(json.data && json.data.level !== undefined) { - updateRmsMeter(json.data.level); + const level = json.data.level; + currentRms = level; // ✅ Обновляем currentRms для визуализации + updateRmsMeter(level); } } @@ -581,11 +583,13 @@ } } - // Визуализация микрофона (если доступен) — рисуем абстракцию ритма - let fakeAudioArray = new Uint8Array(64); - function drawVisualization() { + // Визуализация на canvas — рисуем RMS от satellite + let satelliteRmsHistory = new Array(64).fill(0); // История RMS значений + + function drawSatelliteVisualization() { if(!ctx) return; - requestAnimationFrame(drawVisualization); + requestAnimationFrame(drawSatelliteVisualization); + if(!isConnected) { ctx.clearRect(0,0,canvas.width, canvas.height); ctx.fillStyle = '#0a1222'; @@ -595,51 +599,34 @@ ctx.fillText('⚡ idle', canvas.width-50, 20); return; } - // имитация уровня громкости + случайный шум, если нет микрофона, но выглядит живо - let avg = 20; - if(analyser && analyser.fftSize) { - const dataArray = new Uint8Array(analyser.frequencyBinCount); - analyser.getByteFrequencyData(dataArray); - let sum = 0; - for(let i=0;i orb.style.animation='',700); - initMicVisualizer(); + // initMicVisualizer() — удалено, используем satellite RMS }; ws.onmessage = handleIncomingMessage; ws.onerror = (err) => { addEventToLog(`⚠️ WebSocket ошибка`); }; @@ -666,8 +653,6 @@ addEventToLog(`🔌 Отключено`); stateText.innerText = 'OFFLINE'; document.body.classList.remove('listening-active'); - if(mediaStream) mediaStream.getTracks().forEach(t=>t.stop()); - if(audioCtx) audioCtx.close(); }; } diff --git a/wyoming_satellite/satellite.py b/wyoming_satellite/satellite.py index 225762e..5befb21 100755 --- a/wyoming_satellite/satellite.py +++ b/wyoming_satellite/satellite.py @@ -1235,6 +1235,10 @@ class SatelliteBase: data={"level": self._last_mic_level} ) await self._broadcast_to_websocket(event) + + # Логировать только если уровень выше порога (чтобы не спамить) + if self._last_mic_level > 0.05: + _LOGGER.debug(f"Audio level: {self._last_mic_level:.2f}") # ------------------------------------------------------------------------- # Info