datbkpro commited on
Commit
4b51187
·
verified ·
1 Parent(s): a1302e7

Update services/streaming_voice_service.py

Browse files
Files changed (1) hide show
  1. services/streaming_voice_service.py +44 -18
services/streaming_voice_service.py CHANGED
@@ -181,11 +181,10 @@
181
  import io
182
  import numpy as np
183
  import soundfile as sf
184
- import threading
185
- import time
186
  import traceback
187
  from groq import Groq
188
- from typing import Optional, Callable
189
  from config.settings import settings
190
  from core.rag_system import EnhancedRAGSystem
191
  from core.tts_service import EnhancedTTSService
@@ -197,15 +196,11 @@ class StreamingVoiceService:
197
  self.rag_system = rag_system
198
  self.tts_service = tts_service
199
 
200
- # Streaming state
201
- self.is_listening = False
202
- self.callback_handler = None
203
-
204
  # Conversation context
205
  self.conversation_history = []
206
  self.current_transcription = ""
207
 
208
- def process_streaming_audio(self, audio_data: tuple) -> dict:
209
  """Xử lý audio streaming từ Gradio microphone component"""
210
  if not audio_data:
211
  return {
@@ -220,6 +215,14 @@ class StreamingVoiceService:
220
 
221
  print(f"🎯 Nhận audio: {len(audio_array)} samples, SR: {sample_rate}")
222
 
 
 
 
 
 
 
 
 
223
  # Chuyển đổi thành văn bản
224
  transcription = self._transcribe_audio(audio_array, sample_rate)
225
 
@@ -232,6 +235,9 @@ class StreamingVoiceService:
232
 
233
  print(f"📝 Đã chuyển đổi: {transcription}")
234
 
 
 
 
235
  # Tạo phản hồi AI
236
  response = self._generate_ai_response(transcription)
237
 
@@ -246,9 +252,10 @@ class StreamingVoiceService:
246
 
247
  except Exception as e:
248
  print(f"❌ Lỗi xử lý streaming audio: {e}")
 
249
  return {
250
  'transcription': f"❌ Lỗi: {str(e)}",
251
- 'response': "Xin lỗi, có lỗi xảy ra",
252
  'tts_audio': None
253
  }
254
 
@@ -259,14 +266,23 @@ class StreamingVoiceService:
259
  if audio_data.ndim > 1:
260
  audio_data = np.mean(audio_data, axis=1) # Chuyển sang mono
261
 
262
- # Normalize
263
- if np.max(np.abs(audio_data)) > 0:
264
- audio_data = audio_data / np.max(np.abs(audio_data))
 
 
 
 
 
 
 
 
265
 
266
  buffer = io.BytesIO()
267
  sf.write(buffer, audio_data, sample_rate, format='wav', subtype='PCM_16')
268
  buffer.seek(0)
269
 
 
270
  transcription = self.client.audio.transcriptions.create(
271
  model=settings.WHISPER_MODEL,
272
  file=("speech.wav", buffer.read(), "audio/wav"),
@@ -276,11 +292,14 @@ class StreamingVoiceService:
276
 
277
  # Xử lý response
278
  if hasattr(transcription, 'text'):
279
- return transcription.text.strip()
280
  elif isinstance(transcription, str):
281
- return transcription.strip()
282
  else:
283
- return str(transcription).strip()
 
 
 
284
 
285
  except Exception as e:
286
  print(f"❌ Lỗi transcription: {e}")
@@ -323,14 +342,19 @@ Thông tin tham khảo:
323
  return response
324
 
325
  except Exception as e:
326
- return f"Xin lỗi, tôi gặp lỗi: {str(e)}"
327
 
328
  def _text_to_speech(self, text: str) -> Optional[str]:
329
  """Chuyển văn bản thành giọng nói"""
330
  try:
 
 
 
331
  tts_bytes = self.tts_service.text_to_speech(text, 'vi')
332
  if tts_bytes:
333
- return self.tts_service.save_audio_to_file(tts_bytes)
 
 
334
  except Exception as e:
335
  print(f"❌ Lỗi TTS: {e}")
336
  return None
@@ -338,11 +362,13 @@ Thông tin tham khảo:
338
  def clear_conversation(self):
339
  """Xóa lịch sử hội thoại"""
340
  self.conversation_history = []
 
341
  print("🗑️ Đã xóa lịch sử hội thoại")
342
 
343
  def get_conversation_state(self) -> dict:
344
  """Lấy trạng thái hội thoại"""
345
  return {
346
  'history_length': len(self.conversation_history),
347
- 'current_transcription': self.current_transcription
 
348
  }
 
181
  import io
182
  import numpy as np
183
  import soundfile as sf
184
+ import time # THÊM IMPORT NÀY
 
185
  import traceback
186
  from groq import Groq
187
+ from typing import Optional, Dict, Any
188
  from config.settings import settings
189
  from core.rag_system import EnhancedRAGSystem
190
  from core.tts_service import EnhancedTTSService
 
196
  self.rag_system = rag_system
197
  self.tts_service = tts_service
198
 
 
 
 
 
199
  # Conversation context
200
  self.conversation_history = []
201
  self.current_transcription = ""
202
 
203
+ def process_streaming_audio(self, audio_data: tuple) -> Dict[str, Any]:
204
  """Xử lý audio streaming từ Gradio microphone component"""
205
  if not audio_data:
206
  return {
 
215
 
216
  print(f"🎯 Nhận audio: {len(audio_array)} samples, SR: {sample_rate}")
217
 
218
+ # Kiểm tra audio có dữ liệu không
219
+ if len(audio_array) == 0 or np.max(np.abs(audio_array)) < 0.01:
220
+ return {
221
+ 'transcription': "❌ Âm thanh quá yếu",
222
+ 'response': "Xin vui lòng nói to hơn và rõ hơn",
223
+ 'tts_audio': None
224
+ }
225
+
226
  # Chuyển đổi thành văn bản
227
  transcription = self._transcribe_audio(audio_array, sample_rate)
228
 
 
235
 
236
  print(f"📝 Đã chuyển đổi: {transcription}")
237
 
238
+ # Cập nhật transcription hiện tại
239
+ self.current_transcription = transcription
240
+
241
  # Tạo phản hồi AI
242
  response = self._generate_ai_response(transcription)
243
 
 
252
 
253
  except Exception as e:
254
  print(f"❌ Lỗi xử lý streaming audio: {e}")
255
+ print(f"Chi tiết lỗi: {traceback.format_exc()}")
256
  return {
257
  'transcription': f"❌ Lỗi: {str(e)}",
258
+ 'response': "Xin lỗi, có lỗi xảy ra trong quá trình xử lý",
259
  'tts_audio': None
260
  }
261
 
 
266
  if audio_data.ndim > 1:
267
  audio_data = np.mean(audio_data, axis=1) # Chuyển sang mono
268
 
269
+ # Normalize âm lượng
270
+ audio_max = np.max(np.abs(audio_data))
271
+ if audio_max > 0:
272
+ audio_data = audio_data / audio_max
273
+
274
+ # Giới hạn độ dài audio (tránh quá dài)
275
+ max_duration = 10 # giây
276
+ max_samples = sample_rate * max_duration
277
+ if len(audio_data) > max_samples:
278
+ audio_data = audio_data[:max_samples]
279
+ print(f"⚠️ Cắt audio xuống còn {max_duration} giây")
280
 
281
  buffer = io.BytesIO()
282
  sf.write(buffer, audio_data, sample_rate, format='wav', subtype='PCM_16')
283
  buffer.seek(0)
284
 
285
+ # Gọi API Whisper
286
  transcription = self.client.audio.transcriptions.create(
287
  model=settings.WHISPER_MODEL,
288
  file=("speech.wav", buffer.read(), "audio/wav"),
 
292
 
293
  # Xử lý response
294
  if hasattr(transcription, 'text'):
295
+ result = transcription.text.strip()
296
  elif isinstance(transcription, str):
297
+ result = transcription.strip()
298
  else:
299
+ result = str(transcription).strip()
300
+
301
+ print(f"✅ Transcription thành công: {result}")
302
+ return result
303
 
304
  except Exception as e:
305
  print(f"❌ Lỗi transcription: {e}")
 
342
  return response
343
 
344
  except Exception as e:
345
+ return f"Xin lỗi, tôi gặp lỗi khi tạo phản hồi: {str(e)}"
346
 
347
  def _text_to_speech(self, text: str) -> Optional[str]:
348
  """Chuyển văn bản thành giọng nói"""
349
  try:
350
+ if not text or text.startswith("❌") or text.startswith("Xin lỗi"):
351
+ return None
352
+
353
  tts_bytes = self.tts_service.text_to_speech(text, 'vi')
354
  if tts_bytes:
355
+ audio_path = self.tts_service.save_audio_to_file(tts_bytes)
356
+ print(f"✅ Đã tạo TTS: {audio_path}")
357
+ return audio_path
358
  except Exception as e:
359
  print(f"❌ Lỗi TTS: {e}")
360
  return None
 
362
  def clear_conversation(self):
363
  """Xóa lịch sử hội thoại"""
364
  self.conversation_history = []
365
+ self.current_transcription = ""
366
  print("🗑️ Đã xóa lịch sử hội thoại")
367
 
368
  def get_conversation_state(self) -> dict:
369
  """Lấy trạng thái hội thoại"""
370
  return {
371
  'history_length': len(self.conversation_history),
372
+ 'current_transcription': self.current_transcription,
373
+ 'last_update': time.strftime("%H:%M:%S")
374
  }