""" 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 )