Mike W commited on
Commit
2e0855f
·
1 Parent(s): d0ae679

Fix: Initial runtime errors with integration

Browse files
Files changed (3) hide show
  1. README.md +1 -1
  2. index.html +10 -2
  3. server.py +18 -6
README.md CHANGED
@@ -86,7 +86,7 @@ You will need active accounts and API keys for the following services:
86
  GOOGLE_APPLICATION_CREDENTIALS="/path/to/your/google-credentials.json"
87
 
88
  # Your DeepL API Key
89
- DEPL_API_KEY="YOUR_DEEPL_API_KEY"
90
 
91
  # Your ElevenLabs API Key and Voice ID
92
  ELEVENLABS_API_KEY="YOUR_ELEVENLABS_API_KEY"
 
86
  GOOGLE_APPLICATION_CREDENTIALS="/path/to/your/google-credentials.json"
87
 
88
  # Your DeepL API Key
89
+ DEEPL_API_KEY="YOUR_DEEPL_API_KEY"
90
 
91
  # Your ElevenLabs API Key and Voice ID
92
  ELEVENLABS_API_KEY="YOUR_ELEVENLABS_API_KEY"
index.html CHANGED
@@ -32,11 +32,13 @@
32
  const connectWebSocket = () => {
33
  const proto = window.location.protocol === "https:" ? "wss:" : "ws:";
34
  const wsUri = `${proto}//${window.location.host}/ws`;
 
35
  status.textContent = `Status: Connecting to ${wsUri}...`;
36
  socket = new WebSocket(wsUri);
37
 
38
  socket.onopen = () => {
39
  status.textContent = 'Status: Connected. Ready to start.';
 
40
  startButton.disabled = false;
41
  };
42
 
@@ -62,13 +64,14 @@
62
  };
63
 
64
  socket.onclose = () => {
 
65
  status.textContent = 'Status: Disconnected. Please refresh the page.';
66
  startButton.disabled = false; // Allow user to try starting again
67
  stopButton.disabled = true;
68
  };
69
 
70
  socket.onerror = (error) => {
71
- console.error("WebSocket Error:", error);
72
  status.textContent = 'Status: Connection error. Check console for details.';
73
  };
74
  };
@@ -121,6 +124,7 @@
121
  };
122
 
123
  startButton.onclick = async () => {
 
124
  // AudioContext must be created or resumed by a user gesture.
125
  if (!audioContext) {
126
  audioContext = new (window.AudioContext || window.webkitAudioContext)({ sampleRate: 16000 });
@@ -128,6 +132,7 @@
128
  await audioContext.resume();
129
  }
130
 
 
131
  navigator.mediaDevices.getUserMedia({ audio: { sampleRate: 16000, channelCount: 1 } })
132
  .then(stream => {
133
  mediaRecorder = new MediaRecorder(stream, { mimeType: 'audio/webm; codecs=opus' });
@@ -137,18 +142,20 @@
137
  }
138
  };
139
  mediaRecorder.start(250); // Send data every 250ms
 
140
 
141
  startButton.disabled = true;
142
  stopButton.disabled = false;
143
  status.textContent = 'Status: Translating...';
144
  })
145
  .catch(err => {
146
- console.error('Error getting user media:', err);
147
  status.textContent = 'Error: Could not access microphone.';
148
  });
149
  };
150
 
151
  stopButton.onclick = () => {
 
152
  if (mediaRecorder) {
153
  mediaRecorder.stop();
154
  }
@@ -160,6 +167,7 @@
160
  };
161
 
162
  window.onload = () => {
 
163
  startButton.disabled = true;
164
  stopButton.disabled = true;
165
  connectWebSocket(); // Connect automatically on page load
 
32
  const connectWebSocket = () => {
33
  const proto = window.location.protocol === "https:" ? "wss:" : "ws:";
34
  const wsUri = `${proto}//${window.location.host}/ws`;
35
+ console.log("[CLIENT] Attempting to connect to WebSocket:", wsUri);
36
  status.textContent = `Status: Connecting to ${wsUri}...`;
37
  socket = new WebSocket(wsUri);
38
 
39
  socket.onopen = () => {
40
  status.textContent = 'Status: Connected. Ready to start.';
41
+ console.log("[CLIENT] WebSocket connection opened. Enabling start button.");
42
  startButton.disabled = false;
43
  };
44
 
 
64
  };
65
 
66
  socket.onclose = () => {
67
+ console.log("[CLIENT] WebSocket connection closed.");
68
  status.textContent = 'Status: Disconnected. Please refresh the page.';
69
  startButton.disabled = false; // Allow user to try starting again
70
  stopButton.disabled = true;
71
  };
72
 
73
  socket.onerror = (error) => {
74
+ console.error("[CLIENT] WebSocket Error:", error);
75
  status.textContent = 'Status: Connection error. Check console for details.';
76
  };
77
  };
 
124
  };
125
 
126
  startButton.onclick = async () => {
127
+ console.log("[CLIENT] Start button clicked.");
128
  // AudioContext must be created or resumed by a user gesture.
129
  if (!audioContext) {
130
  audioContext = new (window.AudioContext || window.webkitAudioContext)({ sampleRate: 16000 });
 
132
  await audioContext.resume();
133
  }
134
 
135
+ console.log("[CLIENT] Requesting microphone access...");
136
  navigator.mediaDevices.getUserMedia({ audio: { sampleRate: 16000, channelCount: 1 } })
137
  .then(stream => {
138
  mediaRecorder = new MediaRecorder(stream, { mimeType: 'audio/webm; codecs=opus' });
 
142
  }
143
  };
144
  mediaRecorder.start(250); // Send data every 250ms
145
+ console.log("[CLIENT] Microphone access granted. MediaRecorder started.");
146
 
147
  startButton.disabled = true;
148
  stopButton.disabled = false;
149
  status.textContent = 'Status: Translating...';
150
  })
151
  .catch(err => {
152
+ console.error('[CLIENT] Error getting user media:', err);
153
  status.textContent = 'Error: Could not access microphone.';
154
  });
155
  };
156
 
157
  stopButton.onclick = () => {
158
+ console.log("[CLIENT] Stop button clicked.");
159
  if (mediaRecorder) {
160
  mediaRecorder.stop();
161
  }
 
167
  };
168
 
169
  window.onload = () => {
170
+ console.log("[CLIENT] Page loaded. Initializing...");
171
  startButton.disabled = true;
172
  stopButton.disabled = true;
173
  connectWebSocket(); // Connect automatically on page load
server.py CHANGED
@@ -18,8 +18,16 @@ deepl_key = os.getenv("DEEPL_API_KEY")
18
  eleven_key = os.getenv("ELEVENLABS_API_KEY")
19
  voice_id = os.getenv("ELEVENLABS_VOICE_ID")
20
 
 
 
 
 
 
 
 
 
21
  if not all([google_creds, deepl_key, eleven_key, voice_id]):
22
- raise ValueError("Missing one or more required API keys in .env file.")
23
 
24
  translator = VoiceTranslator(deepl_key, eleven_key, voice_id)
25
 
@@ -69,15 +77,18 @@ async def handle_audio_input(websocket: WebSocket, input_queue: asyncio.Queue):
69
 
70
  @app.websocket("/ws") # This was correct, the error was in the old HTML. No change needed here, but confirming it's /ws.
71
  async def websocket_endpoint(websocket: WebSocket):
 
72
  await websocket.accept()
73
- print("WebSocket connection accepted.")
74
 
75
  output_sender_task = None
76
  input_handler_task = None
77
 
78
  try:
79
  # Start translation and audio processing tasks
 
80
  translator.start_translation()
 
81
  output_sender_task = asyncio.create_task(
82
  audio_output_sender(websocket, translator.output_queue)
83
  )
@@ -85,18 +96,19 @@ async def websocket_endpoint(websocket: WebSocket):
85
  handle_audio_input(websocket, translator.input_queue)
86
  )
87
 
 
88
  await asyncio.gather(input_handler_task, output_sender_task)
89
 
90
  except WebSocketDisconnect:
91
- print("Client disconnected.")
92
  except Exception as e:
93
- print(f"An error occurred: {e}")
94
  finally:
95
- print("Stopping translation and cleaning up...")
96
  if output_sender_task:
97
  output_sender_task.cancel()
98
  if input_handler_task:
99
  input_handler_task.cancel()
100
  translator.stop_translation()
101
  await websocket.close()
102
- print("WebSocket connection closed.")
 
18
  eleven_key = os.getenv("ELEVENLABS_API_KEY")
19
  voice_id = os.getenv("ELEVENLABS_VOICE_ID")
20
 
21
+ # --- Start Debug Prints ---
22
+ print("--- API Key Status ---")
23
+ print(f"GOOGLE_APPLICATION_CREDENTIALS loaded: {bool(google_creds)}")
24
+ print(f"DEEPL_API_KEY loaded: {bool(deepl_key)}")
25
+ print(f"ELEVENLABS_API_KEY loaded: {bool(eleven_key)}")
26
+ print(f"ELEVENLABS_VOICE_ID loaded: {bool(voice_id)}")
27
+ print("----------------------")
28
+
29
  if not all([google_creds, deepl_key, eleven_key, voice_id]):
30
+ raise ValueError("CRITICAL: Missing one or more required API keys. Please check your Hugging Face secrets.")
31
 
32
  translator = VoiceTranslator(deepl_key, eleven_key, voice_id)
33
 
 
77
 
78
  @app.websocket("/ws") # This was correct, the error was in the old HTML. No change needed here, but confirming it's /ws.
79
  async def websocket_endpoint(websocket: WebSocket):
80
+ print("[SERVER] WebSocket endpoint called. Awaiting connection...")
81
  await websocket.accept()
82
+ print("[SERVER] WebSocket connection accepted.")
83
 
84
  output_sender_task = None
85
  input_handler_task = None
86
 
87
  try:
88
  # Start translation and audio processing tasks
89
+ print("[SERVER] Calling translator.start_translation()...")
90
  translator.start_translation()
91
+ print("[SERVER] translator.start_translation() returned. Creating tasks...")
92
  output_sender_task = asyncio.create_task(
93
  audio_output_sender(websocket, translator.output_queue)
94
  )
 
96
  handle_audio_input(websocket, translator.input_queue)
97
  )
98
 
99
+ print("[SERVER] Awaiting asyncio.gather for I/O tasks...")
100
  await asyncio.gather(input_handler_task, output_sender_task)
101
 
102
  except WebSocketDisconnect:
103
+ print("[SERVER] Client disconnected via WebSocketDisconnect.")
104
  except Exception as e:
105
+ print(f"[SERVER] An error occurred in websocket_endpoint: {e}")
106
  finally:
107
+ print("[SERVER] Cleaning up tasks and stopping translation...")
108
  if output_sender_task:
109
  output_sender_task.cancel()
110
  if input_handler_task:
111
  input_handler_task.cancel()
112
  translator.stop_translation()
113
  await websocket.close()
114
+ print("[SERVER] WebSocket connection closed.")