diff --git a/audio_handler.py b/audio_handler.py index 525a187..4cc30fe 100644 --- a/audio_handler.py +++ b/audio_handler.py @@ -4,6 +4,8 @@ from pydub import AudioSegment from gtts import gTTS import uuid import re +from elevenlabs import generate, save, Voice, VoiceSettings +from elevenlabs.client import ElevenLabs def transcribe_audio(file_path: str) -> str: """Converte áudio (qualquer formato compatível com pydub) para WAV e transcreve com Google Speech.""" @@ -24,19 +26,38 @@ def transcribe_audio(file_path: str) -> str: os.remove(temp_wav) def text_to_speech(text: str) -> str: - """Sintetiza texto em áudio MP3, removendo tags visuais e emojis.""" + """Sintetiza texto em áudio MP3 usando ElevenLabs (voz masculina) ou gTTS como fallback.""" # Limpeza para narração texto_limpo = text.replace("🤖", "").replace("🧑‍🏫", "").replace("*", "").replace("`", "") - # Remove o bloco se houver, pois ele é para leitura visual apenas texto_limpo = re.sub(r'.*?', '', texto_limpo, flags=re.DOTALL).strip() - # Se sobrar texto vazio após limpar o refinado (raro), fala algo genérico if not texto_limpo: texto_limpo = "Relatório processado. Os detalhes estão no painel visual." filename = f"audio_reply_{uuid.uuid4().hex[:8]}.mp3" filepath = os.path.join("/tmp", filename) + api_key = os.getenv("ELEVENLABS_API_KEY") + voice_id = os.getenv("ELEVENLABS_VOICE_ID", "ErMmoak87FvRAs60I6g0") # Marco (Male, PT-BR) as default + + if api_key: + try: + client = ElevenLabs(api_key=api_key) + audio = client.generate( + text=texto_limpo, + voice=voice_id, + model="eleven_multilingual_v2" + ) + # Salvando o resultado para arquivo + with open(filepath, "wb") as f: + for chunk in audio: + if chunk: + f.write(chunk) + return filename + except Exception as e: + print(f"[VOICE] Erro ElevenLabs: {e}. Usando fallback gTTS.") + + # Fallback gTTS (Voz feminina lenta mas gratuita) tts = gTTS(text=texto_limpo, lang='pt-br', tld='com.br', slow=False) tts.save(filepath) return filename