benjamin5607 commited on
Commit
8ee2277
Β·
verified Β·
1 Parent(s): f47f0ad

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +96 -104
app.py CHANGED
@@ -2,133 +2,125 @@ import gradio as gr
2
  import requests
3
  import edge_tts
4
  import os
5
- import json
 
 
 
 
6
 
7
- # 1. API ν‚€ μ„€μ •
8
  GENAI_KEY = os.getenv("GEMINI_KEY")
9
 
10
- # ======================================================
11
- # πŸ•΅οΈβ€β™‚οΈ [핡심] ꡬ글 μ„œλ²„μ—μ„œ 'μ§„μ§œ λͺ¨λΈ 이름' μ•Œμ•„μ˜€κΈ°
12
- # ======================================================
 
 
 
 
 
 
 
 
13
  def find_working_model():
14
- # λͺ¨λΈ 리슀트 쑰회 API 호좜
15
  url = f"https://generativelanguage.googleapis.com/v1beta/models?key={GENAI_KEY}"
16
- response = requests.get(url)
17
-
18
- if response.status_code != 200:
19
- print(f"❌ λͺ¨λΈ 리슀트 쑰회 μ‹€νŒ¨: {response.text}")
20
- return "gemini-pro" # μ‹€νŒ¨ν•˜λ©΄ κ·Έλƒ₯ 깑톡 λͺ¨λΈλ‘œ 작기
21
-
22
- data = response.json()
23
-
24
- # 1. 'generateContent' κΈ°λŠ₯이 μžˆλŠ” λͺ¨λΈλ§Œ 필터링
25
- candidates = []
26
- if 'models' in data:
27
- for m in data['models']:
28
- if 'supportedGenerationMethods' in m and 'generateContent' in m['supportedGenerationMethods']:
29
- # μ΄λ¦„μ—μ„œ 'models/' λΆ€λΆ„ λ–Όκ³  μ €μž₯ (예: models/gemini-pro -> gemini-pro)
30
- clean_name = m['name'].replace("models/", "")
31
- candidates.append(clean_name)
32
-
33
- print(f"πŸ“‹ μ‚¬μš© κ°€λŠ₯ λͺ¨λΈ λͺ©λ‘: {candidates}")
34
-
35
- # 2. μš°μ„ μˆœμœ„λŒ€λ‘œ 선택 (ν”Œλž˜μ‹œ -> ν”„λ‘œ)
36
- # λ¦¬λ”λ‹˜ ν‚€λ‘œ 'gemini-1.5-flash'κ°€ μ•ˆλ˜λ©΄ 'gemini-1.0-pro'라도 μž‘μŠ΅λ‹ˆλ‹€.
37
- preferred_order = [
38
- "gemini-1.5-flash-latest",
39
- "gemini-1.5-flash",
40
- "gemini-1.5-flash-001",
41
- "gemini-1.5-pro",
42
- "gemini-1.0-pro",
43
- "gemini-pro"
44
- ]
45
-
46
- for pref in preferred_order:
47
- if pref in candidates:
48
- print(f"βœ… κ²°μ •λœ λͺ¨λΈ: {pref}")
49
- return pref
50
-
51
- # μ„ ν˜Έν•˜λŠ” 게 μ—†μœΌλ©΄ λͺ©λ‘μ˜ 첫 번째 λ†ˆ 작기
52
- if candidates:
53
- print(f"⚠️ μ„ ν˜Έ λͺ¨λΈ μ—†μŒ. λŒ€μ²΄ λͺ¨λΈ μ‚¬μš©: {candidates[0]}")
54
- return candidates[0]
55
-
56
- return "gemini-pro" # μ§„μ§œ 아무것도 μ—†μœΌλ©΄...
57
-
58
- # ======================================================
59
- # 3. 직접 톡신 ν•¨μˆ˜ (λͺ¨λΈλͺ…을 λ™μ μœΌλ‘œ λ„£μŒ)
60
- # ======================================================
61
- def call_gemini_direct(prompt, model_name):
62
- # μœ„μ—μ„œ 찾은 λͺ¨λΈλͺ…을 URL에 λΌμ›Œλ„£κΈ°
63
- url = f"https://generativelanguage.googleapis.com/v1beta/models/{model_name}:generateContent?key={GENAI_KEY}"
64
-
65
- headers = {'Content-Type': 'application/json'}
66
- data = {
67
- "contents": [{
68
- "parts": [{"text": prompt}]
69
- }]
70
- }
71
-
72
- response = requests.post(url, headers=headers, json=data)
73
-
74
- if response.status_code == 200:
75
- return response.json()['candidates'][0]['content']['parts'][0]['text']
76
- else:
77
- # μ—λŸ¬ λ‚˜λ©΄ μ—λŸ¬ λ©”μ‹œμ§€ λ°˜ν™˜
78
- raise Exception(f"Google API Error ({model_name}): {response.text}")
79
 
 
80
 
81
- # 4. 멀버 데이터 (κ·ΈλŒ€λ‘œ)
82
  MEMBERS = {
83
- "μ„œμœ€ (Korea)": { "role": "메인 보컬", "voice": "ko-KR-SunHiNeural", "prompt": "당신은 λ‘λ°΄λ“œ 'Error 404'의 메인보컬 'μ„œμœ€'μž…λ‹ˆλ‹€. ν•œκ΅­μ–΄(Korean)둜 λŒ€λ‹΅ν•˜μ„Έμš”. 성격: μ‹œλ‹ˆμ»¬, 츀데레. 말투: 'μ•Ό', 'μžˆμž–μ•„' μ‚¬μš©." },
84
- "Chloe (USA)": { "role": "λ¦¬λ“œ 기타", "voice": "en-US-AriaNeural", "prompt": "You are 'Chloe'. Respond in English. Personality: Cool rockstar." },
85
- "Beatrice (Brazil)": { "role": "λ“œλŸΌ", "voice": "pt-BR-FranciscaNeural", "prompt": "You are 'Beatrice'. Respond in English/Portuguese. Personality: Passionate." },
86
- "Naomi (Japan)": { "role": "리듬 기타", "voice": "ja-JP-NanamiNeural", "prompt": "You are 'Naomi'. Respond in Japanese. Personality: Calm." },
87
- "Elena (Spain)": { "role": "베이슀", "voice": "es-ES-ElviraNeural", "prompt": "You are 'Elena'. Respond in Spanish/English. Personality: Mature." },
88
- "Amira (Egypt)": { "role": "ν‚€λ³΄λ“œ", "voice": "ar-EG-SalmaNeural", "prompt": "You are 'Amira'. Respond in Arabic/English. Personality: Mystical." },
89
- "Liwei (China)": { "role": "DJ / FX", "voice": "zh-CN-XiaoxiaoNeural", "prompt": "You are 'Liwei'. Respond in Chinese/English. Personality: Trendy." },
90
- "Sophie (France)": { "role": "λ°”μ΄μ˜¬λ¦°", "voice": "fr-FR-DeniseNeural", "prompt": "You are 'Sophie'. Respond in French/English. Personality: Elegant." }
91
  }
92
 
93
  async def band_consulting(user_input, member_name):
94
  try:
95
  if member_name not in MEMBERS:
96
- return f"Error: 이름 뢈일치! ('{member_name}')", None
97
 
98
  member = MEMBERS[member_name]
99
- full_prompt = f"{member['prompt']}\n\nUser's Error/Worry: {user_input}\nResponse:"
100
 
101
- try:
102
- # 1. μ‚΄μ•„μžˆλŠ” λͺ¨λΈ μ°ΎκΈ° (맀번 찾으면 λŠλ¦¬λ‹ˆκΉŒ μΊμ‹±ν•˜λ©΄ μ’‹μ§€λ§Œ, 확싀함을 μœ„ν•΄ 맀번 확인)
103
- active_model = find_working_model()
104
-
105
- # 2. κ·Έ λͺ¨λΈλ‘œ μš”μ²­ 보내기
106
- ai_text = call_gemini_direct(full_prompt, active_model)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
 
108
- except Exception as e:
109
- return f"Error (Gemini): {str(e)}", None
 
 
 
 
 
 
 
 
 
110
 
111
- try:
112
- output_file = f"/tmp/{member_name}_reply.mp3"
113
- communicate = edge_tts.Communicate(ai_text, member['voice'])
114
- await communicate.save(output_file)
115
- except Exception as e:
116
- return f"Error (TTS): {str(e)}", None
117
 
118
- return ai_text, output_file
 
 
 
 
 
 
 
 
 
 
 
119
 
120
  except Exception as e:
121
- return f"System Error: {str(e)}", None
122
 
123
- # UI
124
  with gr.Blocks() as demo:
125
- gr.Markdown("# Error 404 Band API Server (Auto-Discovery Mode)")
126
  with gr.Row():
127
- inp_text = gr.Textbox(label="κ³ λ―Ό μž…λ ₯")
128
- inp_member = gr.Dropdown(choices=list(MEMBERS.keys()), label="멀버 선택", value="μ„œμœ€ (Korea)")
129
- out_text = gr.Textbox(label="μ‘°μ–Έ")
130
- out_audio = gr.Audio(label="μŒμ„±")
131
- btn = gr.Button("상담 μš”μ²­")
132
- btn.click(fn=band_consulting, inputs=[inp_text, inp_member], outputs=[out_text, out_audio], api_name="predict")
 
 
133
 
134
  demo.launch()
 
2
  import requests
3
  import edge_tts
4
  import os
5
+ import re
6
+ import torch
7
+ import scipy.io.wavfile
8
+ import numpy as np
9
+ from transformers import pipeline
10
 
11
+ # 1. API ν‚€ (ν™˜κ²½λ³€μˆ˜ μ„€μ • ν•„μˆ˜!)
12
  GENAI_KEY = os.getenv("GEMINI_KEY")
13
 
14
+ # 2. [μž‘κ³‘κ°€] MusicGen λͺ¨λΈ λ‘œλ“œ
15
+ print("⏳ μž‘κ³‘κ°€(MusicGen) μ„­μ™Έ 쀑... (μ΅œλŒ€ 1~2λΆ„ μ†Œμš”)")
16
+ try:
17
+ # facebook/musicgen-small : 가볍고 λΉ λ₯Έ λͺ¨λΈ
18
+ music_synthesiser = pipeline("text-to-audio", "facebook/musicgen-small")
19
+ print("βœ… μž‘κ³‘κ°€ μ„­μ™Έ μ™„λ£Œ! Start Jamming!")
20
+ except Exception as e:
21
+ print(f"⚠️ μž‘κ³‘ λͺ¨λΈ λ‘œλ“œ μ‹€νŒ¨: {e}")
22
+ music_synthesiser = None
23
+
24
+ # 3. Gemini λͺ¨λΈ μ°ΎκΈ° 헬퍼
25
  def find_working_model():
 
26
  url = f"https://generativelanguage.googleapis.com/v1beta/models?key={GENAI_KEY}"
27
+ try:
28
+ response = requests.get(url)
29
+ if response.status_code != 200: return "gemini-pro"
30
+ data = response.json()
31
+ candidates = [m['name'].replace("models/", "") for m in data.get('models', []) if 'generateContent' in m.get('supportedGenerationMethods', [])]
32
+ preferred = ["gemini-1.5-flash", "gemini-1.5-flash-latest", "gemini-pro"]
33
+ for p in preferred:
34
+ if p in candidates: return p
35
+ return candidates[0] if candidates else "gemini-pro"
36
+ except:
37
+ return "gemini-pro"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
 
39
+ ACTIVE_MODEL = find_working_model()
40
 
41
+ # 4. 멀버 페λ₯΄μ†Œλ‚˜ μ •μ˜
42
  MEMBERS = {
43
+ "μ„œμœ€ (Korea)": { "voice": "ko-KR-SunHiNeural", "prompt": "당신은 λ‘λ°΄λ“œ 보컬 'μ„œμœ€'μž…λ‹ˆλ‹€. ν•œκ΅­μ–΄(Korean)둜 λŒ€λ‹΅ν•˜μ„Έμš”. 성격: μ‹œλ‹ˆμ»¬ν•˜μ§€λ§Œ μŒμ•…μ—” 진심. λ‹΅λ³€ 끝에 μž‘κ³‘ 아이디어λ₯Ό ν¬ν•¨ν•˜μ„Έμš”." },
44
+ "Chloe (USA)": { "voice": "en-US-AriaNeural", "prompt": "You are 'Chloe', the lead guitarist. Speak in English. Personality: Cool rockstar. Suggest guitar riffs." },
45
+ "Beatrice (Brazil)": { "voice": "pt-BR-FranciscaNeural", "prompt": "You are 'Beatrice', the drummer. Speak in English/Portuguese. Focus on rhythm and groove." },
46
+ "Naomi (Japan)": { "voice": "ja-JP-NanamiNeural", "prompt": "You are 'Naomi'. Speak in Japanese. Focus on melody and chords." },
47
+ "Elena (Spain)": { "voice": "es-ES-ElviraNeural", "prompt": "You are 'Elena'. Speak in Spanish/English. Focus on bass lines." },
48
+ "Amira (Egypt)": { "voice": "ar-EG-SalmaNeural", "prompt": "You are 'Amira'. Speak in Arabic/English. Focus on atmosphere." },
49
+ "Liwei (China)": { "voice": "zh-CN-XiaoxiaoNeural", "prompt": "You are 'Liwei'. Speak in Chinese/English. Focus on FX and sound design." },
50
+ "Sophie (France)": { "voice": "fr-FR-DeniseNeural", "prompt": "You are 'Sophie'. Speak in French/English. Focus on emotional melody." }
51
  }
52
 
53
  async def band_consulting(user_input, member_name):
54
  try:
55
  if member_name not in MEMBERS:
56
+ return "Error: Unknown Member", None, None
57
 
58
  member = MEMBERS[member_name]
 
59
 
60
+ # β˜… μ‹œμŠ€ν…œ ν”„λ‘¬ν”„νŠΈ: μž‘κ³‘ λͺ…λ Ή [MUSIC:...] 을 μœ λ„
61
+ system_instruction = f"""
62
+ {member['prompt']}
63
+
64
+ [INSTRUCTION]
65
+ 1. Give advice based on the user's input.
66
+ 2. IF appropriate (user asks for music, sample, or feeling), create a short music sample.
67
+ 3. To create music, write a hidden command at the END of your response like this:
68
+ [MUSIC: genre, tempo, instruments, mood]
69
+
70
+ Example: "Let's go with a heavy beat! [MUSIC: heavy metal drum beat, 140bpm, aggressive]"
71
+ If no music needed, do NOT write [MUSIC:...].
72
+ """
73
+
74
+ # Gemini 호좜
75
+ url = f"https://generativelanguage.googleapis.com/v1beta/models/{ACTIVE_MODEL}:generateContent?key={GENAI_KEY}"
76
+ payload = {"contents": [{"parts": [{"text": f"{system_instruction}\nUser: {user_input}\nResponse:"}]}]}
77
+ res = requests.post(url, json=payload, headers={'Content-Type': 'application/json'})
78
+
79
+ if res.status_code != 200:
80
+ return f"API Error: {res.text}", None, None
81
 
82
+ ai_text_raw = res.json()['candidates'][0]['content']['parts'][0]['text']
83
+
84
+ # μŒμ•… λͺ…λ Ή μΆ”μΆœ
85
+ music_prompt = None
86
+ clean_text = ai_text_raw
87
+ match = re.search(r'\[MUSIC:(.*?)\]', ai_text_raw, re.IGNORECASE)
88
+
89
+ if match:
90
+ music_prompt = match.group(1).strip()
91
+ clean_text = ai_text_raw.replace(match.group(0), "").strip()
92
+ print(f"🎡 μž‘κ³‘ μš”μ²­: {music_prompt}")
93
 
94
+ # TTS (λͺ©μ†Œλ¦¬) 생성
95
+ voice_path = f"/tmp/{member_name}_voice.mp3"
96
+ await edge_tts.Communicate(clean_text, member['voice']).save(voice_path)
 
 
 
97
 
98
+ # MusicGen (μŒμ•…) 생성
99
+ music_path = None
100
+ if music_prompt and music_synthesiser:
101
+ try:
102
+ # max_new_tokens=256 (μ•½ 5초) ~ 512 (μ•½ 10초)
103
+ music = music_synthesiser(music_prompt, forward_params={"max_new_tokens": 512})
104
+ music_path = f"/tmp/{member_name}_music.wav"
105
+ scipy.io.wavfile.write(music_path, music["sampling_rate"], music["audio"][0].T)
106
+ except Exception as e:
107
+ print(f"❌ μž‘κ³‘ μ‹€νŒ¨: {e}")
108
+
109
+ return clean_text, voice_path, music_path
110
 
111
  except Exception as e:
112
+ return f"System Error: {e}", None, None
113
 
114
+ # Gradio μ•± μ‹€ν–‰
115
  with gr.Blocks() as demo:
 
116
  with gr.Row():
117
+ inp = gr.Textbox(label="Input")
118
+ mem = gr.Textbox(label="Member")
119
+ out_text = gr.Textbox(label="Advice")
120
+ out_voice = gr.Audio(label="Voice")
121
+ out_music = gr.Audio(label="Music Sample")
122
+
123
+ btn = gr.Button("GO")
124
+ btn.click(band_consulting, [inp, mem], [out_text, out_voice, out_music], api_name="predict")
125
 
126
  demo.launch()