Files
say/public/index.html
T

74 lines
2.7 KiB
HTML

<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Say — Voice Assistant</title>
<link rel="stylesheet" href="/style.css">
</head>
<body>
<h1>Say</h1>
<div id="models">
<button class="model-btn" data-model="ddm-120">DDM-120</button>
<button class="model-btn" data-model="ddm-20">DDM-20</button>
<button class="model-btn" data-model="qwen">Qwen</button>
<button class="model-btn active" data-model="deepseek">DeepSeek</button>
</div>
<div id="chat"></div>
<div id="recorder">
<button id="mic-btn">Start Recording</button>
<span id="status"></span>
</div>
<script>
let mediaRecorder, chunks = [];
const micBtn = document.getElementById('mic-btn');
const status = document.getElementById('status');
const chat = document.getElementById('chat');
let activeModel = 'deepseek';
document.querySelectorAll('.model-btn').forEach(b => {
b.addEventListener('click', () => {
document.querySelectorAll('.model-btn').forEach(x => x.classList.remove('active'));
b.classList.add('active');
activeModel = b.dataset.model;
});
});
micBtn.addEventListener('click', async () => {
if (mediaRecorder && mediaRecorder.state === 'recording') {
mediaRecorder.stop();
micBtn.textContent = 'Processing...';
return;
}
chunks = [];
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
mediaRecorder = new MediaRecorder(stream);
mediaRecorder.ondataavailable = e => chunks.push(e.data);
mediaRecorder.onstop = async () => {
stream.getTracks().forEach(t => t.stop());
const blob = new Blob(chunks, { type: 'audio/webm' });
const fd = new FormData(); fd.append('audio', blob);
status.textContent = 'Transcribing...';
const t = await fetch('/api/whisper', { method: 'POST', body: fd }).then(r => r.json());
chat.innerHTML += '<div class="user">You: ' + t.text + '</div>';
status.textContent = activeModel + ' thinking...';
const r = await fetch('/api/chat', {
method: 'POST', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ model: activeModel, message: t.text }),
}).then(r => r.json());
chat.innerHTML += '<div class="bot">' + activeModel + ': ' + r.response + '</div>';
chat.scrollTop = chat.scrollHeight;
micBtn.textContent = 'Start Recording';
status.textContent = '';
};
mediaRecorder.start();
micBtn.textContent = 'Stop Recording';
status.textContent = 'Recording...';
});
</script>
</body>
</html>