datbkpro commited on
Commit
5e244c1
·
verified ·
1 Parent(s): d936d48

Update ui/tabs.py

Browse files
Files changed (1) hide show
  1. ui/tabs.py +77 -118
ui/tabs.py CHANGED
@@ -200,176 +200,135 @@ def create_audio_tab(audio_service: AudioService):
200
  outputs=[transcription_output, response_output, tts_audio_output, language_display] # UPDATED
201
  )
202
  def create_streaming_voice_tab(streaming_service: StreamingVoiceService):
203
- """Tạo tab streaming voice với VAD"""
204
 
205
  with gr.Blocks() as streaming_tab:
206
- gr.Markdown("## 🎤 Trò chuyện giọng nói thời gian thực với VAD")
207
- gr.Markdown("""
208
- ### 🎯 Chế độ VAD (Voice Activity Detection)
209
- - **Tự động phát hiện** khi bạn bắt đầu nói
210
- - **Không cần giữ nút** - hệ thống tự nhận diện
211
- - **Loại bỏ tiếng ồn** - chỉ xử lý giọng nói thật
212
- """)
213
 
214
  with gr.Row():
215
  with gr.Column(scale=1):
216
- # VAD Controls
217
  with gr.Row():
218
- start_vad_btn = gr.Button("🎙️ Bắt đầu VAD", variant="primary")
219
- stop_vad_btn = gr.Button("🛑 Dừng VAD", variant="secondary")
220
 
221
- # Microphone component (vẫn giữ cho manual mode)
 
 
 
 
 
 
 
 
 
 
222
  microphone = gr.Microphone(
223
- label="🎤 Hoặc nhấn để nói thủ công",
224
  type="numpy",
225
- streaming=True,
226
- show_download_button=False
227
  )
228
 
229
- # Clear conversation button
230
- clear_btn = gr.Button("🗑️ Xóa hội thoại", variant="secondary")
231
-
232
- # Status display
233
- status_display = gr.Textbox(
234
- label="Trạng thái",
235
- value="Chưa bắt đầu - nhấn 'Bắt đầu VAD'",
236
- interactive=False
237
- )
238
 
239
- # Conversation state
240
- state_display = gr.JSON(
241
  label="Thông tin hệ thống",
242
- value={}
 
 
243
  )
244
 
245
  with gr.Column(scale=2):
246
- # Real-time transcription
247
- realtime_transcription = gr.Textbox(
248
  label="📝 Bạn vừa nói",
249
  lines=2,
250
- interactive=False,
251
- placeholder="Văn bản được chuyển đổi sẽ xuất hiện ở đây..."
252
  )
253
 
254
- # AI Response
255
- ai_response = gr.Textbox(
256
  label="🤖 Phản hồi AI",
257
  lines=3,
258
- interactive=False,
259
- placeholder="Phản hồi của AI sẽ xuất hiện ở đây..."
260
  )
261
 
262
- # TTS Audio output
263
- tts_output = gr.Audio(
264
- label="🔊 Phản hồi bằng giọng nói",
265
  interactive=False,
266
  autoplay=True
267
  )
268
 
269
- # Biến state để lưu kết quả từ VAD
270
- vad_transcription = gr.State(value="")
271
- vad_response = gr.State(value="")
272
- vad_audio = gr.State(value=None)
273
- vad_status = gr.State(value="waiting")
274
 
275
  def start_vad():
276
- """Bắt đầu VAD listening"""
277
- def vad_callback(result):
278
- """Callback khi VAD phát hiện speech"""
279
- # Cập nhật state với kết quả mới
280
- vad_transcription.value = result.get('transcription', '')
281
- vad_response.value = result.get('response', '')
282
- vad_audio.value = result.get('tts_audio', None)
283
- vad_status.value = result.get('status', 'completed')
284
- print(f"VAD Callback: {result.get('transcription', '')}")
 
 
 
 
 
 
285
 
286
- success = streaming_service.start_listening(vad_callback)
287
- status = "✅ Đang lắng nghe với VAD..." if success else "❌ Lỗi khởi động VAD"
288
- state = streaming_service.get_conversation_state()
289
  return status, state
290
 
291
  def stop_vad():
292
- """Dừng VAD listening"""
293
  streaming_service.stop_listening()
294
- state = streaming_service.get_conversation_state()
295
- return "🛑 Đã dừng VAD", state
 
 
296
 
297
- def process_manual_audio(audio_data):
298
- """Xử lý audio manual (không dùng VAD)"""
299
  if audio_data is None:
300
- return " Không có âm thanh", "Vui lòng nói lại", None, "Đang chờ...", {}
301
 
302
  try:
303
  result = streaming_service.process_streaming_audio(audio_data)
304
- state = streaming_service.get_conversation_state()
305
- status = "✅ Đã xử lý manual audio"
306
- return result['transcription'], result['response'], result['tts_audio'], status, state
307
  except Exception as e:
308
- error_msg = f"Lỗi: {str(e)}"
309
- return error_msg, "Xin lỗi, có lỗi xảy ra", None, "❌ Lỗi", {}
310
 
311
- def clear_conversation():
312
  """Xóa hội thoại"""
313
  streaming_service.clear_conversation()
314
- state = streaming_service.get_conversation_state()
315
- # Reset các state
316
- vad_transcription.value = ""
317
- vad_response.value = ""
318
- vad_audio.value = None
319
- return "", "", None, "🗑️ Đã xóa hội thoại", state
320
-
321
- def get_vad_results():
322
- """Lấy kết quả từ VAD và cập nhật UI"""
323
- if vad_status.value == "completed":
324
- # Reset status sau khi lấy kết quả
325
- vad_status.value = "waiting"
326
- state = streaming_service.get_conversation_state()
327
- return (vad_transcription.value, vad_response.value, vad_audio.value,
328
- "✅ VAD đã xử lý", state)
329
- else:
330
- # Không có kết quả mới, trả về None để không cập nhật
331
- return gr.skip(), gr.skip(), gr.skip(), gr.skip(), gr.skip()
332
-
333
- def refresh_state():
334
- """Chỉ cập nhật state display"""
335
- state = streaming_service.get_conversation_state()
336
- return state
337
 
338
- # Event handlers chính
339
- start_vad_btn.click(
340
- start_vad,
341
- outputs=[status_display, state_display]
342
- )
 
 
 
343
 
344
- stop_vad_btn.click(
345
- stop_vad,
346
- outputs=[status_display, state_display]
347
- )
348
 
349
  microphone.stream(
350
- process_manual_audio,
351
  inputs=[microphone],
352
- outputs=[realtime_transcription, ai_response, tts_output, status_display, state_display]
353
  )
354
 
355
  clear_btn.click(
356
- clear_conversation,
357
- outputs=[realtime_transcription, ai_response, tts_output, status_display, state_display]
358
- )
359
-
360
- # Nút refresh để cập nhật kết quả VAD thủ công
361
- refresh_btn = gr.Button("🔄 Kiểm tra kết quả VAD", variant="secondary", visible=False)
362
-
363
- refresh_btn.click(
364
- get_vad_results,
365
- outputs=[realtime_transcription, ai_response, tts_output, status_display, state_display]
366
- )
367
-
368
- # Tự động cập nhật state display mỗi 2 giây
369
- streaming_tab.load(
370
- refresh_state,
371
- outputs=[state_display],
372
- every=2
373
  )
374
 
375
  return streaming_tab
 
200
  outputs=[transcription_output, response_output, tts_audio_output, language_display] # UPDATED
201
  )
202
  def create_streaming_voice_tab(streaming_service: StreamingVoiceService):
203
+ """Tạo tab streaming voice với VAD - Phiên bản cực kỳ đơn giản"""
204
 
205
  with gr.Blocks() as streaming_tab:
206
+ gr.Markdown("## 🎤 Trò chuyện giọng nói thời gian thực")
 
 
 
 
 
 
207
 
208
  with gr.Row():
209
  with gr.Column(scale=1):
210
+ # Controls
211
  with gr.Row():
212
+ start_btn = gr.Button("🎙️ Bắt đầu VAD", variant="primary")
213
+ stop_btn = gr.Button("🛑 Dừng VAD", variant="secondary")
214
 
215
+ gr.Markdown("### Chế độ tự động (VAD)")
216
+ gr.Markdown("Hệ thống tự động nhận diện khi bạn bắt đầu nói")
217
+
218
+ with gr.Row():
219
+ vad_status = gr.Textbox(
220
+ label="Trạng thái VAD",
221
+ value="Chưa bắt đầu",
222
+ interactive=False
223
+ )
224
+
225
+ gr.Markdown("### Chế độ thủ công")
226
  microphone = gr.Microphone(
227
+ label="🎤 Nhấn để nói thủ công",
228
  type="numpy",
229
+ streaming=True
 
230
  )
231
 
232
+ clear_btn = gr.Button("🗑️ Xóa hội thoại")
 
 
 
 
 
 
 
 
233
 
234
+ # State info
235
+ state_info = gr.Textbox(
236
  label="Thông tin hệ thống",
237
+ value="Khởi tạo...",
238
+ lines=3,
239
+ interactive=False
240
  )
241
 
242
  with gr.Column(scale=2):
243
+ transcription_box = gr.Textbox(
 
244
  label="📝 Bạn vừa nói",
245
  lines=2,
246
+ interactive=False
 
247
  )
248
 
249
+ response_box = gr.Textbox(
 
250
  label="🤖 Phản hồi AI",
251
  lines=3,
252
+ interactive=False
 
253
  )
254
 
255
+ audio_output = gr.Audio(
256
+ label="🔊 Giọng nói AI",
 
257
  interactive=False,
258
  autoplay=True
259
  )
260
 
261
+ # Biến đơn giản để track VAD
262
+ is_vad_active = gr.State(value=False)
263
+ last_vad_result = gr.State(value=None)
 
 
264
 
265
  def start_vad():
266
+ """Bắt đầu VAD"""
267
+ def callback(result):
268
+ last_vad_result.value = result
269
+ print(f"VAD: {result.get('transcription', '')}")
270
+
271
+ success = streaming_service.start_listening(callback)
272
+ if success:
273
+ is_vad_active.value = True
274
+ status = "VAD đang chạy - Hãy nói gì đó!"
275
+ state = f"VAD: Đang hoạt động\n"
276
+ state += f"Processing: {streaming_service.is_processing}\n"
277
+ state += f"History: {len(streaming_service.conversation_history)} messages"
278
+ else:
279
+ status = "❌ Không thể khởi động VAD"
280
+ state = "Lỗi khởi động"
281
 
 
 
 
282
  return status, state
283
 
284
  def stop_vad():
285
+ """Dừng VAD"""
286
  streaming_service.stop_listening()
287
+ is_vad_active.value = False
288
+ state = f"VAD: Đã dừng\n"
289
+ state += f"History: {len(streaming_service.conversation_history)} messages"
290
+ return "🛑 VAD đã dừng", state
291
 
292
+ def process_microphone(audio_data):
293
+ """Xử lý microphone input"""
294
  if audio_data is None:
295
+ return "Chưa có âm thanh", "Hãy nói gì đó...", None, "VAD: Đang chạy" if is_vad_active.value else "VAD: Dừng"
296
 
297
  try:
298
  result = streaming_service.process_streaming_audio(audio_data)
299
+ state = f"Manual mode\nHistory: {len(streaming_service.conversation_history)} messages"
300
+ return result['transcription'], result['response'], result['tts_audio'], state
 
301
  except Exception as e:
302
+ return f"Lỗi: {e}", "Xin lỗi, có lỗi xảy ra", None, "Lỗi xử lý"
 
303
 
304
+ def clear_chat():
305
  """Xóa hội thoại"""
306
  streaming_service.clear_conversation()
307
+ state = f"Đã xóa hội thoại\nHistory: 0 messages"
308
+ return "", "", None, state
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
309
 
310
+ def check_vad_auto():
311
+ """Tự động kiểm tra VAD results (nếu có)"""
312
+ if is_vad_active.value and last_vad_result.value:
313
+ result = last_vad_result.value
314
+ last_vad_result.value = None # Reset sau khi dùng
315
+ state = f"VAD: Đã xử lý\nHistory: {len(streaming_service.conversation_history)} messages"
316
+ return result['transcription'], result['response'], result['tts_audio'], state
317
+ return gr.skip(), gr.skip(), gr.skip(), gr.skip()
318
 
319
+ # Event handlers đơn giản
320
+ start_btn.click(start_vad, outputs=[vad_status, state_info])
321
+ stop_btn.click(stop_vad, outputs=[vad_status, state_info])
 
322
 
323
  microphone.stream(
324
+ process_microphone,
325
  inputs=[microphone],
326
+ outputs=[transcription_box, response_box, audio_output, state_info]
327
  )
328
 
329
  clear_btn.click(
330
+ clear_chat,
331
+ outputs=[transcription_box, response_box, audio_output, state_info]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
332
  )
333
 
334
  return streaming_tab