Files
satellite/web-client/html/index.html
T
sirmrakandQwen-Coder 2b4e6f824b feat: WebSocket команды — раздельная громкость mic/snd + запись аудио + обновлённый web-client
- satellite.py: разделён _runtime_volume на _runtime_mic_volume и _runtime_snd_volume
- satellite.py: добавлены команды start_recording/stop_recording (WAV через base64)
- satellite.py: метод _create_wav_from_buffer() для создания WAV из буфера
- web-client: добавлен слайдер громкости микрофона (MIC+/MIC-)
- web-client: добавлены кнопки записи и воспроизведения аудио
- web-client: улучшенный лог событий и отладочные console.log
- docs: websocket-server-plan.md сокращён с 1205 до ~80 строк

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-05-25 17:58:37 +03:00

128 lines
5.2 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<title>NOVA Voice Assistant</title>
<link rel="stylesheet" href="styles.css">
<script src="script.js" defer></script>
</head>
<body>
<div class="app-container">
<!-- Верхняя панель -->
<header class="app-header">
<div class="logo">
<span class="logo-icon">🎙️</span>
<span class="logo-text">NOVA Assistant</span>
</div>
<div class="connection-status">
<div class="led" id="statusLed"></div>
<span class="status-text" id="statusLabel">disconnected</span>
<button id="connectBtn" class="btn-outline">⟳ Connect</button>
</div>
</header>
<!-- Блок настроек WebSocket -->
<div class="settings-card glass">
<div class="settings-row">
<input type="text" id="wsUrlInput" value="ws://192.168.200.111:8675" placeholder="ws://ip:port" class="input-url">
<button id="connectBtnCard" class="btn-primary">Connect</button>
<label class="auto-connect">
<input type="checkbox" id="autoConnect" checked> Auto-connect
</label>
</div>
</div>
<!-- Основная сетка -->
<div class="dashboard">
<!-- Левая колонка: голосовой аватар -->
<div class="card voice-card glass">
<div class="card-header">
<span class="header-icon">🎤</span>
<h3>Voice Core</h3>
</div>
<div class="avatar-container">
<div class="orb" id="orbCore">
<div class="orb-pulse"></div>
<div class="orb-inner">🎙️</div>
</div>
<div class="state-badge" id="stateText">Idle</div>
</div>
<!-- Визуализатор аудио (волны) -->
<div class="viz-wrapper">
<canvas id="audioCanvas" width="500" height="80"></canvas>
</div>
<!-- RMS-метр -->
<div class="rms-container">
<div class="rms-label">RMS Level</div>
<div class="rms-bar">
<div class="rms-fill" id="rmsFill"></div>
</div>
<div class="rms-value" id="rmsValue">0.00</div>
</div>
<!-- Регулировка громкости -->
<div class="volume-control">
<span>🔊 Volume</span>
<input type="range" id="volumeSlider" min="0" max="1" step="0.01" value="0.8">
<span id="volumeValue" class="volume-percent">80%</span>
</div>
<div class="button-group">
<button id="muteBtn" class="btn-secondary">🔇 Mute</button>
<button id="unmuteBtn" class="btn-secondary">🎤 Unmute</button>
</div>
</div>
<!-- Центр: команды и транскрипция -->
<div class="card commands-card glass">
<div class="card-header">
<span class="header-icon">🕹️</span>
<h3>Commands & Transcripts</h3>
</div>
<div class="button-group">
<button id="startListeningBtn" class="btn-primary">🎧 Start Listen</button>
<button id="stopPipelineBtn" class="btn-danger">⏹️ Stop Pipeline</button>
<button id="stopTimerBtn" class="btn-secondary">⏲️ Stop Timer</button>
</div>
<div class="button-group">
<button id="volUpBtn" class="btn-secondary">➕ Vol+</button>
<button id="volDownBtn" class="btn-secondary">➖ Vol-</button>
<button id="requestRmsBtn" class="btn-secondary">📊 Request RMS</button>
</div>
<div class="button-group">
<button id="singlePressBtn" class="btn-outline">Single</button>
<button id="doublePressBtn" class="btn-outline">Double</button>
<button id="triplePressBtn" class="btn-outline">Triple</button>
<button id="longPressBtn" class="btn-outline">Long</button>
</div>
<div class="transcript-area">
<div class="transcript-item">
<div class="transcript-label">You said:</div>
<div id="lastStt" class="transcript-text">—</div>
</div>
<div class="transcript-item">
<div class="transcript-label">Assistant said:</div>
<div id="lastTts" class="transcript-text">—</div>
</div>
</div>
</div>
<!-- Правая колонка: телеметрия и логи -->
<div class="card telemetry-card glass">
<div class="card-header">
<span class="header-icon">📡</span>
<h3>Telemetry & Events</h3>
</div>
<div class="status-grid">
<div class="status-chip"><span>🔇 Muted:</span> <strong id="mutedStatus">—</strong></div>
<div class="status-chip"><span>🏠 HA:</span> <strong id="haStatus">—</strong></div>
<div class="status-chip"><span>🎚️ Vol:</span> <strong id="liveVol">—</strong></div>
</div>
<div class="event-feed" id="eventFeed">
<div class="event-item">⬤ Ready to connect...</div>
</div>
<button id="clearEvents" class="btn-secondary full-width">Clear log</button>
</div>
</div>
</div>
</body>
</html>