File size: 4,602 Bytes
005d3a9 756a7d1 7451f00 005d3a9 7451f00 005d3a9 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
<!-- static/index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AI Voice Assistant</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
.conversation {
margin-top: 20px;
border: 1px solid #ccc;
padding: 20px;
height: 400px;
overflow-y: auto;
}
.status {
margin-top: 10px;
color: #666;
}
.user-message {
color: blue;
margin: 10px 0;
}
.assistant-message {
color: green;
margin: 10px 0;
}
</style>
</head>
<body>
<h1>AI Voice Assistant</h1>
<div class="status" id="status">Initializing...</div>
<div class="conversation" id="conversation"></div>
<script>
let mediaRecorder;
let socket;
let audioChunks = [];
async function initializeAudio() {
try {
const stream = await navigator.mediaDevices.getUserMedia({
audio: {
sampleRate: 16000,
channelCount: 1,
echoCancellation: true,
noiseSuppression: true
}
});
// Initialize WebSocket connection
socket = new WebSocket(`wss://${window.location.host}/ws`);
socket.onclose = () => {
document.getElementById('status').textContent = 'Reconnecting...';
setTimeout(initializeAudio, 1000); // Attempt reconnection
};
socket.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.user_text) {
addMessage('user', data.user_text);
addMessage('assistant', `German: ${data.response_de}\nEnglish: ${data.response_en}`);
}
if (data.audio) {
// Convert base64 audio to ArrayBuffer and play it
const audio = new Audio(URL.createObjectURL(
new Blob([new Uint8Array(atob(data.audio).split('').map(c => c.charCodeAt(0)))],
{ type: 'audio/wav' })
));
audio.play();
}
};
// Initialize MediaRecorder
mediaRecorder = new MediaRecorder(stream);
mediaRecorder.ondataavailable = (event) => {
if (event.data.size > 0) {
audioChunks.push(event.data);
}
// Send chunks to server
if (audioChunks.length > 0) {
const audioBlob = new Blob(audioChunks);
audioBlob.arrayBuffer().then(buffer => {
if (socket.readyState === WebSocket.OPEN) {
socket.send(buffer);
}
});
audioChunks = [];
}
};
// Start recording in chunks
mediaRecorder.start(2000); // Send 2 seconds of audio at a time
document.getElementById('status').textContent = 'Listening... (Say "Computer" to activate)';
} catch (error) {
console.error('Error initializing audio:', error);
document.getElementById('status').textContent = 'Error initializing audio';
}
}
function addMessage(sender, text) {
const conversation = document.getElementById('conversation');
const message = document.createElement('div');
message.className = sender === 'user' ? 'user-message' : 'assistant-message';
message.textContent = text;
conversation.appendChild(message);
conversation.scrollTop = conversation.scrollHeight;
}
// Initialize when page loads
window.addEventListener('load', initializeAudio);
</script>
</body>
</html> |