File size: 4,018 Bytes
1dd5ac4 c0b8023 5de0578 c0b8023 3767dfa 5de0578 1dd5ac4 c0b8023 1dd5ac4 c0b8023 1dd5ac4 9c8f593 1dd5ac4 c0b8023 5de0578 1dd5ac4 5de0578 1dd5ac4 c0b8023 1dd5ac4 3767dfa 1dd5ac4 3767dfa 1dd5ac4 3767dfa 1dd5ac4 3767dfa 1dd5ac4 3767dfa 1dd5ac4 3767dfa 1dd5ac4 3767dfa 1dd5ac4 3767dfa 1dd5ac4 3767dfa 1dd5ac4 3767dfa 1dd5ac4 3767dfa 1dd5ac4 3767dfa 1dd5ac4 3767dfa | 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 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | import os
import uuid
import gradio as gr
import torch
import spaces
from TTS.api import TTS
from supabase import create_client, Client
import config
# 1. Supabase Connection
supabase = None
if config.IS_CONNECTED:
try:
supabase: Client = create_client(config.SUPABASE_URL, config.SUPABASE_KEY)
print("β
Supabase Connected!")
except Exception as e:
print(f"β Supabase Error: {e}")
# 2. Model Setup
os.environ["COQUI_TOS_AGREED"] = "1"
device = "cuda" if torch.cuda.is_available() else "cpu"
print(f"β³ Loading XTTS Model on {device}...")
tts = TTS("tts_models/multilingual/multi-dataset/xtts_v2").to(device)
# --- Helper Functions ---
def get_voice_list():
if not supabase: return []
try:
res = supabase.storage.from_("voice-bucket").list()
files = [f['name'] for f in res if f['name'].endswith(('.wav', '.mp3'))]
return files
except Exception as e:
return []
def download_cloud_voice(filename):
local_path = f"temp_{filename}"
with open(local_path, 'wb+') as f:
res = supabase.storage.from_("voice-bucket").download(filename)
f.write(res)
return local_path
# --- Main Logic ---
@spaces.GPU(duration=120)
def generate_preview(text, language, upload_voice, cloud_voice_name):
speaker_wav = None
if upload_voice is not None:
speaker_wav = upload_voice
elif cloud_voice_name:
try:
speaker_wav = download_cloud_voice(cloud_voice_name)
except Exception as e:
return None, f"Error downloading: {e}"
else:
return None, "β οΈ Please select a voice!"
output_path = "preview.wav"
tts.tts_to_file(text=text, file_path=output_path, speaker_wav=speaker_wav, language=language)
return output_path, "β
Preview Ready!"
def save_to_cloud(preview_path, text, language):
if not preview_path or not os.path.exists(preview_path):
return "β οΈ No preview found!"
if not supabase:
return "β Supabase not connected!"
filename = f"final_{language}_{uuid.uuid4()}.wav"
try:
with open(preview_path, 'rb') as f:
supabase.storage.from_("voice-bucket").upload(filename, f)
storage_url = f"{config.SUPABASE_URL}/storage/v1/object/public/voice-bucket/{filename}"
data = {"name": f"Clone_{language}", "file_path": storage_url, "ref_text": text}
supabase.table("clones").insert(data).execute()
return f"π Saved! Link: {storage_url}"
except Exception as e:
return f"β Save Error: {e}"
# --- UI Layout ---
with gr.Blocks(title="Shubham's Secure Voice AI") as app:
gr.Markdown("## π Secure XTTS Voice Cloning")
with gr.Row():
with gr.Column():
txt_input = gr.Textbox(label="Text", lines=3, value="Namaste!")
lang_dropdown = gr.Dropdown(label="Language", choices=["hi", "en"], value="hi")
with gr.Column():
voice_upload = gr.Audio(label="Upload Voice", type="filepath")
voice_dropdown = gr.Dropdown(label="Select from Cloud", choices=get_voice_list())
refresh_btn = gr.Button("π Refresh List")
btn_preview = gr.Button("π Generate Preview", variant="primary")
audio_output = gr.Audio(label="Preview")
status_msg = gr.Textbox(label="Status")
btn_save = gr.Button("βοΈ Save to Cloud", variant="secondary")
# Events
refresh_btn.click(lambda: gr.Dropdown(choices=get_voice_list()), outputs=voice_dropdown)
btn_preview.click(generate_preview, inputs=[txt_input, lang_dropdown, voice_upload, voice_dropdown], outputs=[audio_output, status_msg])
btn_save.click(save_to_cloud, inputs=[audio_output, txt_input, lang_dropdown], outputs=status_msg)
# π LOGIN SYSTEM (Powered by Config/Secrets)
if __name__ == "__main__":
app.launch(
auth=(config.APP_USER, config.APP_PASS), # π Ab ye config file se password lega
server_name="0.0.0.0",
server_port=7860
) |