atlury commited on
Commit
1ad72f4
·
verified ·
1 Parent(s): f1943e1

Create index.html

Browse files
Files changed (1) hide show
  1. index.html +216 -0
index.html ADDED
@@ -0,0 +1,216 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Voice Chat Bot</title>
7
+ <script src="https://cdn.jsdelivr.net/npm/onnxruntime-web/dist/ort.js"></script>
8
+ <script src="https://cdn.jsdelivr.net/npm/@ricky0123/vad-web@0.0.18/dist/bundle.min.js"></script>
9
+ <script src="https://cdn.jsdelivr.net/npm/@xenova/transformers@2.17.2"></script>
10
+ <style>
11
+ body {
12
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
13
+ max-width: 800px;
14
+ margin: 0 auto;
15
+ padding: 20px;
16
+ background-color: #f0f0f0;
17
+ color: #333;
18
+ }
19
+ h1 {
20
+ text-align: center;
21
+ color: #2c3e50;
22
+ }
23
+ #chat-container {
24
+ display: flex;
25
+ flex-direction: column;
26
+ height: 70vh;
27
+ }
28
+ #conversation {
29
+ flex-grow: 1;
30
+ border: 1px solid #ccc;
31
+ padding: 10px;
32
+ overflow-y: scroll;
33
+ background-color: white;
34
+ border-radius: 5px;
35
+ box-shadow: 0 2px 5px rgba(0,0,0,0.1);
36
+ }
37
+ #controls {
38
+ display: flex;
39
+ justify-content: center;
40
+ margin-top: 20px;
41
+ }
42
+ button {
43
+ font-size: 18px;
44
+ padding: 10px 20px;
45
+ margin: 0 10px;
46
+ background-color: #3498db;
47
+ color: white;
48
+ border: none;
49
+ border-radius: 5px;
50
+ cursor: pointer;
51
+ transition: background-color 0.3s;
52
+ }
53
+ button:hover {
54
+ background-color: #2980b9;
55
+ }
56
+ button:disabled {
57
+ background-color: #bdc3c7;
58
+ cursor: not-allowed;
59
+ }
60
+ #visualizer {
61
+ width: 100%;
62
+ height: 100px;
63
+ background-color: #34495e;
64
+ margin-top: 20px;
65
+ border-radius: 5px;
66
+ overflow: hidden;
67
+ }
68
+ .bar {
69
+ width: 5px;
70
+ height: 100%;
71
+ background-color: #3498db;
72
+ display: inline-block;
73
+ margin-right: 1px;
74
+ }
75
+ </style>
76
+ </head>
77
+ <body>
78
+ <h1>Voice Chat Bot</h1>
79
+ <div id="chat-container">
80
+ <div id="conversation"></div>
81
+ <div id="visualizer"></div>
82
+ <div id="controls">
83
+ <button id="startButton">Start Listening</button>
84
+ <button id="stopButton" disabled>Stop Listening</button>
85
+ </div>
86
+ </div>
87
+
88
+ <script type="module">
89
+ import { pipeline, env } from 'https://cdn.jsdelivr.net/npm/@xenova/transformers@2.17.2';
90
+
91
+ env.localModelPath = './models';
92
+
93
+ const conversationDiv = document.getElementById('conversation');
94
+ const startButton = document.getElementById('startButton');
95
+ const stopButton = document.getElementById('stopButton');
96
+ const visualizer = document.getElementById('visualizer');
97
+
98
+ let myvad;
99
+ let sttPipeline;
100
+ let ttsPipeline;
101
+ let audioContext;
102
+ let analyser;
103
+ let dataArray;
104
+ let bars;
105
+
106
+ function createVisualizer() {
107
+ const barCount = 64;
108
+ for (let i = 0; i < barCount; i++) {
109
+ const bar = document.createElement('div');
110
+ bar.className = 'bar';
111
+ visualizer.appendChild(bar);
112
+ }
113
+ bars = visualizer.getElementsByClassName('bar');
114
+ }
115
+
116
+ function updateVisualizer() {
117
+ analyser.getByteFrequencyData(dataArray);
118
+ for (let i = 0; i < bars.length; i++) {
119
+ const barHeight = dataArray[i] / 2;
120
+ bars[i].style.height = barHeight + 'px';
121
+ }
122
+ requestAnimationFrame(updateVisualizer);
123
+ }
124
+
125
+ async function initializePipelines() {
126
+ try {
127
+ sttPipeline = await pipeline('automatic-speech-recognition', 'Xenova/whisper-tiny.en');
128
+ ttsPipeline = await pipeline('text-to-speech', 'Xenova/mms-tts-eng', {
129
+ quantized: false,
130
+ });
131
+ addMessage('System', 'Voice Chat Bot initialized. Click "Start Listening" to begin.');
132
+ } catch (error) {
133
+ console.error('Error initializing pipelines:', error);
134
+ addMessage('System', 'Error initializing Voice Chat Bot. Please check the console for details.');
135
+ }
136
+ }
137
+
138
+ async function processSpeech(audio) {
139
+ try {
140
+ if (!sttPipeline || !ttsPipeline) {
141
+ throw new Error('Pipelines not initialized');
142
+ }
143
+
144
+ const transcription = await sttPipeline(audio);
145
+ addMessage('User', transcription.text);
146
+
147
+ const botResponse = `I heard you say: "${transcription.text}". This is a placeholder response.`;
148
+ addMessage('Bot', botResponse);
149
+
150
+ const speechOutput = await ttsPipeline(botResponse);
151
+ playAudio(speechOutput.audio);
152
+ } catch (error) {
153
+ console.error('Error processing speech:', error);
154
+ addMessage('System', 'Error processing speech. Please try again.');
155
+ }
156
+ }
157
+
158
+ function addMessage(sender, message) {
159
+ const messageElement = document.createElement('p');
160
+ messageElement.innerHTML = `<strong>${sender}:</strong> ${message}`;
161
+ conversationDiv.appendChild(messageElement);
162
+ conversationDiv.scrollTop = conversationDiv.scrollHeight;
163
+ }
164
+
165
+ function playAudio(audioArray) {
166
+ const audioBuffer = audioContext.createBuffer(1, audioArray.length, 16000);
167
+ const channelData = audioBuffer.getChannelData(0);
168
+ channelData.set(audioArray);
169
+
170
+ const source = audioContext.createBufferSource();
171
+ source.buffer = audioBuffer;
172
+ source.connect(analyser);
173
+ analyser.connect(audioContext.destination);
174
+ source.start();
175
+ }
176
+
177
+ async function startListening() {
178
+ try {
179
+ audioContext = new (window.AudioContext || window.webkitAudioContext)();
180
+ analyser = audioContext.createAnalyser();
181
+ analyser.fftSize = 128;
182
+ dataArray = new Uint8Array(analyser.frequencyBinCount);
183
+
184
+ myvad = await vad.MicVAD.new({
185
+ onSpeechEnd: (audio) => {
186
+ processSpeech(audio);
187
+ }
188
+ });
189
+ await myvad.start();
190
+ startButton.disabled = true;
191
+ stopButton.disabled = false;
192
+ addMessage('System', 'Listening...');
193
+ updateVisualizer();
194
+ } catch (error) {
195
+ console.error('Error starting VAD:', error);
196
+ addMessage('System', 'Error starting voice detection. Please check your microphone and try again.');
197
+ }
198
+ }
199
+
200
+ function stopListening() {
201
+ if (myvad) {
202
+ myvad.pause();
203
+ startButton.disabled = false;
204
+ stopButton.disabled = true;
205
+ addMessage('System', 'Stopped listening.');
206
+ }
207
+ }
208
+
209
+ startButton.addEventListener('click', startListening);
210
+ stopButton.addEventListener('click', stopListening);
211
+
212
+ createVisualizer();
213
+ initializePipelines();
214
+ </script>
215
+ </body>
216
+ </html>