ciyidogan commited on
Commit
93dcbd8
·
verified ·
1 Parent(s): baba9d7

Update stt_google.py

Browse files
Files changed (1) hide show
  1. stt_google.py +145 -129
stt_google.py CHANGED
@@ -110,116 +110,120 @@ class GoogleCloudSTT(STTInterface):
110
  log_error(f"❌ Error queuing result: {e}")
111
 
112
  def _run_stream(self):
113
- """Run the streaming recognition in a separate thread"""
114
- try:
115
- log_info("🎤 Google STT stream thread started")
116
-
117
- def request_generator():
118
- """Generate streaming requests"""
119
- chunk_count = 0
120
- start_time = datetime.now()
121
 
122
- while not self.stop_event.is_set():
123
- try:
124
- # 5 dakika sınırına yaklaşıyorsak stream'i sonlandır
125
- elapsed = (datetime.now() - start_time).total_seconds()
126
- if elapsed > 280: # 4 dakika 40 saniye - güvenli margin
127
- log_warning(f"⚠️ Approaching 5-minute limit ({elapsed:.1f}s), ending stream gracefully")
128
- break
129
-
130
- # Get audio chunk with timeout
131
- chunk = self.audio_queue.get(timeout=0.1)
132
- if chunk is None: # Poison pill
133
- log_info("📛 Poison pill received, stopping request generator")
134
- break
135
- chunk_count += 1
136
-
137
- # Sadece önemli milestone'larda logla
138
- if chunk_count == 1:
139
- log_info(f"📤 First chunk sent to Google STT, size: {len(chunk)} bytes")
140
- elif chunk_count % 100 == 0:
141
- log_info(f"📤 Sent {chunk_count} chunks to Google STT (elapsed: {elapsed:.1f}s)")
142
 
143
- yield speech.StreamingRecognizeRequest(audio_content=chunk)
144
- except queue.Empty:
145
- continue
146
- except Exception as e:
147
- log_error(f"❌ Error in request generator: {e}")
148
- break
149
-
150
- # Create streaming client
151
- requests = request_generator()
152
-
153
- log_info("🎤 Creating Google STT streaming client...")
154
-
155
- try:
156
- responses = self.client.streaming_recognize(self.streaming_config, requests)
157
- log_info("✅ Google STT streaming client created")
 
 
 
 
 
 
 
158
 
159
- # Process responses
160
- response_count = 0
161
- empty_response_count = 0
162
 
163
- for response in responses:
164
- response_count += 1
 
165
 
166
- if self.stop_event.is_set():
167
- log_info("🛑 Stop event detected, breaking response loop")
168
- break
169
 
170
- # Boş response'ları say ama loglama
171
- if not response.results:
172
- empty_response_count += 1
173
- if empty_response_count % 50 == 0:
174
- log_warning(f"⚠️ Received {empty_response_count} empty responses from Google STT")
175
- continue
176
 
177
- for result in response.results:
178
- if not result.alternatives:
179
- continue
180
-
181
- # İlk alternatifi al
182
- alternative = result.alternatives[0]
183
 
184
- # Sadece anlamlı text'leri işle
185
- if alternative.transcript.strip():
186
- # Create transcription result
187
- transcription = TranscriptionResult(
188
- text=alternative.transcript,
189
- is_final=result.is_final,
190
- confidence=alternative.confidence if hasattr(alternative, 'confidence') and alternative.confidence else 0.0,
191
- timestamp=datetime.now().timestamp()
192
- )
193
 
194
- # Put result in queue
195
- self._put_result(transcription)
 
 
 
 
196
 
197
- # SADECE final result'ları logla
198
- if result.is_final:
199
- log_info(f"🎯 GOOGLE STT FINAL: '{alternative.transcript}'")
 
 
 
 
 
 
 
 
 
 
 
 
 
200
 
201
- log_info(f"📊 Google STT stream ended. Total responses: {response_count}, Empty: {empty_response_count}")
202
 
203
- except Exception as e:
204
- error_msg = str(e)
205
-
206
- # Detaylı hata mesajları
207
- if "Exceeded maximum allowed stream duration" in error_msg:
208
- log_warning("⚠️ Stream duration limit exceeded (5 minutes). This is expected for long sessions.")
209
- # Bu bir error değil, normal davranış - result queue'ya error koymuyoruz
210
- elif "Bad language code" in error_msg:
211
- log_error(f" Invalid language code in STT config. Check locale settings.")
212
- elif "invalid_argument" in error_msg:
213
- log_error(f" Invalid STT configuration. Check encoding and sample rate.")
214
- elif "Deadline Exceeded" in error_msg:
215
- log_error(f" Google STT timeout - possibly network issue or slow connection")
216
- else:
217
- log_error(f"❌ Google STT stream error: {error_msg}")
 
218
 
219
- except Exception as e:
220
- log_error(f"❌ Fatal error in STT stream thread", error=str(e), traceback=traceback.format_exc())
221
- finally:
222
- log_info("🎤 Google STT stream thread ended")
 
 
 
223
 
224
  async def stream_audio(self, audio_chunk: bytes) -> AsyncIterator[TranscriptionResult]:
225
  """Stream audio chunk and get transcription results"""
@@ -246,39 +250,51 @@ class GoogleCloudSTT(STTInterface):
246
  raise
247
 
248
  async def stop_streaming(self) -> Optional[TranscriptionResult]:
249
- """Stop streaming and get final result"""
250
- if not self.is_streaming:
251
- return None
252
-
253
- try:
254
- log_info("🛑 Stopping Google STT streaming...")
255
-
256
- self.is_streaming = False
257
- self.stop_event.set()
258
-
259
- # Send poison pill to queue
260
- self.audio_queue.put(None)
261
-
262
- # Wait for thread to finish
263
- if self.stream_thread:
264
- self.stream_thread.join(timeout=5.0)
265
-
266
- # Clear queues
267
- while not self.audio_queue.empty():
268
- self.audio_queue.get_nowait()
269
 
270
- final_result = None
271
- while not self.responses_queue.empty():
272
- result = await self.responses_queue.get()
273
- if result.is_final:
274
- final_result = result
275
-
276
- log_info("✅ Google STT streaming stopped")
277
- return final_result
278
-
279
- except Exception as e:
280
- log_error(f"❌ Failed to stop Google STT streaming", error=str(e))
281
- return None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
282
 
283
  def supports_realtime(self) -> bool:
284
  """Google Cloud STT supports real-time streaming"""
 
110
  log_error(f"❌ Error queuing result: {e}")
111
 
112
  def _run_stream(self):
113
+ """Run the streaming recognition in a separate thread"""
114
+ try:
115
+ log_info("🎤 Google STT stream thread started")
 
 
 
 
 
116
 
117
+ def request_generator():
118
+ """Generate streaming requests"""
119
+ chunk_count = 0
120
+ start_time = datetime.now()
121
+
122
+ while not self.stop_event.is_set():
123
+ try:
124
+ # 5 dakika sınırına yaklaşıyorsak stream'i sonlandır
125
+ elapsed = (datetime.now() - start_time).total_seconds()
126
+ if elapsed > 280: # 4 dakika 40 saniye - güvenli margin
127
+ log_warning(f"⚠️ Approaching 5-minute limit ({elapsed:.1f}s), ending stream gracefully")
128
+ break
 
 
 
 
 
 
 
 
129
 
130
+ # Get audio chunk with timeout
131
+ chunk = self.audio_queue.get(timeout=0.1)
132
+ if chunk is None: # Poison pill
133
+ log_info("📛 Poison pill received, stopping request generator")
134
+ break
135
+ chunk_count += 1
136
+
137
+ # Sadece önemli milestone'larda logla
138
+ if chunk_count == 1:
139
+ log_info(f"📤 First chunk sent to Google STT, size: {len(chunk)} bytes")
140
+ elif chunk_count % 100 == 0:
141
+ log_info(f"📤 Sent {chunk_count} chunks to Google STT (elapsed: {elapsed:.1f}s)")
142
+
143
+ yield speech.StreamingRecognizeRequest(audio_content=chunk)
144
+ except queue.Empty:
145
+ continue
146
+ except Exception as e:
147
+ log_error(f"❌ Error in request generator: {e}")
148
+ break
149
+
150
+ # Create streaming client
151
+ requests = request_generator()
152
 
153
+ log_info("🎤 Creating Google STT streaming client...")
 
 
154
 
155
+ try:
156
+ responses = self.client.streaming_recognize(self.streaming_config, requests)
157
+ log_info("✅ Google STT streaming client created")
158
 
159
+ # Process responses
160
+ response_count = 0
161
+ empty_response_count = 0
162
 
163
+ for response in responses:
164
+ response_count += 1
 
 
 
 
165
 
166
+ if self.stop_event.is_set():
167
+ log_info("🛑 Stop event detected, breaking response loop")
168
+ break
 
 
 
169
 
170
+ # Boş response'ları say ama loglama
171
+ if not response.results:
172
+ empty_response_count += 1
173
+ if empty_response_count % 50 == 0:
174
+ log_warning(f"⚠️ Received {empty_response_count} empty responses from Google STT")
175
+ continue
 
 
 
176
 
177
+ for result in response.results:
178
+ if not result.alternatives:
179
+ continue
180
+
181
+ # İlk alternatifi al
182
+ alternative = result.alternatives[0]
183
 
184
+ # Sadece anlamlı text'leri işle
185
+ if alternative.transcript.strip():
186
+ # Create transcription result
187
+ transcription = TranscriptionResult(
188
+ text=alternative.transcript,
189
+ is_final=result.is_final,
190
+ confidence=alternative.confidence if hasattr(alternative, 'confidence') and alternative.confidence else 0.0,
191
+ timestamp=datetime.now().timestamp()
192
+ )
193
+
194
+ # Put result in queue
195
+ self._put_result(transcription)
196
+
197
+ # SADECE final result'ları logla
198
+ if result.is_final:
199
+ log_info(f"🎯 GOOGLE STT FINAL: '{alternative.transcript}'")
200
 
201
+ log_info(f"📊 Google STT stream ended. Total responses: {response_count}, Empty: {empty_response_count}")
202
 
203
+ except Exception as e:
204
+ error_msg = str(e)
205
+
206
+ # Detaylı hata mesajları
207
+ if "Exceeded maximum allowed stream duration" in error_msg:
208
+ log_warning("⚠️ Stream duration limit exceeded (5 minutes). This is expected for long sessions.")
209
+ elif "Bad language code" in error_msg:
210
+ log_error(f" Invalid language code in STT config. Check locale settings.")
211
+ elif "invalid_argument" in error_msg:
212
+ log_error(f" Invalid STT configuration. Check encoding and sample rate.")
213
+ elif "Deadline Exceeded" in error_msg:
214
+ log_error(f" Google STT timeout - possibly network issue or slow connection")
215
+ elif "503" in error_msg or "Service Unavailable" in error_msg:
216
+ log_error(f"❌ Google STT service temporarily unavailable. Will retry...")
217
+ else:
218
+ log_error(f"❌ Google STT stream error: {error_msg}")
219
 
220
+ except Exception as e:
221
+ import traceback
222
+ log_error(f"❌ Fatal error in STT stream thread", error=str(e), traceback=traceback.format_exc())
223
+ finally:
224
+ log_info("🎤 Google STT stream thread ended")
225
+ # Thread bittiğinde streaming flag'ini kapat
226
+ self.is_streaming = False
227
 
228
  async def stream_audio(self, audio_chunk: bytes) -> AsyncIterator[TranscriptionResult]:
229
  """Stream audio chunk and get transcription results"""
 
250
  raise
251
 
252
  async def stop_streaming(self) -> Optional[TranscriptionResult]:
253
+ """Stop streaming and get final result"""
254
+ if not self.is_streaming:
255
+ return None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
256
 
257
+ try:
258
+ log_info("🛑 Stopping Google STT streaming...")
259
+
260
+ self.is_streaming = False
261
+ self.stop_event.set()
262
+
263
+ # Send poison pill to queue
264
+ self.audio_queue.put(None)
265
+
266
+ # Wait for thread to finish with longer timeout
267
+ if self.stream_thread and self.stream_thread.is_alive():
268
+ self.stream_thread.join(timeout=10.0)
269
+ if self.stream_thread.is_alive():
270
+ log_warning("⚠️ STT thread did not stop gracefully")
271
+
272
+ # Clear queues
273
+ while not self.audio_queue.empty():
274
+ try:
275
+ self.audio_queue.get_nowait()
276
+ except:
277
+ pass
278
+
279
+ final_result = None
280
+ while not self.responses_queue.empty():
281
+ try:
282
+ result = self.responses_queue.get_nowait()
283
+ if result.is_final:
284
+ final_result = result
285
+ except:
286
+ pass
287
+
288
+ # Reset thread reference
289
+ self.stream_thread = None
290
+
291
+ log_info("✅ Google STT streaming stopped")
292
+ return final_result
293
+
294
+ except Exception as e:
295
+ log_error(f"❌ Failed to stop Google STT streaming", error=str(e))
296
+ self.stream_thread = None
297
+ return None
298
 
299
  def supports_realtime(self) -> bool:
300
  """Google Cloud STT supports real-time streaming"""