sg123321 commited on
Commit
3767dfa
·
verified ·
1 Parent(s): e9f5c42

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +30 -85
app.py CHANGED
@@ -5,7 +5,7 @@ import torch
5
  import spaces
6
  from TTS.api import TTS
7
  from supabase import create_client, Client
8
- import config # आपकी config file
9
 
10
  # 1. Supabase Connection
11
  supabase = None
@@ -23,22 +23,16 @@ print(f"⏳ Loading XTTS Model on {device}...")
23
  tts = TTS("tts_models/multilingual/multi-dataset/xtts_v2").to(device)
24
 
25
  # --- Helper Functions ---
26
-
27
  def get_voice_list():
28
- """Supabase Bucket से फाइलों की लिस्ट लाता है"""
29
  if not supabase: return []
30
  try:
31
- # 'voice-bucket' से सारी फाइलें लाना
32
  res = supabase.storage.from_("voice-bucket").list()
33
- # सिर्फ ऑडियो फाइलें छांटना
34
  files = [f['name'] for f in res if f['name'].endswith(('.wav', '.mp3'))]
35
  return files
36
  except Exception as e:
37
- print(f"List Error: {e}")
38
  return []
39
 
40
  def download_cloud_voice(filename):
41
- """क्लाउड से फाइल डाउनलोड करके temp फोल्डर में रखता है"""
42
  local_path = f"temp_{filename}"
43
  with open(local_path, 'wb+') as f:
44
  res = supabase.storage.from_("voice-bucket").download(filename)
@@ -46,119 +40,70 @@ def download_cloud_voice(filename):
46
  return local_path
47
 
48
  # --- Main Logic ---
49
-
50
  @spaces.GPU(duration=120)
51
  def generate_preview(text, language, upload_voice, cloud_voice_name):
52
- # 1. Voice Selection Logic (Upload को पहली प्राथमिकता)
53
  speaker_wav = None
54
-
55
  if upload_voice is not None:
56
- print("🎙️ Using Uploaded Voice")
57
  speaker_wav = upload_voice
58
  elif cloud_voice_name:
59
- print(f"☁️ Using Cloud Voice: {cloud_voice_name}")
60
  try:
61
  speaker_wav = download_cloud_voice(cloud_voice_name)
62
  except Exception as e:
63
- return None, f"Error downloading voice: {e}"
64
  else:
65
- return None, "⚠️ Please upload a voice OR select one from Cloud!"
66
 
67
- # 2. Preview Logic (Delete Previous / Overwrite)
68
- # हम हमेशा एक ही नाम 'preview.wav' यूज़ करेंगे।
69
- # इससे जब भी नया ऑडियो बनेगा, पुराना वाला अपने आप मिट जाएगा।
70
  output_path = "preview.wav"
71
-
72
- print("🔄 Generating Preview...")
73
- tts.tts_to_file(
74
- text=text,
75
- file_path=output_path,
76
- speaker_wav=speaker_wav,
77
- language=language
78
- )
79
-
80
- return output_path, "✅ Preview Ready! Save karne ke liye neeche button dabayein."
81
 
82
  def save_to_cloud(preview_path, text, language):
83
- """सिर्फ तब सेव करेगा जब यूजर चाहेगा"""
84
  if not preview_path or not os.path.exists(preview_path):
85
- return "⚠️ No preview found! Pehle 'Generate Preview' karein."
86
-
87
  if not supabase:
88
  return "❌ Supabase not connected!"
89
 
90
- # फाइल का नया यूनिक नाम
91
  filename = f"final_{language}_{uuid.uuid4()}.wav"
92
-
93
  try:
94
- print("☁️ Uploading to Supabase...")
95
  with open(preview_path, 'rb') as f:
96
  supabase.storage.from_("voice-bucket").upload(filename, f)
97
 
98
- # पब्लिक लिंक
99
  storage_url = f"{config.SUPABASE_URL}/storage/v1/object/public/voice-bucket/{filename}"
100
 
101
- # डेटाबेस एंट्री
102
- data = {
103
- "name": f"Clone_{language}",
104
- "file_path": storage_url,
105
- "ref_text": text
106
- }
107
  supabase.table("clones").insert(data).execute()
108
 
109
- return f"🎉 Saved Successfully! Link: {storage_url}"
110
  except Exception as e:
111
  return f"❌ Save Error: {e}"
112
 
113
- # --- UI Layout (Blocks) ---
114
- with gr.Blocks(title="Shubham's Ultimate Voice Cloner") as app:
115
- gr.Markdown("## 🚀 XTTS Voice Cloning (With Preview & Cloud Select)")
116
 
117
  with gr.Row():
118
- # Text Input Area
119
  with gr.Column():
120
- txt_input = gr.Textbox(label="Text to Speak", lines=3, value="Namaste, main ab preview lekar cloud par save ho sakta hoon.")
121
- lang_dropdown = gr.Dropdown(label="Language", choices=["hi", "en", "es", "fr"], value="hi")
122
-
123
- # Voice Selection Area
124
  with gr.Column():
125
- gr.Markdown("### 🎤 Select Voice Source")
126
- # Tab 1: Upload
127
- voice_upload = gr.Audio(label="Option A: Upload New Voice", type="filepath")
128
- # Tab 2: Cloud Select
129
- voice_dropdown = gr.Dropdown(label="Option B: Choose from Supabase", choices=get_voice_list(), interactive=True)
130
- refresh_btn = gr.Button("🔄 Refresh Cloud List") # लिस्ट रिफ्रेश करने के लिए
131
-
132
- # Action Buttons
133
- btn_preview = gr.Button("🔊 Generate Preview (Wait for it...)", variant="primary")
134
-
135
- # Output Area
136
- audio_output = gr.Audio(label="Preview Audio (Temporary)")
137
- status_msg = gr.Textbox(label="Status", interactive=False)
138
-
139
- # Save Button (Preview ke baad dabana hai)
140
- btn_save = gr.Button("☁️ Save this to Supabase", variant="secondary")
141
-
142
- # --- Click Events ---
143
-
144
- # 1. Refresh Button Logic
145
- def refresh_list():
146
- return gr.Dropdown(choices=get_voice_list())
147
- refresh_btn.click(refresh_list, outputs=voice_dropdown)
148
 
149
- # 2. Preview Generation
150
- btn_preview.click(
151
- fn=generate_preview,
152
- inputs=[txt_input, lang_dropdown, voice_upload, voice_dropdown],
153
- outputs=[audio_output, status_msg]
154
- )
155
 
156
- # 3. Save to Cloud
157
- btn_save.click(
158
- fn=save_to_cloud,
159
- inputs=[audio_output, txt_input, lang_dropdown],
160
- outputs=status_msg
161
- )
162
 
 
163
  if __name__ == "__main__":
164
- app.launch(server_name="0.0.0.0", server_port=7860)
 
 
 
 
 
5
  import spaces
6
  from TTS.api import TTS
7
  from supabase import create_client, Client
8
+ import config
9
 
10
  # 1. Supabase Connection
11
  supabase = None
 
23
  tts = TTS("tts_models/multilingual/multi-dataset/xtts_v2").to(device)
24
 
25
  # --- Helper Functions ---
 
26
  def get_voice_list():
 
27
  if not supabase: return []
28
  try:
 
29
  res = supabase.storage.from_("voice-bucket").list()
 
30
  files = [f['name'] for f in res if f['name'].endswith(('.wav', '.mp3'))]
31
  return files
32
  except Exception as e:
 
33
  return []
34
 
35
  def download_cloud_voice(filename):
 
36
  local_path = f"temp_{filename}"
37
  with open(local_path, 'wb+') as f:
38
  res = supabase.storage.from_("voice-bucket").download(filename)
 
40
  return local_path
41
 
42
  # --- Main Logic ---
 
43
  @spaces.GPU(duration=120)
44
  def generate_preview(text, language, upload_voice, cloud_voice_name):
 
45
  speaker_wav = None
 
46
  if upload_voice is not None:
 
47
  speaker_wav = upload_voice
48
  elif cloud_voice_name:
 
49
  try:
50
  speaker_wav = download_cloud_voice(cloud_voice_name)
51
  except Exception as e:
52
+ return None, f"Error downloading: {e}"
53
  else:
54
+ return None, "⚠️ Please select a voice!"
55
 
 
 
 
56
  output_path = "preview.wav"
57
+ tts.tts_to_file(text=text, file_path=output_path, speaker_wav=speaker_wav, language=language)
58
+ return output_path, "✅ Preview Ready!"
 
 
 
 
 
 
 
 
59
 
60
  def save_to_cloud(preview_path, text, language):
 
61
  if not preview_path or not os.path.exists(preview_path):
62
+ return "⚠️ No preview found!"
 
63
  if not supabase:
64
  return "❌ Supabase not connected!"
65
 
 
66
  filename = f"final_{language}_{uuid.uuid4()}.wav"
 
67
  try:
 
68
  with open(preview_path, 'rb') as f:
69
  supabase.storage.from_("voice-bucket").upload(filename, f)
70
 
 
71
  storage_url = f"{config.SUPABASE_URL}/storage/v1/object/public/voice-bucket/{filename}"
72
 
73
+ data = {"name": f"Clone_{language}", "file_path": storage_url, "ref_text": text}
 
 
 
 
 
74
  supabase.table("clones").insert(data).execute()
75
 
76
+ return f"🎉 Saved! Link: {storage_url}"
77
  except Exception as e:
78
  return f"❌ Save Error: {e}"
79
 
80
+ # --- UI Layout ---
81
+ with gr.Blocks(title="Shubham's Secure Voice AI") as app:
82
+ gr.Markdown("## 🔐 Secure XTTS Voice Cloning")
83
 
84
  with gr.Row():
 
85
  with gr.Column():
86
+ txt_input = gr.Textbox(label="Text", lines=3, value="Namaste!")
87
+ lang_dropdown = gr.Dropdown(label="Language", choices=["hi", "en"], value="hi")
 
 
88
  with gr.Column():
89
+ voice_upload = gr.Audio(label="Upload Voice", type="filepath")
90
+ voice_dropdown = gr.Dropdown(label="Select from Cloud", choices=get_voice_list())
91
+ refresh_btn = gr.Button("🔄 Refresh List")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
 
93
+ btn_preview = gr.Button("🔊 Generate Preview", variant="primary")
94
+ audio_output = gr.Audio(label="Preview")
95
+ status_msg = gr.Textbox(label="Status")
96
+ btn_save = gr.Button("☁️ Save to Cloud", variant="secondary")
 
 
97
 
98
+ # Events
99
+ refresh_btn.click(lambda: gr.Dropdown(choices=get_voice_list()), outputs=voice_dropdown)
100
+ btn_preview.click(generate_preview, inputs=[txt_input, lang_dropdown, voice_upload, voice_dropdown], outputs=[audio_output, status_msg])
101
+ btn_save.click(save_to_cloud, inputs=[audio_output, txt_input, lang_dropdown], outputs=status_msg)
 
 
102
 
103
+ # 🚀 LOGIN SYSTEM (Powered by Config/Secrets)
104
  if __name__ == "__main__":
105
+ app.launch(
106
+ auth=(config.APP_USER, config.APP_PASS), # 🔒 Ab ye config file se password lega
107
+ server_name="0.0.0.0",
108
+ server_port=7860
109
+ )