benjamin5607 commited on
Commit
b22fa4e
ยท
verified ยท
1 Parent(s): 6ef5c24

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +65 -40
app.py CHANGED
@@ -1,21 +1,26 @@
1
  import gradio as gr
2
- import requests
3
  import edge_tts
4
  import os
5
  import re
 
 
 
6
  import scipy.io.wavfile
 
7
  from transformers import pipeline
8
 
 
9
  GENAI_KEY = os.getenv("GEMINI_KEY")
10
 
11
- # ์Œ์•… ๋ชจ๋ธ ๋กœ๋“œ
12
  try:
13
  music_synthesiser = pipeline("text-to-audio", "facebook/musicgen-small")
14
  except Exception as e:
15
  print(f"Music Model Load Error: {e}")
16
  music_synthesiser = None
17
 
18
- # 8์ธ ๋ฉค๋ฒ„ ๋ฐ์ดํ„ฐ (์ ˆ๋Œ€ ์ถ•์†Œ ์—†์Œ)
19
  MEMBERS = {
20
  "์„œ์œค (Korea)": { "voice": "ko-KR-SunHiNeural", "prompt": "๋ณด์ปฌ ์„œ์œค. ์‹œ๋‹ˆ์ปฌํ•˜์ง€๋งŒ ์ง„์‹ฌ์ž„." },
21
  "Chloe (USA)": { "voice": "en-US-AriaNeural", "prompt": "Guitarist Chloe. Cool rockstar vibe." },
@@ -28,7 +33,15 @@ MEMBERS = {
28
  }
29
 
30
  async def band_consulting(user_input, member_name, lang_code):
 
 
 
 
 
31
  try:
 
 
 
32
  member_data = MEMBERS.get(member_name, MEMBERS["์„œ์œค (Korea)"])
33
  lang_map = {"ko":"Korean","en":"English","ja":"Japanese","pt":"Portuguese","es":"Spanish","ar":"Arabic","zh":"Chinese","fr":"French"}
34
  target_lang = lang_map.get(lang_code, "Korean")
@@ -40,57 +53,69 @@ async def band_consulting(user_input, member_name, lang_code):
40
  3. ๋งˆ์ง€๋ง‰์— [MUSIC: ์˜์–ด ํ”„๋กฌํ”„ํŠธ]๋ฅผ ํฌํ•จํ•˜์„ธ์š”.
41
  """
42
 
 
43
  url = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key={GENAI_KEY}"
44
  payload = {"contents": [{"parts": [{"text": f"{system_instruction}\n์งˆ๋ฌธ: {user_input}"}]}]}
45
 
46
- response = requests.post(url, json=payload, timeout=20)
47
- res_data = response.json()
 
48
 
49
  if 'candidates' not in res_data:
50
- clean_text = "์˜๊ฐ์ด ๊ผฌ์˜€์–ด. ๋‹ค์‹œ ์‹œ๋„ํ•ด์ค˜!"
51
- tab_display = "๋ฐ์ดํ„ฐ ์˜ค๋ฅ˜"
52
- music_p = "rock music riff"
53
  else:
54
  ai_text_raw = res_data['candidates'][0]['content']['parts'][0]['text']
55
- tab_match = re.search(r'\[TAB\](.*?)(\[|$)', ai_text_raw, re.DOTALL)
56
- music_match = re.search(r'\[MUSIC:(.*?)\]', ai_text_raw, re.IGNORECASE)
57
- tab_display = tab_match.group(1).strip() if tab_match else "์ƒ์„ธ ์•…๋ณด ์—†์Œ"
58
- clean_text = re.sub(r'\[TAB\].*?(\[|$)', '', ai_text_raw, flags=re.DOTALL)
59
- clean_text = re.sub(r'\[MUSIC:.*?\]', '', clean_text).strip()
60
- music_p = music_match.group(1).strip() if music_match else "rock guitar riff"
61
-
62
- # ์Œ์„ฑ ์ƒ์„ฑ
63
- tts_final = "\n".join(clean_text.split('\n')[:5])
64
- voice_path = f"/tmp/v_{member_name.split()[0]}.mp3"
65
- communicate = edge_tts.Communicate(re.sub(r'[\*\#\-\_\~\|]', '', tts_final), member_data['voice'])
 
66
  await communicate.save(voice_path)
67
 
68
- # ์Œ์•… ์ƒ์„ฑ
69
- music_path = None
70
  if music_synthesiser:
71
- try:
72
- # ํ•„ํ„ฐ ๋‹จ์–ด ์šฐํšŒ ๋ฐ ๊ธธ์ด ์กฐ์ ˆ (12์ดˆ)
73
- safe_p = music_p.lower()
74
- if any(x in safe_p for x in ['laugh', 'vocal', 'voice', 'human']):
75
- safe_p = "heavy rock electric guitar riff"
76
-
77
- music_output = music_synthesiser(safe_p, forward_params={"max_new_tokens": 512})
78
- if music_output and "audio" in music_output:
79
- music_path = f"/tmp/m_{member_name.split()[0]}.wav"
80
- scipy.io.wavfile.write(music_path, music_output["sampling_rate"], music_output["audio"][0].T)
81
- except:
82
- music_path = None
 
 
 
 
 
 
 
 
83
 
84
- return tts_final, voice_path, music_path, tab_display
85
 
86
  except Exception as e:
87
- return f"System Overload: {str(e)}", None, None, "Error"
 
88
 
 
89
  with gr.Blocks() as demo:
90
- # API ์ „์šฉ ์ตœ์†Œ UI (๋ชจ๋“  ๋กœ์ง์€ predict๋กœ ์—ฐ๊ฒฐ)
91
- i1 = gr.Textbox(); i2 = gr.Textbox(); i3 = gr.Textbox()
92
- o1 = gr.Textbox(); o2 = gr.Audio(); o3 = gr.Audio(); o4 = gr.Textbox()
93
- btn = gr.Button("GO"); btn.click(band_consulting, [i1, i2, i3], [o1, o2, o3, o4], api_name="predict")
 
 
94
 
95
- # ํ ์‹œ์Šคํ…œ์„ ์ ์šฉํ•˜๋˜ ssr_mode๋Š” False๋กœ ์„ค์ •ํ•˜์—ฌ asyncio ์—๋Ÿฌ ๋ฐฉ์ง€
96
  demo.queue().launch(ssr_mode=False)
 
1
  import gradio as gr
2
+ import httpx
3
  import edge_tts
4
  import os
5
  import re
6
+ import uuid
7
+ import torch
8
+ import numpy as np
9
  import scipy.io.wavfile
10
+ import asyncio
11
  from transformers import pipeline
12
 
13
+ # ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ๋กœ๋“œ ๋ฐ ๊ฒ€์ฆ
14
  GENAI_KEY = os.getenv("GEMINI_KEY")
15
 
16
+ # ์Œ์•… ์ƒ์„ฑ ๋ชจ๋ธ ๋กœ๋“œ
17
  try:
18
  music_synthesiser = pipeline("text-to-audio", "facebook/musicgen-small")
19
  except Exception as e:
20
  print(f"Music Model Load Error: {e}")
21
  music_synthesiser = None
22
 
23
+ # 8์ธ ๋ฉค๋ฒ„ ๋ฐ์ดํ„ฐ (์›๋ณธ ๋ณด์กด)
24
  MEMBERS = {
25
  "์„œ์œค (Korea)": { "voice": "ko-KR-SunHiNeural", "prompt": "๋ณด์ปฌ ์„œ์œค. ์‹œ๋‹ˆ์ปฌํ•˜์ง€๋งŒ ์ง„์‹ฌ์ž„." },
26
  "Chloe (USA)": { "voice": "en-US-AriaNeural", "prompt": "Guitarist Chloe. Cool rockstar vibe." },
 
33
  }
34
 
35
  async def band_consulting(user_input, member_name, lang_code):
36
+ # ๋ฆฌํ€˜์ŠคํŠธ๋ณ„ ๊ณ ์œ  ID ์ƒ์„ฑ (ํŒŒ์ผ ์ถฉ๋Œ ๋ฐฉ์ง€)
37
+ req_id = str(uuid.uuid4())[:8]
38
+ voice_path = f"/tmp/v_{req_id}.mp3"
39
+ music_path = f"/tmp/m_{req_id}.wav"
40
+
41
  try:
42
+ if not GENAI_KEY:
43
+ raise ValueError("API Key is missing in Environment Variables")
44
+
45
  member_data = MEMBERS.get(member_name, MEMBERS["์„œ์œค (Korea)"])
46
  lang_map = {"ko":"Korean","en":"English","ja":"Japanese","pt":"Portuguese","es":"Spanish","ar":"Arabic","zh":"Chinese","fr":"French"}
47
  target_lang = lang_map.get(lang_code, "Korean")
 
53
  3. ๋งˆ์ง€๋ง‰์— [MUSIC: ์˜์–ด ํ”„๋กฌํ”„ํŠธ]๋ฅผ ํฌํ•จํ•˜์„ธ์š”.
54
  """
55
 
56
+ # ๋น„๋™๊ธฐ HTTP ํด๋ผ์ด์–ธํŠธ ์‚ฌ์šฉ (Blocking ๋ฐฉ์ง€)
57
  url = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key={GENAI_KEY}"
58
  payload = {"contents": [{"parts": [{"text": f"{system_instruction}\n์งˆ๋ฌธ: {user_input}"}]}]}
59
 
60
+ async with httpx.AsyncClient() as client:
61
+ response = await client.post(url, json=payload, timeout=25.0)
62
+ res_data = response.json()
63
 
64
  if 'candidates' not in res_data:
65
+ ai_text_raw = "์˜๊ฐ์ด ์ž ์‹œ ์ฐจ๋‹จ๋์–ด. ๋‹ค์‹œ ๋ฌผ์–ด๋ด์ค„๋ž˜? [TAB] API ์‘๋‹ต ์˜ค๋ฅ˜ [MUSIC: rock guitar riff]"
 
 
66
  else:
67
  ai_text_raw = res_data['candidates'][0]['content']['parts'][0]['text']
68
+
69
+ # ์ •๊ทœํ‘œํ˜„์‹ ํŒŒ์‹ฑ (๋Œ€์†Œ๋ฌธ์ž ๋ฌด์‹œ ๋ฐ ์œ ์—ฐํ•œ ๋งค์นญ)
70
+ tab_match = re.search(r'\[TAB\](.*?)(\[|$)', ai_text_raw, re.DOTALL | re.IGNORECASE)
71
+ music_match = re.search(r'\[MUSIC:(.*?)\]', ai_text_raw, re.IGNORECASE)
72
+
73
+ tab_display = tab_match.group(1).strip() if tab_match else "์ƒ์„ธ ์ •๋ณด ์—†์Œ"
74
+ clean_text = re.sub(r'\[TAB\].*?(\[|$)', '', ai_text_raw, flags=re.DOTALL | re.IGNORECASE)
75
+ clean_text = re.sub(r'\[MUSIC:.*?\]', '', clean_text, flags=re.IGNORECASE).strip()
76
+
77
+ # TTS ์Œ์„ฑ ์ƒ์„ฑ
78
+ tts_text = "\n".join(clean_text.split('\n')[:5])
79
+ communicate = edge_tts.Communicate(re.sub(r'[\*\#\-\_\~\|]', '', tts_text), member_data['voice'])
80
  await communicate.save(voice_path)
81
 
82
+ # ์Œ์•… ์ƒ์„ฑ (Blocking ๋ฐฉ์ง€ ์œ„ํ•ด ๋ณ„๋„ ์Šค๋ ˆ๋“œ ๊ณ ๋ ค ๊ฐ€๋Šฅํ•˜๋‚˜ Gradio Queue๊ฐ€ ์žˆ์œผ๋ฏ€๋กœ ์ง์ ‘ ์‹คํ–‰)
 
83
  if music_synthesiser:
84
+ music_p = music_match.group(1).strip() if music_match else "rock music"
85
+ # ๊ฐ€์ด๋“œ๋ผ์ธ ์œ„๋ฐ˜ ๋‹จ์–ด ์šฐํšŒ
86
+ if any(x in music_p.lower() for x in ['laugh', 'vocal', 'voice', 'human']):
87
+ music_p = "energetic rock electric guitar solo"
88
+
89
+ # [MUSICGEN ์‹คํ–‰] - 512 ํ† ํฐ (์•ฝ 12์ดˆ)
90
+ music_output = music_synthesiser(music_p, forward_params={"max_new_tokens": 512})
91
+
92
+ # ์˜ค๋””์˜ค ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ (Float32 -> Int16)
93
+ audio_tensor = music_output["audio"]
94
+ if torch.is_tensor(audio_tensor):
95
+ audio_data = audio_tensor.cpu().numpy()
96
+ else:
97
+ audio_data = np.array(audio_tensor)
98
+
99
+ audio_data = np.squeeze(audio_data) # ์ฐจ์› ์••์ถ•
100
+ audio_int16 = (audio_data * 32767).astype(np.int16) # ์ •๊ทœํ™”
101
+ scipy.io.wavfile.write(music_path, music_output["sampling_rate"], audio_int16)
102
+ else:
103
+ music_path = None
104
 
105
+ return tts_text, voice_path, music_path, tab_display
106
 
107
  except Exception as e:
108
+ print(f"Critical Error: {e}")
109
+ return f"System Overload: ๋‹ค์‹œ ์‹œ๋„ํ•ด์ฃผ์„ธ์š”. ({str(e)})", None, None, "Error"
110
 
111
+ # Gradio Interface
112
  with gr.Blocks() as demo:
113
+ # ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•œ ๋‚ด๋ถ€ ํ†ต๋กœ
114
+ i1 = gr.Textbox(visible=False); i2 = gr.Textbox(visible=False); i3 = gr.Textbox(visible=False)
115
+ o1 = gr.Textbox(visible=False); o2 = gr.Audio(visible=False); o3 = gr.Audio(visible=False); o4 = gr.Textbox(visible=False)
116
+
117
+ btn = gr.Button("GO", visible=False) # JS์—์„œ ํ˜ธ์ถœ์šฉ
118
+ btn.click(band_consulting, [i1, i2, i3], [o1, o2, o3, o4], api_name="predict")
119
 
120
+ # ํ ํ™œ์„ฑํ™” ๋ฐ ์‹คํ–‰
121
  demo.queue().launch(ssr_mode=False)