import asyncio import edge_tts import re import subprocess # Cambiado para mayor seguridad from pathlib import Path def limpiar_markdown(texto): texto = re.sub(r'```.*?```', ' [código] ', texto, flags=re.DOTALL) texto = re.sub(r'\|.*?\|', '', texto) texto = re.sub(r'[#*_~`>]', '', texto) return ' '.join(texto.split()) async def convertir_archivo(path_md): bloque = path_md.parent.name # bloque1, bloque2, etc. audios_dir = Path('audios') / bloque audios_dir.mkdir(parents=True, exist_ok=True) temp_output = audios_dir / (path_md.stem + '.temp.mp3') final_output = audios_dir / (path_md.stem + '.mp3') nombre_tema = path_md.stem.replace('_', ' ').capitalize() texto = path_md.read_text(encoding="utf-8") texto_limpio = limpiar_markdown(texto) # 1. Generar audio comunicar = edge_tts.Communicate(texto_limpio, "es-ES-AlvaroNeural") await comunicar.save(str(temp_output)) # 2. Normalización con FFmpeg usando subprocess comando = [ 'ffmpeg', '-i', str(temp_output), '-codec:a', 'libmp3lame', '-b:a', '192k', '-ar', '44100', '-metadata', f'title={nombre_tema}', '-id3v2_version', '3', '-write_id3v1', '1', '-y', str(final_output) ] try: # Ejecutar sin mostrar la molesta ventana negra de ffmpeg subprocess.run(comando, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) except FileNotFoundError: print(f"❌ Error: No se encontró 'ffmpeg'. Asegúrate de que esté instalado.") return if temp_output.exists(): temp_output.unlink() print(f"✅ Listo: {final_output.name} (Título: {nombre_tema})") async def main(): for carpeta in ['bloque1', 'bloque2', 'bloque3', 'bloque4']: archivos = sorted(Path(carpeta).glob('*_audio.md')) if not archivos: print(f"No se encontraron archivos *_audio.md en la carpeta '{carpeta}'") continue for md in archivos: print(f"Procesando: {md.name}...") await convertir_archivo(md) if __name__ == "__main__": asyncio.run(main())