openfree commited on
Commit
77b322a
·
verified ·
1 Parent(s): a2e646d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +137 -27
app.py CHANGED
@@ -1,6 +1,7 @@
1
  import gradio as gr
2
  import openai
3
  import os
 
4
  from dotenv import load_dotenv
5
 
6
  # 환경변수 로드
@@ -11,84 +12,187 @@ api_key = os.getenv("OPENAI_API_KEY")
11
  if not api_key:
12
  print("⚠️ OPENAI_API_KEY를 .env 파일에 설정하세요!")
13
  print("예: OPENAI_API_KEY=sk-...")
 
 
14
 
15
- client = openai.OpenAI(api_key=api_key)
 
 
 
 
16
 
17
  def translate_audio(audio_file, source_lang, target_lang):
18
  """음성 파일을 번역하는 함수"""
 
 
19
  if not audio_file:
20
- return "오디오 파일을 업로드하거나 녹음하세요.", "", None
21
 
22
  if not api_key:
23
- return "API 키가 설정되지 않았습니다.", "", None
 
 
 
 
 
 
 
24
 
25
  try:
 
 
 
26
  # 1. Whisper로 음성을 텍스트로 변환
 
27
  with open(audio_file, "rb") as f:
28
  transcript = client.audio.transcriptions.create(
29
  model="whisper-1",
30
- file=f
 
31
  )
32
  original_text = transcript.text
 
 
 
 
 
33
 
34
  # 2. GPT-4로 번역
 
35
  response = client.chat.completions.create(
36
- model="gpt-4",
37
  messages=[
38
- {"role": "system", "content": f"Translate from {source_lang} to {target_lang}. Only provide the translation without any explanation."},
39
- {"role": "user", "content": original_text}
 
 
 
 
 
 
40
  ],
41
- temperature=0.3
 
42
  )
43
- translated_text = response.choices[0].message.content
 
44
 
45
  # 3. TTS로 번역된 텍스트를 음성으로 변환
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  tts_response = client.audio.speech.create(
47
  model="tts-1",
48
- voice="alloy",
49
- input=translated_text
50
  )
51
 
52
- # 음성 파일 저장
53
- output_file = "translated_audio.mp3"
54
- with open(output_file, "wb") as f:
55
- f.write(tts_response.content)
56
 
 
57
  return original_text, translated_text, output_file
58
 
 
 
 
 
 
 
 
 
 
 
 
 
59
  except Exception as e:
60
- return f"오류 발생: {str(e)}", "", None
 
 
 
 
61
 
62
  # Gradio 인터페이스
63
- with gr.Blocks(title="음성 번역기") as app:
64
- gr.Markdown("# 🎙️ AI 음성 번역기")
65
- gr.Markdown("음성을 녹음하거나 업로드하면 자동으로 번역합니다.")
 
 
 
 
 
 
 
 
 
 
 
 
66
 
67
  with gr.Row():
68
  source_lang = gr.Dropdown(
69
  ["Korean", "English", "Japanese", "Chinese", "Spanish", "French"],
70
  value="Korean",
71
- label="입력 언어"
 
72
  )
73
  target_lang = gr.Dropdown(
74
  ["Korean", "English", "Japanese", "Chinese", "Spanish", "French"],
75
  value="English",
76
- label="출력 언어"
 
77
  )
78
 
79
  audio_input = gr.Audio(
80
  sources=["microphone", "upload"],
81
  type="filepath",
82
- label="음성 입력 (녹음 또는 파일 업로드)"
 
83
  )
84
 
85
- translate_btn = gr.Button("번역하기", variant="primary")
86
 
87
  with gr.Row():
88
- original_text = gr.Textbox(label="원본 텍스트", lines=3)
89
- translated_text = gr.Textbox(label="번역된 텍스트", lines=3)
 
 
 
 
 
 
 
 
90
 
91
- audio_output = gr.Audio(label="번역된 음성", type="filepath")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
 
93
  translate_btn.click(
94
  translate_audio,
@@ -97,4 +201,10 @@ with gr.Blocks(title="음성 번역기") as app:
97
  )
98
 
99
  if __name__ == "__main__":
100
- app.launch(server_name="0.0.0.0", server_port=7860, share=True)
 
 
 
 
 
 
 
1
  import gradio as gr
2
  import openai
3
  import os
4
+ import tempfile
5
  from dotenv import load_dotenv
6
 
7
  # 환경변수 로드
 
12
  if not api_key:
13
  print("⚠️ OPENAI_API_KEY를 .env 파일에 설정하세요!")
14
  print("예: OPENAI_API_KEY=sk-...")
15
+ else:
16
+ print(f"✅ API Key 로드됨: {api_key[:10]}...")
17
 
18
+ try:
19
+ client = openai.OpenAI(api_key=api_key)
20
+ except Exception as e:
21
+ print(f"❌ OpenAI 클라이언트 초기화 실패: {e}")
22
+ client = None
23
 
24
  def translate_audio(audio_file, source_lang, target_lang):
25
  """음성 파일을 번역하는 함수"""
26
+
27
+ # 입력 검증
28
  if not audio_file:
29
+ return "⚠️ 오디오 파일을 업로드하거나 녹음하세요.", "", None
30
 
31
  if not api_key:
32
+ return "API 키가 설정되지 않았습니다. .env 파일을 확인하세요.", "", None
33
+
34
+ if not client:
35
+ return "❌ OpenAI 클라이언트가 초기화되지 않았습니다.", "", None
36
+
37
+ # 같은 언어로 번역하려는 경우
38
+ if source_lang == target_lang:
39
+ return "⚠️ 입력 언어와 출력 언어가 같습니다.", "", None
40
 
41
  try:
42
+ print(f"🎤 오디오 파일 처리 중: {audio_file}")
43
+ print(f"📊 파일 크기: {os.path.getsize(audio_file) / 1024 / 1024:.2f} MB")
44
+
45
  # 1. Whisper로 음성을 텍스트로 변환
46
+ print("1️⃣ 음성 인식 시작...")
47
  with open(audio_file, "rb") as f:
48
  transcript = client.audio.transcriptions.create(
49
  model="whisper-1",
50
+ file=f,
51
+ language=source_lang[:2].lower() if source_lang != "Chinese" else "zh"
52
  )
53
  original_text = transcript.text
54
+ print(f"✅ 음성 인식 완료: {original_text[:50]}...")
55
+
56
+ # 빈 텍스트 체크
57
+ if not original_text.strip():
58
+ return "⚠️ 음성이 인식되지 않았습니다. 다시 녹음해주세요.", "", None
59
 
60
  # 2. GPT-4로 번역
61
+ print("2️⃣ 번역 시작...")
62
  response = client.chat.completions.create(
63
+ model="gpt-3.5-turbo", # 더 빠르고 안정적
64
  messages=[
65
+ {
66
+ "role": "system",
67
+ "content": f"You are a professional translator. Translate the following {source_lang} text to {target_lang}. Only provide the translation without any explanation or additional text."
68
+ },
69
+ {
70
+ "role": "user",
71
+ "content": original_text
72
+ }
73
  ],
74
+ temperature=0.3,
75
+ max_tokens=2000
76
  )
77
+ translated_text = response.choices[0].message.content.strip()
78
+ print(f"✅ 번역 완료: {translated_text[:50]}...")
79
 
80
  # 3. TTS로 번역된 텍스트를 음성으로 변환
81
+ print("3️⃣ 음성 합성 시작...")
82
+
83
+ # 언어별 음성 선택
84
+ voice_map = {
85
+ "Korean": "nova",
86
+ "English": "alloy",
87
+ "Japanese": "nova",
88
+ "Chinese": "nova",
89
+ "Spanish": "nova",
90
+ "French": "nova"
91
+ }
92
+ voice = voice_map.get(target_lang, "alloy")
93
+
94
  tts_response = client.audio.speech.create(
95
  model="tts-1",
96
+ voice=voice,
97
+ input=translated_text[:4096] # TTS 길이 제한
98
  )
99
 
100
+ # 임시 파일로 저장
101
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".mp3") as tmp_file:
102
+ tmp_file.write(tts_response.content)
103
+ output_file = tmp_file.name
104
 
105
+ print("✅ 모든 처리 완료!")
106
  return original_text, translated_text, output_file
107
 
108
+ except openai.APIError as e:
109
+ error_msg = f"❌ OpenAI API 오류: {str(e)}"
110
+ print(error_msg)
111
+ return error_msg, "", None
112
+ except openai.AuthenticationError:
113
+ error_msg = "❌ API 키가 올바르지 않습니다. .env 파일을 확인하세요."
114
+ print(error_msg)
115
+ return error_msg, "", None
116
+ except openai.RateLimitError:
117
+ error_msg = "❌ API 사용 한도를 초���했습니다. 잠시 후 다시 시도하세요."
118
+ print(error_msg)
119
+ return error_msg, "", None
120
  except Exception as e:
121
+ error_msg = f" 예상치 못한 오류: {type(e).__name__}: {str(e)}"
122
+ print(error_msg)
123
+ import traceback
124
+ traceback.print_exc()
125
+ return error_msg, "", None
126
 
127
  # Gradio 인터페이스
128
+ with gr.Blocks(title="음성 번역기", theme=gr.themes.Soft()) as app:
129
+ gr.Markdown(
130
+ """
131
+ # 🎙️ AI 음성 번역기
132
+ 음성을 녹음하거나 업로드하면 자동으로 번역합니다.
133
+
134
+ **지원 형식**: MP3, WAV, M4A, WEBM (최대 25MB)
135
+ """
136
+ )
137
+
138
+ # API 키 상태 표시
139
+ if api_key:
140
+ gr.Markdown(f"✅ API 연결 상태: 정상 (키: {api_key[:10]}...)")
141
+ else:
142
+ gr.Markdown("❌ API 연결 상태: API 키를 설정하세요")
143
 
144
  with gr.Row():
145
  source_lang = gr.Dropdown(
146
  ["Korean", "English", "Japanese", "Chinese", "Spanish", "French"],
147
  value="Korean",
148
+ label="입력 언어",
149
+ info="음성의 언어를 선택하세요"
150
  )
151
  target_lang = gr.Dropdown(
152
  ["Korean", "English", "Japanese", "Chinese", "Spanish", "French"],
153
  value="English",
154
+ label="출력 언어",
155
+ info="번역할 언어를 선택하세요"
156
  )
157
 
158
  audio_input = gr.Audio(
159
  sources=["microphone", "upload"],
160
  type="filepath",
161
+ label="음성 입력 (녹음 또는 파일 업로드)",
162
+ info="마이크 버튼을 클릭하여 녹음하거나 파일을 드래그하세요"
163
  )
164
 
165
+ translate_btn = gr.Button("🔄 번역하기", variant="primary", size="lg")
166
 
167
  with gr.Row():
168
+ original_text = gr.Textbox(
169
+ label="📝 원본 텍스트",
170
+ lines=5,
171
+ placeholder="음성 인식 결과가 여기에 표시됩니다..."
172
+ )
173
+ translated_text = gr.Textbox(
174
+ label="🌐 번역된 텍스트",
175
+ lines=5,
176
+ placeholder="번역 결과가 여기에 표시됩니다..."
177
+ )
178
 
179
+ audio_output = gr.Audio(
180
+ label="🔊 번역된 음성",
181
+ type="filepath",
182
+ autoplay=True
183
+ )
184
+
185
+ # 예시
186
+ gr.Examples(
187
+ examples=[
188
+ ["Korean", "English"],
189
+ ["English", "Korean"],
190
+ ["Japanese", "English"],
191
+ ["Chinese", "Korean"]
192
+ ],
193
+ inputs=[source_lang, target_lang],
194
+ label="언어 조합 예시"
195
+ )
196
 
197
  translate_btn.click(
198
  translate_audio,
 
201
  )
202
 
203
  if __name__ == "__main__":
204
+ print("🚀 서버 시작 중...")
205
+ app.launch(
206
+ server_name="0.0.0.0",
207
+ server_port=7860,
208
+ share=False, # 로컬에서만 실행
209
+ debug=True # 디버그 모드 활성화
210
+ )