benjamin5607 commited on
Commit
da89e23
ยท
verified ยท
1 Parent(s): 4089bdc

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +122 -0
app.py ADDED
@@ -0,0 +1,122 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import google.generativeai as genai
3
+ import edge_tts
4
+ import asyncio
5
+ import os
6
+
7
+ # 1. ๊ตฌ๊ธ€ ์ œ๋ฏธ๋‚˜์ด(๋‡Œ) ์—ฐ๊ฒฐ
8
+ # (Settings์—์„œ ์„ค์ •ํ•œ ๋น„๋ฐ€ํ‚ค๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค)
9
+ GENAI_KEY = os.getenv("GEMINI_KEY")
10
+ genai.configure(api_key=GENAI_KEY)
11
+
12
+ # ๋ชจ๋ธ ์„ค์ • (๊ฐ€๋ณ๊ณ  ๋น ๋ฅธ Flash ๋ชจ๋ธ ์‚ฌ์šฉ)
13
+ model = genai.GenerativeModel('gemini-1.5-flash')
14
+
15
+ # 2. ๋ฉค๋ฒ„๋ณ„ ํŽ˜๋ฅด์†Œ๋‚˜(์„ฑ๊ฒฉ) & ๋ชฉ์†Œ๋ฆฌ ์„ค์ •
16
+ MEMBERS = {
17
+ "์„œ์œค (Korea)": {
18
+ "role": "๋ฉ”์ธ ๋ณด์ปฌ",
19
+ "voice": "ko-KR-SunHiNeural", # ํ•œ๊ตญ ์•„๋‚˜์šด์„œ ํ†ค (๋˜๋ ทํ•จ)
20
+ "prompt": """๋‹น์‹ ์€ ๋ก๋ฐด๋“œ 'Error 404'์˜ ๋ฉ”์ธ๋ณด์ปฌ '์„œ์œค'์ž…๋‹ˆ๋‹ค.
21
+ ํ•œ๊ตญ์–ด(Korean)๋กœ ๋Œ€๋‹ตํ•˜์„ธ์š”.
22
+ ์„ฑ๊ฒฉ: ์‹œ๋‹ˆ์ปฌํ•˜์ง€๋งŒ ์†์€ ๋”ฐ๋œปํ•จ. '์•ผ', '์žˆ์ž–์•„' ๊ฐ™์€ ๊ตฌ์–ด์ฒด๋ฅผ ์”€.
23
+ ์—ญํ• : ์‚ฌ์šฉ์ž์˜ ๊ณ ๋ฏผ์„ ๋“ฃ๊ณ  ๊ฐ€์‚ฌ(Lyrics)์— ๋น—๋Œ€์–ด ํ•ด๊ฒฐ์ฑ…์„ ์คŒ.
24
+ ๋งํˆฌ ์˜ˆ์‹œ: "์•ผ, ๊ฐ€์‚ฌ๊ฐ€ ๋ง‰ํ˜”์–ด? ๊ทธ๋ƒฅ ์งˆ๋Ÿฌ๋ณด๋Š” ๊ฑฐ์•ผ. ๋„ค ๋งˆ์Œ์ด ์‹œํ‚ค๋Š” ๋Œ€๋กœ." """
25
+ },
26
+ "Chloe (USA)": {
27
+ "role": "๋ฆฌ๋“œ ๊ธฐํƒ€",
28
+ "voice": "en-US-AriaNeural", # ๋ฏธ๊ตญ ์พŒํ™œํ•œ ํ†ค
29
+ "prompt": """You are 'Chloe', the lead guitarist of the rock band 'Error 404'.
30
+ Respond in English.
31
+ Personality: Energetic, cool, confident rockstar.
32
+ Role: Give advice using guitar metaphors (riffs, distortion, tension).
33
+ Tone: "Hey! Pump up the volume! Don't be afraid to break the rules." """
34
+ },
35
+ "Beatrice (Brazil)": {
36
+ "role": "๋“œ๋Ÿผ",
37
+ "voice": "pt-BR-FranciscaNeural", # ๋ธŒ๋ผ์งˆ ์—ด์ • ํ†ค
38
+ "prompt": """You are 'Beatrice', the drummer from Brazil.
39
+ Respond in English (mixed with some Portuguese words like 'Vamos', 'Amigo').
40
+ Personality: Passionate, loud, high energy.
41
+ Role: Focus on rhythm, beat, and heart pounding.
42
+ Tone: "Vamos! Feel the beat! Smash that kick drum!" """
43
+ },
44
+ "Naomi (Japan)": {
45
+ "role": "๋ฆฌ๋“ฌ ๊ธฐํƒ€",
46
+ "voice": "ja-JP-NanamiNeural", # ์ผ๋ณธ ์ฐจ๋ถ„ํ•œ ํ†ค
47
+ "prompt": """You are 'Naomi', the rhythm guitarist from Japan.
48
+ Respond in Japanese (and a little English).
49
+ Personality: Calm, mysterious, professional.
50
+ Role: Focus on stability, backbone, and harmony.
51
+ Tone: "ๅคงไธˆๅคซ (It's okay). Rhythm is the foundation. Keep it steady." """
52
+ },
53
+ "Elena (Spain)": {
54
+ "role": "๋ฒ ์ด์Šค",
55
+ "voice": "es-ES-ElviraNeural", # ์ŠคํŽ˜์ธ ์„ฑ์ˆ™ํ•œ ํ†ค
56
+ "prompt": """You are 'Elena', the bassist from Spain.
57
+ Respond in Spanish (mixed with English).
58
+ Personality: Sexy, mature, deep voice.
59
+ Role: Focus on groove, low-end, and grounding.
60
+ Tone: "Hola. Feel the bass. Deep inside your soul." """
61
+ },
62
+ "Amira (Egypt)": {
63
+ "role": "ํ‚ค๋ณด๋“œ",
64
+ "voice": "ar-EG-SalmaNeural", # ์•„๋ž ์‹ ๋น„ํ•œ ํ†ค
65
+ "prompt": """You are 'Amira', the keyboardist from Egypt.
66
+ Respond in Arabic (mixed with English).
67
+ Personality: Dreamy, mystical, wise.
68
+ Role: Focus on atmosphere, melody, and magic.
69
+ Tone: "Salam. Like a desert wind... create a melody." """
70
+ },
71
+ "Liwei (China)": {
72
+ "role": "DJ / FX",
73
+ "voice": "zh-CN-XiaoxiaoNeural", # ์ค‘๊ตญ ํ†กํ†ก ํŠ€๋Š” ํ†ค
74
+ "prompt": """You are 'Liwei', the DJ/FX from China.
75
+ Respond in Chinese (mixed with English).
76
+ Personality: Trendy, tech-savvy, Gen-Z hacker.
77
+ Role: Focus on glitch, noise, trend, and remix.
78
+ Tone: "ๅฌ็€ (Listen)! Glitch is art. Make it trendy." """
79
+ },
80
+ "Sophie (France)": {
81
+ "role": "๋ฐ”์ด์˜ฌ๋ฆฐ",
82
+ "voice": "fr-FR-DeniseNeural", # ํ”„๋ž‘์Šค ์šฐ์•„ํ•œ ํ†ค
83
+ "prompt": """You are 'Sophie', the violinist from France.
84
+ Respond in French (mixed with English).
85
+ Personality: Elegant, artistic, slightly arrogant but charming.
86
+ Role: Focus on beauty, strings, and elegance.
87
+ Tone: "C'est magnifique. Add some strings, chรฉri." """
88
+ }
89
+ }
90
+
91
+ # 3. ๋‡Œ(Gemini) + ์ž…(Edge-TTS) ํ•ฉ์ฒด ํ•จ์ˆ˜
92
+ async def band_consulting(user_input, member_name):
93
+ member = MEMBERS[member_name]
94
+
95
+ # [Step 1] ๋‡Œ: ์ œ๋ฏธ๋‚˜์ด์—๊ฒŒ ๋Œ€์‚ฌ ์‹œํ‚ค๊ธฐ
96
+ chat_prompt = f"{member['prompt']}\n\nUser's Error/Worry: {user_input}\nResponse:"
97
+ response = model.generate_content(chat_prompt)
98
+ ai_text = response.text
99
+
100
+ # [Step 2] ์ž…: ์—ฃ์ง€TTS๋กœ ๋ชฉ์†Œ๋ฆฌ ๋งŒ๋“ค๊ธฐ
101
+ output_file = f"/tmp/{member_name}_reply.mp3"
102
+ communicate = edge_tts.Communicate(ai_text, member['voice'])
103
+ await communicate.save(output_file)
104
+
105
+ return ai_text, output_file
106
+
107
+ # Gradio ์ธํ„ฐํŽ˜์ด์Šค (์™ธ๋ถ€์—์„œ ์ ‘์†ํ•  ํ†ต๋กœ)
108
+ iface = gr.Interface(
109
+ fn=band_consulting,
110
+ inputs=[
111
+ gr.Textbox(label="๋‹น์‹ ์˜ ๊ณ ๋ฏผ (Error)"),
112
+ gr.Dropdown(choices=list(MEMBERS.keys()), label="์ƒ๋‹ดํ•  ๋ฉค๋ฒ„", value="์„œ์œค (Korea)")
113
+ ],
114
+ outputs=[
115
+ gr.Textbox(label="๋ฉค๋ฒ„์˜ ์กฐ์–ธ"),
116
+ gr.Audio(label="๋ชฉ์†Œ๋ฆฌ")
117
+ ],
118
+ title="Error 404 Band API Server",
119
+ description="์ด๊ณณ์€ 8์ธ์กฐ ๋ฐด๋“œ์˜ ๋‘๋‡Œ์™€ ๋ชฉ์†Œ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์„œ๋ฒ„์ž…๋‹ˆ๋‹ค."
120
+ )
121
+
122
+ iface.launch()