VoiceSementle / voice_app.py
SJLee-0525
[TEST] test45
ab1ab06
raw
history blame
4.27 kB
"""
Gradio Voice Recording App for Komentle
Records user voice and sends to FastAPI backend
"""
import gradio as gr
import requests
import uuid
from datetime import datetime
import os
# Backend API URL (ν™˜κ²½λ³€μˆ˜λ‘œ 관리 κ°€λŠ₯)
BACKEND_URL = os.getenv("BACKEND_URL")
def process_voice(audio):
"""
Process recorded voice and send to backend
Args:
audio: tuple (sample_rate, audio_data) or file path
Returns:
dict: Response from backend with scores
"""
if audio is None:
return {
"status": "error",
"message": "μŒμ„±μ΄ λ…ΉμŒλ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€."
}
try:
# Generate or retrieve session ID (μ‹€μ œλ‘œλŠ” μ„Έμ…˜ 관리 ν•„μš”)
session_id = str(uuid.uuid4())
today = datetime.now().strftime("%Y-%m-%d")
# Prepare request data
files = {
'audio': ('audio.wav', open(audio, 'rb'), 'audio/wav')
}
data = {
'date': today,
'session_id': session_id
}
# Send to backend
response = requests.post(
f"{BACKEND_URL}/api/analyze-voice",
files=files,
data=data,
timeout=30
)
if response.status_code == 200:
result = response.json()
return format_result(result)
else:
return {
"status": "error",
"message": f"λ°±μ—”λ“œ 였λ₯˜: {response.status_code}"
}
except Exception as e:
return {
"status": "error",
"message": f"였λ₯˜ λ°œμƒ: {str(e)}"
}
def format_result(result):
"""Format backend response for display"""
if result.get("status") == "error":
return f"❌ 였λ₯˜: {result.get('message')}"
category = result.get("category", "unknown")
pitch = result.get("pitch", 0.0)
rhythm = result.get("rhythm", 0.0)
energy = result.get("energy", 0.0)
pronunciation = result.get("pronunciation", 0.0)
transcript = result.get("transcript", 0.0) # λŒ€μ‚¬ 정확도 점수
overall = result.get("overall", 0.0)
advice = result.get("advice", "")
is_correct = result.get("is_correct", False) # μ •λ‹΅ μ—¬λΆ€
output = f"🎯 μΉ΄ν…Œκ³ λ¦¬: {category}\n\n"
# μ •λ‹΅ μ—¬λΆ€
if is_correct:
output += "πŸŽ‰ μ •λ‹΅μž…λ‹ˆλ‹€! μΆ•ν•˜ν•©λ‹ˆλ‹€!\n\n"
else:
output += "❌ 아직 정닡이 μ•„λ‹™λ‹ˆλ‹€. λ‹€μ‹œ λ„μ „ν•΄λ³΄μ„Έμš”!\n\n"
output += "πŸ“Š 뢄석 κ²°κ³Ό:\n"
output += f" - μŒλ†’μ΄ (Pitch): {pitch:.1f}/100\n"
output += f" - 리듬감 (Rhythm): {rhythm:.1f}/100\n"
output += f" - μ—λ„ˆμ§€ (Energy): {energy:.1f}/100\n"
output += f" - 발음 (Pronunciation): {pronunciation:.1f}/100\n"
output += f" - λŒ€μ‚¬ 정확도 (Transcript): {transcript:.1f}/100\n"
output += f"\n⭐ 총점 (Overall): {overall:.1f}/100\n"
# AI μ‘°μ–Έ
if advice:
output += f"\nπŸ’‘ AI μ‘°μ–Έ:\n{advice}\n"
return output
# Gradio Interface
with gr.Blocks(title="🎀 Komentle Voice Challenge") as demo:
gr.Markdown("# 🎀 Komentle Voice Challenge")
gr.Markdown("였늘의 문제λ₯Ό μŒμ„±μœΌλ‘œ λ„μ „ν•˜μ„Έμš”!")
gr.Markdown("### μ‚¬μš© 방법")
gr.Markdown("""
1. πŸŽ™οΈ 마이크 λ²„νŠΌμ„ ν΄λ¦­ν•˜μ—¬ λ…ΉμŒ μ‹œμž‘
2. 였늘의 문제λ₯Ό μŒμ„±μœΌλ‘œ λ§ν•˜κΈ°
3. λ…ΉμŒ μ™„λ£Œ ν›„ '뢄석 μ‹œμž‘' λ²„νŠΌ 클릭
4. AIκ°€ λΆ„μ„ν•œ 점수 확인
""")
with gr.Row():
with gr.Column():
audio_input = gr.Audio(
sources=["microphone"],
type="filepath",
label="πŸŽ™οΈ μŒμ„± λ…ΉμŒ",
format="wav"
)
submit_btn = gr.Button("뢄석 μ‹œμž‘", variant="primary", size="lg")
with gr.Column():
result_output = gr.Textbox(
label="πŸ“Š 뢄석 κ²°κ³Ό",
lines=10,
interactive=False
)
# Event handlers
submit_btn.click(
fn=process_voice,
inputs=audio_input,
outputs=result_output
)
if __name__ == "__main__":
demo.launch(
server_name="0.0.0.0",
server_port=7860,
share=False
)