# genesis/narration.py import os import requests from typing import Optional ELEVEN_LABS_API_KEY = os.getenv("ELEVEN_LABS_API_KEY") VOICE_ID = "EXAVITQu4vr4xnSDxMaL" # Default voice; change in ElevenLabs dashboard if needed def narrate_text(text: str) -> Optional[str]: """Convert text to speech using ElevenLabs API and return audio URL.""" if not ELEVEN_LABS_API_KEY: print("[Narration] No ElevenLabs API key provided.") return None try: url = f"https://api.elevenlabs.io/v1/text-to-speech/{VOICE_ID}" headers = { "xi-api-key": ELEVEN_LABS_API_KEY, "Content-Type": "application/json" } payload = { "text": text, "voice_settings": { "stability": 0.4, "similarity_boost": 0.8 } } r = requests.post(url, headers=headers, json=payload, timeout=30) r.raise_for_status() # Save audio locally audio_file = "narration.mp3" with open(audio_file, "wb") as f: f.write(r.content) # In Spaces, you can serve local files directly return audio_file except Exception as e: print(f"[Narration] Failed: {e}") return None