

if websocket connection fails, frontend does not allow recording
@4f252ff4c61200632aaa0190e2559e2886c32599
--- src/live_transcription.html
+++ src/live_transcription.html
... | ... | @@ -101,11 +101,11 @@ |
101 | 101 |
<div id="transcriptions"></div> |
102 | 102 |
|
103 | 103 |
<script> |
104 |
- let isRecording = false, |
|
105 |
- websocket, |
|
106 |
- recorder, |
|
107 |
- chunkDuration = 1000, |
|
108 |
- websocketUrl = "ws://localhost:8000/asr"; |
|
104 |
+ let isRecording = false; |
|
105 |
+ let websocket = null; |
|
106 |
+ let recorder = null; |
|
107 |
+ let chunkDuration = 1000; |
|
108 |
+ let websocketUrl = "ws://localhost:8000/asr"; |
|
109 | 109 |
|
110 | 110 |
// Tracks whether the user voluntarily closed the WebSocket |
111 | 111 |
let userClosing = false; |
... | ... | @@ -137,46 +137,56 @@ |
137 | 137 |
statusText.textContent = "WebSocket URL updated. Ready to connect."; |
138 | 138 |
}); |
139 | 139 |
|
140 |
+ /** |
|
141 |
+ * Opens webSocket connection. |
|
142 |
+ * returns a Promise that resolves when the connection is open. |
|
143 |
+ * rejects if there was an error. |
|
144 |
+ */ |
|
140 | 145 |
function setupWebSocket() { |
141 |
- try { |
|
142 |
- websocket = new WebSocket(websocketUrl); |
|
143 |
- } catch (error) { |
|
144 |
- statusText.textContent = |
|
145 |
- "Invalid WebSocket URL. Please check the URL and try again."; |
|
146 |
- throw error; |
|
147 |
- } |
|
148 |
- |
|
149 |
- websocket.onopen = () => { |
|
150 |
- statusText.textContent = "Connected to server"; |
|
151 |
- }; |
|
152 |
- |
|
153 |
- websocket.onclose = (event) => { |
|
154 |
- if (userClosing) { |
|
155 |
- statusText.textContent = "WebSocket closed by user."; |
|
156 |
- } else { |
|
157 |
- statusText.textContent = "Disconnected from server (unexpected)."; |
|
146 |
+ return new Promise((resolve, reject) => { |
|
147 |
+ try { |
|
148 |
+ websocket = new WebSocket(websocketUrl); |
|
149 |
+ } catch (error) { |
|
150 |
+ statusText.textContent = |
|
151 |
+ "Invalid WebSocket URL. Please check the URL and try again."; |
|
152 |
+ reject(error); |
|
153 |
+ return; |
|
158 | 154 |
} |
159 |
- userClosing = false; |
|
160 |
- }; |
|
161 | 155 |
|
162 |
- websocket.onerror = () => { |
|
163 |
- statusText.textContent = "Error connecting to WebSocket"; |
|
164 |
- stopRecording(); |
|
165 |
- }; |
|
156 |
+ websocket.onopen = () => { |
|
157 |
+ statusText.textContent = "Connected to server"; |
|
158 |
+ resolve(); |
|
159 |
+ }; |
|
166 | 160 |
|
167 |
- websocket.onmessage = (event) => { |
|
168 |
- const data = JSON.parse(event.data); |
|
169 |
- const { transcription, buffer } = data; |
|
161 |
+ websocket.onclose = (event) => { |
|
162 |
+ // If we manually closed it, we say so |
|
163 |
+ if (userClosing) { |
|
164 |
+ statusText.textContent = "WebSocket closed by user."; |
|
165 |
+ } else { |
|
166 |
+ statusText.textContent = "Disconnected from the websocket server. If this is the first launch, the model may be downloading in the backend. Check the API logs for more information."; |
|
167 |
+ } |
|
168 |
+ userClosing = false; |
|
169 |
+ }; |
|
170 | 170 |
|
171 |
- // Update confirmed transcription |
|
172 |
- fullTranscription += transcription; |
|
171 |
+ websocket.onerror = () => { |
|
172 |
+ statusText.textContent = "Error connecting to WebSocket"; |
|
173 |
+ reject(new Error("Error connecting to WebSocket")); |
|
174 |
+ }; |
|
173 | 175 |
|
174 |
- // Update the transcription display |
|
175 |
- transcriptionsDiv.innerHTML = ` |
|
176 |
- <span class="transcription">${fullTranscription}</span> |
|
177 |
- <span class="buffer">${buffer}</span> |
|
178 |
- `; |
|
179 |
- }; |
|
176 |
+ websocket.onmessage = (event) => { |
|
177 |
+ const data = JSON.parse(event.data); |
|
178 |
+ const { transcription, buffer } = data; |
|
179 |
+ |
|
180 |
+ // Update confirmed transcription |
|
181 |
+ fullTranscription += transcription; |
|
182 |
+ |
|
183 |
+ // Update the transcription display |
|
184 |
+ transcriptionsDiv.innerHTML = ` |
|
185 |
+ <span class="transcription">${fullTranscription}</span> |
|
186 |
+ <span class="buffer">${buffer}</span> |
|
187 |
+ `; |
|
188 |
+ }; |
|
189 |
+ }); |
|
180 | 190 |
} |
181 | 191 |
|
182 | 192 |
async function startRecording() { |
... | ... | @@ -200,12 +210,18 @@ |
200 | 210 |
function stopRecording() { |
201 | 211 |
userClosing = true; |
202 | 212 |
|
203 |
- recorder?.stop(); |
|
204 |
- recorder = null; |
|
213 |
+ // Stop the recorder if it exists |
|
214 |
+ if (recorder) { |
|
215 |
+ recorder.stop(); |
|
216 |
+ recorder = null; |
|
217 |
+ } |
|
205 | 218 |
isRecording = false; |
206 | 219 |
|
207 |
- websocket?.close(); |
|
208 |
- websocket = null; |
|
220 |
+ // Close the websocket if it exists |
|
221 |
+ if (websocket) { |
|
222 |
+ websocket.close(); |
|
223 |
+ websocket = null; |
|
224 |
+ } |
|
209 | 225 |
|
210 | 226 |
updateUI(); |
211 | 227 |
} |
... | ... | @@ -216,12 +232,12 @@ |
216 | 232 |
transcriptionsDiv.innerHTML = ""; |
217 | 233 |
|
218 | 234 |
try { |
219 |
- setupWebSocket(); |
|
235 |
+ await setupWebSocket(); |
|
236 |
+ await startRecording(); |
|
220 | 237 |
} catch (err) { |
221 |
- return; |
|
238 |
+ statusText.textContent = |
|
239 |
+ "Could not connect to WebSocket or access mic. Recording aborted."; |
|
222 | 240 |
} |
223 |
- |
|
224 |
- await startRecording(); |
|
225 | 241 |
} else { |
226 | 242 |
stopRecording(); |
227 | 243 |
} |
Add a comment
Delete comment
Once you delete this comment, you won't be able to recover it. Are you sure you want to delete this comment?