File size: 3,847 Bytes
da89e23
440060b
da89e23
 
8ee2277
 
 
d7ca5ff
 
 
 
 
 
da89e23
 
eef5842
d7ca5ff
8ee2277
d7ca5ff
 
8ee2277
 
d7ca5ff
 
 
 
 
 
 
 
 
 
 
 
1359090
7483917
84daabb
7483917
 
26c3944
d7ca5ff
8ee2277
26c3944
d7ca5ff
8ee2277
d7ca5ff
 
7483917
d7ca5ff
 
 
 
 
 
 
84daabb
d400633
26c3944
d7ca5ff
84daabb
d7ca5ff
a1bdc6d
d7ca5ff
 
 
 
 
d400633
d7ca5ff
84daabb
d7ca5ff
84daabb
f2609ff
d7ca5ff
5724da8
d7ca5ff
7483917
d400633
d7ca5ff
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
import gradio as gr
import requests
import edge_tts
import os
import re
import scipy.io.wavfile
from transformers import pipeline
# β˜… GPU 지원을 μœ„ν•œ 라이브러리 (Hugging Face ν™˜κ²½μΈ 경우)
try:
    import spaces
    has_spaces = True
except:
    has_spaces = False

GENAI_KEY = os.getenv("GEMINI_KEY")

# λͺ¨λΈ λ‘œλ“œ (Hugging Face μ΅œμ ν™”)
try:
    music_synthesiser = pipeline("text-to-audio", "facebook/musicgen-small", device=0 if has_spaces else -1)
except:
    music_synthesiser = None

# 8인 멀버 및 데이터 (μ‚­μ œ/μΆ•μ†Œ μ—†μŒ)
MEMBERS = { "μ„œμœ€ (Korea)": "ko-KR-SunHiNeural", "Chloe (USA)": "en-US-AriaNeural", "Naomi (Japan)": "ja-JP-NanamiNeural", "Beatrice (Brazil)": "pt-BR-FranciscaNeural", "Elena (Spain)": "es-ES-ElviraNeural", "Amira (Egypt)": "ar-EG-SalmaNeural", "Liwei (China)": "zh-CN-XiaoxiaoNeural", "Sophie (France)": "fr-FR-DeniseNeural" }

# β˜… GPU 가속 λ°μ½”λ ˆμ΄ν„° (Hugging Face 무료 GPU ν™œμ„±ν™”)
def generate_music_safe(prompt):
    if not music_synthesiser: return None, None
    try:
        # λ¦¬λ”λ‹˜ μš”μ²­λŒ€λ‘œ 512(μ•½ 12초) ν’€ νŒŒμ›Œ!
        output = music_synthesiser(prompt, forward_params={"max_new_tokens": 512, "do_sample": True})
        return output["sampling_rate"], output["audio"][0].T
    except:
        return None, None

async def band_consulting(user_input, member_name, lang_code):
    try:
        lang_map = {"ko":"Korean","en":"English","ja":"Japanese","pt":"Portuguese","es":"Spanish","ar":"Arabic","zh":"Chinese","fr":"French"}
        target_lang = lang_map.get(lang_code, "Korean")
        
        system_instruction = f"당신은 {member_name}μž…λ‹ˆλ‹€. λ°˜λ“œμ‹œ {target_lang}둜만 λ‹΅λ³€ν•˜μ„Έμš”. μŒμ„±μ€ 5쀄 이내, 상세 μ„€λͺ…은 [TAB]에, μŒμ•… ν”„λ‘¬ν”„νŠΈλŠ” [MUSIC: ν”„λ‘¬ν”„νŠΈ]에 λ„£μœΌμ„Έμš”."
        
        url = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key={GENAI_KEY}"
        payload = {"contents": [{"parts": [{"text": f"{system_instruction}\n질문: {user_input}"}]}]}
        
        res = requests.post(url, json=payload).json()
        ai_text_raw = res['candidates'][0]['content']['parts'][0]['text']
        
        tab_match = re.search(r'\[TAB\](.*?)(\[|$)', ai_text_raw, re.DOTALL)
        music_match = re.search(r'\[MUSIC:(.*?)\]', ai_text_raw, re.IGNORECASE)
        tab_display = tab_match.group(1).strip() if tab_match else "상세 악보 μ—†μŒ"
        
        clean_text = re.sub(r'\[TAB\].*?(\[|$)', '', ai_text_raw, flags=re.DOTALL)
        clean_text = re.sub(r'\[MUSIC:.*?\]', '', clean_text).strip()
        tts_final = "\n".join(clean_text.split('\n')[:5])

        # μŒμ„± 생성
        voice_path = f"/tmp/v_{member_name.split()[0]}.mp3"
        await edge_tts.Communicate(re.sub(r'[\*\#\-\_\~\|]', '', tts_final), MEMBERS.get(member_name, "ko-KR-SunHiNeural")).save(voice_path)
        
        # μŒμ•… 생성 (νƒ€μž„μ•„μ›ƒ λ°©μ§€ 둜직 포함)
        music_path = None
        if music_match:
            sr, audio = generate_music_safe(music_match.group(1).strip())
            if sr is not None:
                music_path = f"/tmp/m_{member_name.split()[0]}.wav"
                scipy.io.wavfile.write(music_path, sr, audio)

        return tts_final, voice_path, music_path, tab_display
    except Exception as e:
        return f"System Error: {str(e)}", None, None, "Error"

with gr.Blocks() as demo:
    i1 = gr.Textbox(); i2 = gr.Textbox(); i3 = gr.Textbox()
    o1 = gr.Textbox(); o2 = gr.Audio(); o3 = gr.Audio(); o4 = gr.Textbox()
    # β˜… 큐(Queue)λ₯Ό ν™œμ„±ν™”ν•˜μ—¬ μ„œλ²„κ°€ λŠκΈ°μ§€ μ•Šκ²Œ 함
    btn = gr.Button("GO"); btn.click(band_consulting, [i1, i2, i3], [o1, o2, o3, o4], api_name="predict")

# β˜… queue()λ₯Ό λ°˜λ“œμ‹œ λΆ™μ—¬μ•Ό κΈ΄ μž‘μ—…μ„ λΈŒλΌμš°μ €κ°€ κΈ°λ‹€λ €μ€λ‹ˆλ‹€.
demo.queue().launch()