openfree commited on
Commit
707ae79
Β·
verified Β·
1 Parent(s): bf7c5d7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +32 -36
app.py CHANGED
@@ -21,27 +21,28 @@ 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:
@@ -52,22 +53,22 @@ def translate_audio(audio_file, source_lang, target_lang):
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
  ],
@@ -76,10 +77,10 @@ def translate_audio(audio_file, source_lang, target_lang):
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",
@@ -90,21 +91,21 @@ def translate_audio(audio_file, source_lang, target_lang):
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)
@@ -124,6 +125,7 @@ def translate_audio(audio_file, source_lang, target_lang):
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(
@@ -134,36 +136,33 @@ with gr.Blocks(title="μŒμ„± λ²ˆμ—­κΈ°", theme=gr.themes.Soft()) as app:
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="πŸ“ 원본 ν…μŠ€νŠΈ",
@@ -176,15 +175,12 @@ with gr.Blocks(title="μŒμ„± λ²ˆμ—­κΈ°", theme=gr.themes.Soft()) as app:
176
  placeholder="λ²ˆμ—­ κ²°κ³Όκ°€ 여기에 ν‘œμ‹œλ©λ‹ˆλ‹€..."
177
  )
178
 
179
- audio_input = gr.Audio(
180
- sources=["microphone", "upload"],
181
  type="filepath",
182
- label="μŒμ„± μž…λ ₯ (λ…ΉμŒ λ˜λŠ” 파일 μ—…λ‘œλ“œ)"
183
- # info νŒŒλΌλ―Έν„° 제거
184
  )
185
 
186
-
187
-
188
  # μ˜ˆμ‹œ
189
  gr.Examples(
190
  examples=[
@@ -196,7 +192,7 @@ with gr.Blocks(title="μŒμ„± λ²ˆμ—­κΈ°", theme=gr.themes.Soft()) as app:
196
  inputs=[source_lang, target_lang],
197
  label="μ–Έμ–΄ μ‘°ν•© μ˜ˆμ‹œ"
198
  )
199
-
200
  translate_btn.click(
201
  translate_audio,
202
  inputs=[audio_input, source_lang, target_lang],
@@ -210,4 +206,4 @@ if __name__ == "__main__":
210
  server_port=7860,
211
  share=False, # λ‘œμ»¬μ—μ„œλ§Œ μ‹€ν–‰
212
  debug=True # 디버그 λͺ¨λ“œ ν™œμ„±ν™”
213
- )
 
21
  print(f"❌ OpenAI ν΄λΌμ΄μ–ΈνŠΈ μ΄ˆκΈ°ν™” μ‹€νŒ¨: {e}")
22
  client = None
23
 
24
+
25
  def translate_audio(audio_file, source_lang, target_lang):
26
  """μŒμ„± νŒŒμΌμ„ λ²ˆμ—­ν•˜λŠ” ν•¨μˆ˜"""
27
+
28
  # μž…λ ₯ 검증
29
  if not audio_file:
30
  return "⚠️ μ˜€λ””μ˜€ νŒŒμΌμ„ μ—…λ‘œλ“œν•˜κ±°λ‚˜ λ…ΉμŒν•˜μ„Έμš”.", "", None
31
+
32
  if not api_key:
33
  return "❌ API ν‚€κ°€ μ„€μ •λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€. .env νŒŒμΌμ„ ν™•μΈν•˜μ„Έμš”.", "", None
34
+
35
  if not client:
36
  return "❌ OpenAI ν΄λΌμ΄μ–ΈνŠΈκ°€ μ΄ˆκΈ°ν™”λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€.", "", None
37
+
38
  # 같은 μ–Έμ–΄λ‘œ λ²ˆμ—­ν•˜λ €λŠ” 경우
39
  if source_lang == target_lang:
40
  return "⚠️ μž…λ ₯ 언어와 좜λ ₯ μ–Έμ–΄κ°€ κ°™μŠ΅λ‹ˆλ‹€.", "", None
41
+
42
  try:
43
  print(f"🎀 μ˜€λ””μ˜€ 파일 처리 쀑: {audio_file}")
44
  print(f"πŸ“Š 파일 크기: {os.path.getsize(audio_file) / 1024 / 1024:.2f} MB")
45
+
46
  # 1. Whisper둜 μŒμ„±μ„ ν…μŠ€νŠΈλ‘œ λ³€ν™˜
47
  print("1️⃣ μŒμ„± 인식 μ‹œμž‘...")
48
  with open(audio_file, "rb") as f:
 
53
  )
54
  original_text = transcript.text
55
  print(f"βœ… μŒμ„± 인식 μ™„λ£Œ: {original_text[:50]}...")
56
+
57
  # 빈 ν…μŠ€νŠΈ 체크
58
  if not original_text.strip():
59
  return "⚠️ μŒμ„±μ΄ μΈμ‹λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€. λ‹€μ‹œ λ…ΉμŒν•΄μ£Όμ„Έμš”.", "", None
60
+
61
  # 2. GPT-4둜 λ²ˆμ—­
62
  print("2️⃣ λ²ˆμ—­ μ‹œμž‘...")
63
  response = client.chat.completions.create(
64
  model="gpt-3.5-turbo", # 더 λΉ λ₯΄κ³  μ•ˆμ •μ 
65
  messages=[
66
  {
67
+ "role": "system",
68
  "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."
69
  },
70
  {
71
+ "role": "user",
72
  "content": original_text
73
  }
74
  ],
 
77
  )
78
  translated_text = response.choices[0].message.content.strip()
79
  print(f"βœ… λ²ˆμ—­ μ™„λ£Œ: {translated_text[:50]}...")
80
+
81
  # 3. TTS둜 λ²ˆμ—­λœ ν…μŠ€νŠΈλ₯Ό μŒμ„±μœΌλ‘œ λ³€ν™˜
82
  print("3️⃣ μŒμ„± ν•©μ„± μ‹œμž‘...")
83
+
84
  # 언어별 μŒμ„± 선택
85
  voice_map = {
86
  "Korean": "nova",
 
91
  "French": "nova"
92
  }
93
  voice = voice_map.get(target_lang, "alloy")
94
+
95
  tts_response = client.audio.speech.create(
96
  model="tts-1",
97
  voice=voice,
98
  input=translated_text[:4096] # TTS 길이 μ œν•œ
99
  )
100
+
101
  # μž„μ‹œ 파일둜 μ €μž₯
102
  with tempfile.NamedTemporaryFile(delete=False, suffix=".mp3") as tmp_file:
103
  tmp_file.write(tts_response.content)
104
  output_file = tmp_file.name
105
+
106
  print("βœ… λͺ¨λ“  처리 μ™„λ£Œ!")
107
  return original_text, translated_text, output_file
108
+
109
  except openai.APIError as e:
110
  error_msg = f"❌ OpenAI API 였λ₯˜: {str(e)}"
111
  print(error_msg)
 
125
  traceback.print_exc()
126
  return error_msg, "", None
127
 
128
+
129
  # Gradio μΈν„°νŽ˜μ΄μŠ€
130
  with gr.Blocks(title="μŒμ„± λ²ˆμ—­κΈ°", theme=gr.themes.Soft()) as app:
131
  gr.Markdown(
 
136
  **지원 ν˜•μ‹**: MP3, WAV, M4A, WEBM (μ΅œλŒ€ 25MB)
137
  """
138
  )
139
+
140
  # API ν‚€ μƒνƒœ ν‘œμ‹œ
141
  if api_key:
142
  gr.Markdown(f"βœ… API μ—°κ²° μƒνƒœ: 정상 (ν‚€: {api_key[:10]}...)")
143
  else:
144
  gr.Markdown("❌ API μ—°κ²° μƒνƒœ: API ν‚€λ₯Ό μ„€μ •ν•˜μ„Έμš”")
145
+
146
  with gr.Row():
147
  source_lang = gr.Dropdown(
148
  ["Korean", "English", "Japanese", "Chinese", "Spanish", "French"],
149
  value="Korean",
150
+ label="μž…λ ₯ μ–Έμ–΄"
 
151
  )
152
  target_lang = gr.Dropdown(
153
  ["Korean", "English", "Japanese", "Chinese", "Spanish", "French"],
154
  value="English",
155
+ label="좜λ ₯ μ–Έμ–΄"
 
156
  )
157
+
158
  audio_input = gr.Audio(
159
  sources=["microphone", "upload"],
160
  type="filepath",
161
+ label="μŒμ„± μž…λ ₯ (λ…ΉμŒ λ˜λŠ” 파일 μ—…οΏ½οΏ½οΏ½λ“œ)"
 
162
  )
163
+
164
+ translate_btn = gr.Button("πŸ”„ λ²ˆμ—­ν•˜κΈ°")
165
+
166
  with gr.Row():
167
  original_text = gr.Textbox(
168
  label="πŸ“ 원본 ν…μŠ€νŠΈ",
 
175
  placeholder="λ²ˆμ—­ κ²°κ³Όκ°€ 여기에 ν‘œμ‹œλ©λ‹ˆλ‹€..."
176
  )
177
 
178
+ audio_output = gr.Audio(
179
+ label="πŸ”Š λ²ˆμ—­λœ μŒμ„±",
180
  type="filepath",
181
+ autoplay=True
 
182
  )
183
 
 
 
184
  # μ˜ˆμ‹œ
185
  gr.Examples(
186
  examples=[
 
192
  inputs=[source_lang, target_lang],
193
  label="μ–Έμ–΄ μ‘°ν•© μ˜ˆμ‹œ"
194
  )
195
+
196
  translate_btn.click(
197
  translate_audio,
198
  inputs=[audio_input, source_lang, target_lang],
 
206
  server_port=7860,
207
  share=False, # λ‘œμ»¬μ—μ„œλ§Œ μ‹€ν–‰
208
  debug=True # 디버그 λͺ¨λ“œ ν™œμ„±ν™”
209
+ )