freddyaboulton HF staff commited on
Commit
e780bf4
·
verified ·
1 Parent(s): 829856e

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. index.html +120 -9
index.html CHANGED
@@ -80,13 +80,57 @@
80
  }
81
 
82
  button:hover {
83
- background-color: #ffffff;
84
- color: #0a0a0a;
 
85
  }
86
 
87
  #audio-output {
88
  display: none;
89
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
  </style>
91
  </head>
92
 
@@ -111,7 +155,57 @@
111
  const startButton = document.getElementById('start-button');
112
  const chatMessages = document.getElementById('chat-messages');
113
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114
  async function setupWebRTC() {
 
115
  const config = __RTC_CONFIGURATION__;
116
 
117
  peerConnection = new RTCPeerConnection(config);
@@ -121,6 +215,8 @@
121
  audio: true
122
  });
123
 
 
 
124
  stream.getTracks().forEach(track => {
125
  peerConnection.addTrack(track, stream);
126
  });
@@ -151,6 +247,11 @@
151
  }
152
  });
153
 
 
 
 
 
 
154
  webrtc_id = Math.random().toString(36).substring(7);
155
 
156
  const response = await fetch('/webrtc/offer', {
@@ -186,6 +287,15 @@
186
  }
187
 
188
  function stop() {
 
 
 
 
 
 
 
 
 
189
  if (peerConnection) {
190
  if (peerConnection.getTransceivers) {
191
  peerConnection.getTransceivers().forEach(transceiver => {
@@ -200,20 +310,21 @@
200
  if (sender.track && sender.track.stop) sender.track.stop();
201
  });
202
  }
203
-
204
- setTimeout(() => {
205
- peerConnection.close();
206
- }, 500);
207
  }
 
 
208
  }
209
 
210
  startButton.addEventListener('click', () => {
211
- if (startButton.textContent === 'Start Conversation') {
 
 
212
  setupWebRTC();
213
- startButton.textContent = 'Stop Conversation';
214
  } else {
 
215
  stop();
216
- startButton.textContent = 'Start Conversation';
217
  }
218
  });
219
  </script>
 
80
  }
81
 
82
  button:hover {
83
+ border-width: 2px;
84
+ transform: scale(1.02);
85
+ box-shadow: 0 0 10px rgba(255, 255, 255, 0.2);
86
  }
87
 
88
  #audio-output {
89
  display: none;
90
  }
91
+
92
+ .icon-with-spinner {
93
+ display: flex;
94
+ align-items: center;
95
+ justify-content: center;
96
+ gap: 12px;
97
+ min-width: 180px;
98
+ }
99
+
100
+ .spinner {
101
+ width: 20px;
102
+ height: 20px;
103
+ border: 2px solid #ffffff;
104
+ border-top-color: transparent;
105
+ border-radius: 50%;
106
+ animation: spin 1s linear infinite;
107
+ flex-shrink: 0;
108
+ }
109
+
110
+ @keyframes spin {
111
+ to {
112
+ transform: rotate(360deg);
113
+ }
114
+ }
115
+
116
+ .pulse-container {
117
+ display: flex;
118
+ align-items: center;
119
+ justify-content: center;
120
+ gap: 12px;
121
+ min-width: 180px;
122
+ }
123
+
124
+ .pulse-circle {
125
+ width: 20px;
126
+ height: 20px;
127
+ border-radius: 50%;
128
+ background-color: #ffffff;
129
+ opacity: 0.2;
130
+ flex-shrink: 0;
131
+ transform: translateX(-0%) scale(var(--audio-level, 1));
132
+ transition: transform 0.1s ease;
133
+ }
134
  </style>
135
  </head>
136
 
 
155
  const startButton = document.getElementById('start-button');
156
  const chatMessages = document.getElementById('chat-messages');
157
 
158
+ let audioLevel = 0;
159
+ let animationFrame;
160
+ let audioContext, analyser, audioSource;
161
+
162
+ function updateButtonState() {
163
+ const button = document.getElementById('start-button');
164
+ if (peerConnection && (peerConnection.connectionState === 'connecting' || peerConnection.connectionState === 'new')) {
165
+ button.innerHTML = `
166
+ <div class="icon-with-spinner">
167
+ <div class="spinner"></div>
168
+ <span>Connecting...</span>
169
+ </div>
170
+ `;
171
+ } else if (peerConnection && peerConnection.connectionState === 'connected') {
172
+ button.innerHTML = `
173
+ <div class="pulse-container">
174
+ <div class="pulse-circle"></div>
175
+ <span>Stop Conversation</span>
176
+ </div>
177
+ `;
178
+ } else {
179
+ button.innerHTML = 'Start Conversation';
180
+ }
181
+ }
182
+
183
+ function setupAudioVisualization(stream) {
184
+ audioContext = new (window.AudioContext || window.webkitAudioContext)();
185
+ analyser = audioContext.createAnalyser();
186
+ audioSource = audioContext.createMediaStreamSource(stream);
187
+ audioSource.connect(analyser);
188
+ analyser.fftSize = 64;
189
+ const dataArray = new Uint8Array(analyser.frequencyBinCount);
190
+
191
+ function updateAudioLevel() {
192
+ analyser.getByteFrequencyData(dataArray);
193
+ const average = Array.from(dataArray).reduce((a, b) => a + b, 0) / dataArray.length;
194
+ audioLevel = average / 255;
195
+
196
+ // Update CSS variable instead of rebuilding the button
197
+ const pulseCircle = document.querySelector('.pulse-circle');
198
+ if (pulseCircle) {
199
+ pulseCircle.style.setProperty('--audio-level', 1 + audioLevel);
200
+ }
201
+
202
+ animationFrame = requestAnimationFrame(updateAudioLevel);
203
+ }
204
+ updateAudioLevel();
205
+ }
206
+
207
  async function setupWebRTC() {
208
+ isConnecting = true;
209
  const config = __RTC_CONFIGURATION__;
210
 
211
  peerConnection = new RTCPeerConnection(config);
 
215
  audio: true
216
  });
217
 
218
+ setupAudioVisualization(stream);
219
+
220
  stream.getTracks().forEach(track => {
221
  peerConnection.addTrack(track, stream);
222
  });
 
247
  }
248
  });
249
 
250
+ peerConnection.addEventListener('connectionstatechange', () => {
251
+ console.log('connectionstatechange', peerConnection.connectionState);
252
+ updateButtonState();
253
+ });
254
+
255
  webrtc_id = Math.random().toString(36).substring(7);
256
 
257
  const response = await fetch('/webrtc/offer', {
 
287
  }
288
 
289
  function stop() {
290
+ if (animationFrame) {
291
+ cancelAnimationFrame(animationFrame);
292
+ }
293
+ if (audioContext) {
294
+ audioContext.close();
295
+ audioContext = null;
296
+ analyser = null;
297
+ audioSource = null;
298
+ }
299
  if (peerConnection) {
300
  if (peerConnection.getTransceivers) {
301
  peerConnection.getTransceivers().forEach(transceiver => {
 
310
  if (sender.track && sender.track.stop) sender.track.stop();
311
  });
312
  }
313
+ console.log('closing');
314
+ peerConnection.close();
 
 
315
  }
316
+ updateButtonState();
317
+ audioLevel = 0;
318
  }
319
 
320
  startButton.addEventListener('click', () => {
321
+ console.log('clicked');
322
+ console.log(peerConnection, peerConnection?.connectionState);
323
+ if (!peerConnection || peerConnection.connectionState !== 'connected') {
324
  setupWebRTC();
 
325
  } else {
326
+ console.log('stopping');
327
  stop();
 
328
  }
329
  });
330
  </script>