Update ui/tabs.py
Browse files- ui/tabs.py +28 -42
ui/tabs.py
CHANGED
|
@@ -199,11 +199,11 @@ def create_audio_tab(audio_service: AudioService):
|
|
| 199 |
inputs=audio_input,
|
| 200 |
outputs=[transcription_output, response_output, tts_audio_output, language_display] # UPDATED
|
| 201 |
)
|
| 202 |
-
def create_streaming_voice_tab(streaming_service:
|
| 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")
|
| 207 |
|
| 208 |
with gr.Row():
|
| 209 |
with gr.Column(scale=1):
|
|
@@ -228,6 +228,7 @@ def create_streaming_voice_tab(streaming_service: StreamingVoiceService):
|
|
| 228 |
type="numpy",
|
| 229 |
streaming=True
|
| 230 |
)
|
|
|
|
| 231 |
with gr.Accordion("📊 Performance Metrics", open=False):
|
| 232 |
latency_display = gr.JSON(
|
| 233 |
label="Latency Statistics",
|
|
@@ -264,36 +265,30 @@ def create_streaming_voice_tab(streaming_service: StreamingVoiceService):
|
|
| 264 |
autoplay=True
|
| 265 |
)
|
| 266 |
|
| 267 |
-
#
|
| 268 |
is_vad_active = gr.State(value=False)
|
| 269 |
-
last_vad_result = gr.State(value=None)
|
| 270 |
|
| 271 |
def start_vad():
|
| 272 |
"""Bắt đầu VAD"""
|
| 273 |
-
|
| 274 |
-
last_vad_result.value = result
|
| 275 |
-
print(f"VAD: {result.get('transcription', '')}")
|
| 276 |
-
|
| 277 |
-
success = streaming_service.start_listening(callback)
|
| 278 |
if success:
|
| 279 |
is_vad_active.value = True
|
| 280 |
status = "✅ VAD đang chạy - Hãy nói gì đó!"
|
| 281 |
-
|
| 282 |
-
|
| 283 |
-
state += f"History: {len(streaming_service.conversation_history)} messages"
|
| 284 |
else:
|
| 285 |
status = "❌ Không thể khởi động VAD"
|
| 286 |
-
|
| 287 |
|
| 288 |
-
return status,
|
| 289 |
|
| 290 |
def stop_vad():
|
| 291 |
"""Dừng VAD"""
|
| 292 |
streaming_service.stop_listening()
|
| 293 |
is_vad_active.value = False
|
| 294 |
-
|
| 295 |
-
|
| 296 |
-
return "🛑 VAD đã dừng",
|
| 297 |
|
| 298 |
def process_microphone(audio_data):
|
| 299 |
"""Xử lý microphone input"""
|
|
@@ -302,47 +297,39 @@ def create_streaming_voice_tab(streaming_service: StreamingVoiceService):
|
|
| 302 |
|
| 303 |
try:
|
| 304 |
result = streaming_service.process_streaming_audio(audio_data)
|
| 305 |
-
|
| 306 |
-
|
|
|
|
| 307 |
except Exception as e:
|
| 308 |
return f"Lỗi: {e}", "Xin lỗi, có lỗi xảy ra", None, "Lỗi xử lý"
|
| 309 |
|
| 310 |
def clear_chat():
|
| 311 |
"""Xóa hội thoại"""
|
| 312 |
streaming_service.clear_conversation()
|
| 313 |
-
|
| 314 |
-
|
|
|
|
| 315 |
|
| 316 |
-
def check_vad_auto():
|
| 317 |
-
"""Tự động kiểm tra VAD results (nếu có)"""
|
| 318 |
-
if is_vad_active.value and last_vad_result.value:
|
| 319 |
-
result = last_vad_result.value
|
| 320 |
-
last_vad_result.value = None # Reset sau khi dùng
|
| 321 |
-
state = f"VAD: Đã xử lý\nHistory: {len(streaming_service.conversation_history)} messages"
|
| 322 |
-
return result['transcription'], result['response'], result['tts_audio'], state
|
| 323 |
-
return gr.skip(), gr.skip(), gr.skip(), gr.skip()
|
| 324 |
def refresh_latency():
|
| 325 |
"""Làm mới latency metrics"""
|
| 326 |
stats = streaming_service.get_latency_stats()
|
| 327 |
return stats
|
| 328 |
|
| 329 |
def update_state_info():
|
| 330 |
-
"""Cập nhật thông tin trạng thái
|
| 331 |
state = streaming_service.get_conversation_state()
|
| 332 |
|
| 333 |
-
# Format latency info
|
| 334 |
-
latency_info = state.get('latency_stats', {})
|
| 335 |
formatted_state = f"VAD: {'Đang chạy' if state['is_listening'] else 'Dừng'}\n"
|
| 336 |
-
formatted_state += f"Processing: {state['is_processing']}\n"
|
| 337 |
-
formatted_state += f"History: {state['history_length']} messages\n"
|
| 338 |
formatted_state += f"Queue: {state['queue_size']}\n"
|
|
|
|
|
|
|
|
|
|
| 339 |
|
| 340 |
-
|
| 341 |
-
total_avg = latency_info['total']['recent_avg']
|
| 342 |
-
formatted_state += f"Avg Latency: {total_avg:.2f}s"
|
| 343 |
|
| 344 |
return formatted_state, latency_info
|
| 345 |
-
|
|
|
|
| 346 |
start_btn.click(start_vad, outputs=[vad_status, state_info])
|
| 347 |
stop_btn.click(stop_vad, outputs=[vad_status, state_info])
|
| 348 |
|
|
@@ -357,14 +344,13 @@ def create_streaming_voice_tab(streaming_service: StreamingVoiceService):
|
|
| 357 |
outputs=[transcription_box, response_box, audio_output, state_info]
|
| 358 |
)
|
| 359 |
|
| 360 |
-
# Thêm event cho refresh latency
|
| 361 |
refresh_latency_btn.click(
|
| 362 |
refresh_latency,
|
| 363 |
outputs=[latency_display]
|
| 364 |
)
|
| 365 |
|
| 366 |
-
# Tự động cập nhật
|
| 367 |
-
gr.Timer(
|
| 368 |
fn=update_state_info,
|
| 369 |
outputs=[state_info, latency_display]
|
| 370 |
)
|
|
|
|
| 199 |
inputs=audio_input,
|
| 200 |
outputs=[transcription_output, response_output, tts_audio_output, language_display] # UPDATED
|
| 201 |
)
|
| 202 |
+
def create_streaming_voice_tab(streaming_service: OptimizedStreamingVoiceService):
|
| 203 |
+
"""Tạo tab streaming voice với VAD optimized"""
|
| 204 |
|
| 205 |
with gr.Blocks() as streaming_tab:
|
| 206 |
+
gr.Markdown("## 🎤 Trò chuyện giọng nói thời gian thực - Tối ưu hóa")
|
| 207 |
|
| 208 |
with gr.Row():
|
| 209 |
with gr.Column(scale=1):
|
|
|
|
| 228 |
type="numpy",
|
| 229 |
streaming=True
|
| 230 |
)
|
| 231 |
+
|
| 232 |
with gr.Accordion("📊 Performance Metrics", open=False):
|
| 233 |
latency_display = gr.JSON(
|
| 234 |
label="Latency Statistics",
|
|
|
|
| 265 |
autoplay=True
|
| 266 |
)
|
| 267 |
|
| 268 |
+
# State variables
|
| 269 |
is_vad_active = gr.State(value=False)
|
|
|
|
| 270 |
|
| 271 |
def start_vad():
|
| 272 |
"""Bắt đầu VAD"""
|
| 273 |
+
success = streaming_service.start_listening(lambda result: None)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 274 |
if success:
|
| 275 |
is_vad_active.value = True
|
| 276 |
status = "✅ VAD đang chạy - Hãy nói gì đó!"
|
| 277 |
+
state_info = streaming_service.get_conversation_state()
|
| 278 |
+
state_text = f"VAD: Đang hoạt động\nQueue: {state_info['queue_size']}\nThreads: {state_info['worker_threads']}"
|
|
|
|
| 279 |
else:
|
| 280 |
status = "❌ Không thể khởi động VAD"
|
| 281 |
+
state_text = "Lỗi khởi động"
|
| 282 |
|
| 283 |
+
return status, state_text
|
| 284 |
|
| 285 |
def stop_vad():
|
| 286 |
"""Dừng VAD"""
|
| 287 |
streaming_service.stop_listening()
|
| 288 |
is_vad_active.value = False
|
| 289 |
+
state_info = streaming_service.get_conversation_state()
|
| 290 |
+
state_text = f"VAD: Đã dừng\nHistory: {state_info['history_length']} messages"
|
| 291 |
+
return "🛑 VAD đã dừng", state_text
|
| 292 |
|
| 293 |
def process_microphone(audio_data):
|
| 294 |
"""Xử lý microphone input"""
|
|
|
|
| 297 |
|
| 298 |
try:
|
| 299 |
result = streaming_service.process_streaming_audio(audio_data)
|
| 300 |
+
state_info = streaming_service.get_conversation_state()
|
| 301 |
+
state_text = f"Manual mode\nHistory: {state_info['history_length']} messages"
|
| 302 |
+
return result['transcription'], result['response'], result['tts_audio'], state_text
|
| 303 |
except Exception as e:
|
| 304 |
return f"Lỗi: {e}", "Xin lỗi, có lỗi xảy ra", None, "Lỗi xử lý"
|
| 305 |
|
| 306 |
def clear_chat():
|
| 307 |
"""Xóa hội thoại"""
|
| 308 |
streaming_service.clear_conversation()
|
| 309 |
+
state_info = streaming_service.get_conversation_state()
|
| 310 |
+
state_text = f"Đã xóa hội thoại\nHistory: {state_info['history_length']} messages"
|
| 311 |
+
return "", "", None, state_text
|
| 312 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 313 |
def refresh_latency():
|
| 314 |
"""Làm mới latency metrics"""
|
| 315 |
stats = streaming_service.get_latency_stats()
|
| 316 |
return stats
|
| 317 |
|
| 318 |
def update_state_info():
|
| 319 |
+
"""Cập nhật thông tin trạng thái"""
|
| 320 |
state = streaming_service.get_conversation_state()
|
| 321 |
|
|
|
|
|
|
|
| 322 |
formatted_state = f"VAD: {'Đang chạy' if state['is_listening'] else 'Dừng'}\n"
|
|
|
|
|
|
|
| 323 |
formatted_state += f"Queue: {state['queue_size']}\n"
|
| 324 |
+
formatted_state += f"History: {state['history_length']} messages\n"
|
| 325 |
+
formatted_state += f"Threads: {state['worker_threads']}\n"
|
| 326 |
+
formatted_state += f"Last: {state['last_update']}"
|
| 327 |
|
| 328 |
+
latency_info = streaming_service.get_latency_stats()
|
|
|
|
|
|
|
| 329 |
|
| 330 |
return formatted_state, latency_info
|
| 331 |
+
|
| 332 |
+
# Event handlers
|
| 333 |
start_btn.click(start_vad, outputs=[vad_status, state_info])
|
| 334 |
stop_btn.click(stop_vad, outputs=[vad_status, state_info])
|
| 335 |
|
|
|
|
| 344 |
outputs=[transcription_box, response_box, audio_output, state_info]
|
| 345 |
)
|
| 346 |
|
|
|
|
| 347 |
refresh_latency_btn.click(
|
| 348 |
refresh_latency,
|
| 349 |
outputs=[latency_display]
|
| 350 |
)
|
| 351 |
|
| 352 |
+
# Tự động cập nhật mỗi 3 giây
|
| 353 |
+
gr.Timer(3.0).tick(
|
| 354 |
fn=update_state_info,
|
| 355 |
outputs=[state_info, latency_display]
|
| 356 |
)
|