import tempfile import gradio as gr from elevenlabs.client import ElevenLabs # Premade ElevenLabs voices (name -> voice_id). Voices on the user's own account are # looked up by name with their API key, so custom names typed into the dropdown work too. PREMADE_VOICES = { "Rachel": "21m00Tcm4TlvDq8ikWAM", "Sarah": "EXAVITQu4vr4xnSDxMaL", "Aria": "9BWtsMINqrJLrRacOk9x", "Laura": "FGY2WhTYpPnrIDTdsKH5", "Charlotte": "XB0fDUnXU5powFXDhCwa", "Alice": "Xb7hH8MSUJpSbSDYk0k2", "Matilda": "XrExE9yKIg1WjnnlVkGX", "Jessica": "cgSgspJ2msm6clMCkdW9", "Lily": "pFZP5JQG7iQjIQuC4Bku", "Adam": "pNInz6obpgDQGcFmaJgB", "Roger": "CwhRBWXzGAHq8TQ4Fs17", "Charlie": "IKne3meq5aSn9XLyUdCD", "George": "JBFqnCBsd6RMkjVDRZzb", "Callum": "N2lVS1w4EtoT3dr4eOWO", "Liam": "TX3LPaxmHKxFdv7VOQHJ", "Will": "bIHbv24MWmeRgasZH58o", "Eric": "cjVigY5qzO86Huf0OWal", "Chris": "iP95p4xoKVk53GoZ742B", "Brian": "nPczCjzI2devNBz1zQrb", "Daniel": "onwK4e9ZLuTAKqWW03F9", "Bill": "pqHfZKP75CvOlQylNhV4", } def resolve_voice_id(client, voice_name): try: for voice in client.voices.get_all().voices: if voice.name and voice.name.split(" - ")[0].strip().lower() == voice_name.strip().lower(): return voice.voice_id except Exception: pass if voice_name in PREMADE_VOICES: return PREMADE_VOICES[voice_name] raise gr.Error(f"Voice '{voice_name}' was not found on your ElevenLabs account.") def generate_voice(text, voice_name, api_key): if not api_key or not api_key.strip(): raise gr.Error("Please enter your ElevenLabs API key.") if not text or not text.strip(): raise gr.Error("Please enter some text.") client = ElevenLabs(api_key=api_key.strip()) try: voice_id = resolve_voice_id(client, voice_name or "Rachel") audio = client.text_to_speech.convert( voice_id=voice_id, text=text[:4000], # Limit to 4000 characters model_id="eleven_multilingual_v2", output_format="mp3_44100_128", ) with tempfile.NamedTemporaryFile(delete=False, suffix=".mp3") as f: for chunk in audio: if chunk: f.write(chunk) return f.name except gr.Error: raise except Exception as e: body = getattr(e, "body", None) detail = body.get("detail", body) if isinstance(body, dict) else None if isinstance(detail, dict): detail = detail.get("message") or detail status = getattr(e, "status_code", None) msg = f"{status}: {detail}" if detail else str(e) raise gr.Error(f"ElevenLabs error {msg}") with gr.Blocks() as block: with gr.Row(variant='panel'): input_api_key = gr.Textbox( type='password', label='ElevenLabs API Key', placeholder='Enter your API key', elem_id="input_api_key" ) input_voice = gr.Dropdown( list(PREMADE_VOICES), value="Rachel", label="Voice", allow_custom_value=True, elem_id="input_voice" ) input_text = gr.Textbox( label="Input Text (4000 characters max)", lines=1, value="Hello! 你好! Hola! नमस्ते! Bonjour! こんにちは! مرحبا! 안녕하세요! Ciao! Cześć! Привіт! Γειά σας! Здравей! வணக்கம்!", elem_id="input_text" ) run_button = gr.Button( value="Generate Voice", variant="primary" ) out_audio = gr.Audio( label="Speech Output", type="filepath", elem_id="out_audio", ) run_button.click( fn=generate_voice, inputs=[input_text, input_voice, input_api_key], outputs=[out_audio], api_name="generate_voice", ) block.queue(default_concurrency_limit=5).launch(theme='Nymbo/Alyx_Theme')