Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,21 +1,26 @@
|
|
| 1 |
import gradio as gr
|
| 2 |
-
import
|
| 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 |
-
|
| 47 |
-
|
|
|
|
| 48 |
|
| 49 |
if 'candidates' not in res_data:
|
| 50 |
-
|
| 51 |
-
tab_display = "๋ฐ์ดํฐ ์ค๋ฅ"
|
| 52 |
-
music_p = "rock music riff"
|
| 53 |
else:
|
| 54 |
ai_text_raw = res_data['candidates'][0]['content']['parts'][0]['text']
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
|
|
|
| 66 |
await communicate.save(voice_path)
|
| 67 |
|
| 68 |
-
# ์์
์์ฑ
|
| 69 |
-
music_path = None
|
| 70 |
if music_synthesiser:
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 83 |
|
| 84 |
-
return
|
| 85 |
|
| 86 |
except Exception as e:
|
| 87 |
-
|
|
|
|
| 88 |
|
|
|
|
| 89 |
with gr.Blocks() as demo:
|
| 90 |
-
#
|
| 91 |
-
i1 = gr.Textbox(); i2 = gr.Textbox(); i3 = gr.Textbox()
|
| 92 |
-
o1 = gr.Textbox(); o2 = gr.Audio(); o3 = gr.Audio(); o4 = gr.Textbox()
|
| 93 |
-
|
|
|
|
|
|
|
| 94 |
|
| 95 |
-
# ํ
|
| 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)
|