import os os.environ["COQUI_TOS_AGREED"] = "1" import spaces import gradio as gr import torch # --- Compatibility shim --- # Newer `transformers` (5.x, needed here for gradio's huggingface-hub # requirement) removed `isin_mps_friendly` from transformers.pytorch_utils. # coqui-tts still imports it. This restores the function before coqui-tts # is imported, so both libraries work together in this environment. import transformers.pytorch_utils as _ptu if not hasattr(_ptu, "isin_mps_friendly"): def _isin_mps_friendly(elements, test_elements): return torch.isin(elements, test_elements) _ptu.isin_mps_friendly = _isin_mps_friendly from TTS.api import TTS print("Loading XTTS-v2 model...") device = "cuda" if torch.cuda.is_available() else "cpu" tts_model = TTS("tts_models/multilingual/multi-dataset/xtts_v2").to(device) print("Model ready.") LANGUAGES = { "English": "en", "Hindi": "hi", "Spanish": "es", "French": "fr", "German": "de", "Arabic": "ar", "Chinese": "zh-cn", "Japanese": "ja", "Korean": "ko", } @spaces.GPU(duration=60) def clone_voice(reference_audios, text, language_label): if not reference_audios: raise gr.Error("Please upload at least one voice sample (longer, clean samples work best).") if not text or not text.strip(): raise gr.Error("Please enter the text you want spoken in the cloned voice.") try: lang_code = LANGUAGES[language_label] output_path = "/tmp/cloned_output.wav" # Accept either a single file or multiple — more reference clips # generally improves how closely the output matches the voice. speaker_wavs = reference_audios if isinstance(reference_audios, list) else [reference_audios] tts_model.tts_to_file( text=text, speaker_wav=speaker_wavs, language=lang_code, file_path=output_path, ) return output_path except Exception as e: import traceback traceback.print_exc() raise gr.Error(f"Voice cloning failed: {e}") css = """ #header { text-align: center; padding: 24px 0 8px; } #header h1 { font-size: 32px; font-weight: 700; background: linear-gradient(135deg, #6366f1, #06b6d4); -webkit-background-clip: text; -webkit-text-fill-color: transparent; margin-bottom: 4px; } #header p { color: #888; font-size: 14px; } #license-note { text-align: center; font-size: 12px; color: #999; padding: 0 20px 16px; } #run-btn { background: linear-gradient(135deg, #6366f1, #06b6d4) !important; color: white !important; font-weight: 600 !important; border: none !important; } """ with gr.Blocks(title="Peace Network Voice Clone", css=css) as demo: gr.HTML( """
Non-commercial use only (Coqui Public Model License). Personal projects ke liye theek hai, client/commercial kaam ke liye alag license chahiye.
""" ) reference = gr.File( label="Your voice samples (upload 2-3 clean clips, 20-30 sec each, works much better than one short clip)", file_count="multiple", file_types=["audio"], type="filepath", ) text_input = gr.Textbox( label="Text to speak in your cloned voice", placeholder="Type what you want your cloned voice to say...", lines=5, ) language = gr.Dropdown( choices=list(LANGUAGES.keys()), value="Hindi", label="Language" ) btn = gr.Button("🗣️ Clone & Generate", variant="primary", elem_id="run-btn") output_audio = gr.Audio(label="Cloned voice output", type="filepath") btn.click(clone_voice, inputs=[reference, text_input, language], outputs=output_audio) demo.queue().launch()