<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">import asyncio
from fastapi import FastAPI, Request, HTTPException
from fastapi.responses import FileResponse
from fastapi.middleware.cors import CORSMiddleware
from io import BytesIO
import subprocess
import ffmpeg
import os
import tempfile
import re


# Obtiene la ruta absoluta del directorio actual
current_dir = os.path.dirname(os.path.abspath(__file__))

app = FastAPI()

# ConfiguraciÃ³n de CORS
origins = [
    "http://localhost",
    "http://localhost:8080",
    "http://localhost:5500",  # Agrega el puerto correspondiente al dominio de tu frontend
    "http://127.0.0.1",
    "http://127.0.0.1:5500",
]

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],    #en lugar de origins
    allow_credentials=True,
    allow_methods=["GET", "POST", "PUT", "DELETE"],
    allow_headers=["*"],
)

async def convert_text_to_mp3(text):
    # Establece el directorio de trabajo al directorio del script
    script_dir = os.path.dirname(os.path.abspath(__file__)) + '\piper'    
    text = remove_special_chars(text)
    print(f"Texto aprocesar: {text}")
    os.chdir(script_dir)
    # Ejecuta el archivo ejecutable y captura la salida WAV
    process = await asyncio.create_subprocess_shell(
        f'echo "{text}" | piper/piper.exe --model es_MX-claude-high.onnx -c es_es_MX_claude_high_es_MX-claude-high.onnx.json -f Output.wav',
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE
    )
    await process.communicate()  # Espera a que el proceso termine
    print(f"Process finished with status code {process.returncode}")

    # Convierte el archivo WAV a MP3
    wav_output = "Output.wav"
    #output_file = "Output.mp3"
    #ffmpeg_cmd = f'ffmpeg -i "{wav_output}" -vn -ar 44100 -ac 2 -b:a 192k "{output_file}"'

   # Ejecuta el comando ffmpeg de forma asÃ­ncrona
    #ffmpeg_process = await asyncio.create_subprocess_shell(ffmpeg_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    #stdout, stderr = await ffmpeg_process.communicate()  # Espera a que ffmpeg termine de ejecutarse
    #print(f"ffmpeg process finished with status code {ffmpeg_process.returncode}")
    #if stderr:
    #    raise Exception(f"Error during ffmpeg conversion: {stderr.decode()}")

    # Devuelve el archivo MP3
    with open(wav_output, 'rb') as wav_file:
        wav_data = wav_file.read()

    # Elimina los archivos generados
    os.remove(wav_output)
    #os.remove(output_file)

    return wav_data

def remove_special_chars(text):
    """
    Remove special characters from a string, allowing only letters, numbers, and punctuation characters accepted by Piper TTS.

    Args:
        text (str): The input string.

    Returns:
        str: The string with special characters removed.
    """

    allowed_chars = re.compile(r"[a-zA-Z0-9.,!?;:\"'\(\)]")
    return "".join(allowed_chars.findall(text))

def preprocesar_texto(texto):
    """
    Preprocesa un texto para optimizar su funcionamiento con Piper TTS.

    Args:
    texto (str): La cadena de texto a preprocesar.

    Returns:
    str: La cadena de texto preprocesada.
    """
    # Eliminar caracteres inadecuados y reemplazar algunos caracteres
    texto = texto.replace(',', '')  # Eliminar comas
    texto = texto.replace(';', '')  # Eliminar puntos y comas
    texto = texto.replace('"', '')  # Eliminar comillas dobles
    texto = texto.replace("'", '')  # Eliminar comillas simples
    texto = texto.replace('*', '')  # Eliminar asteriscos
    texto = texto.replace('.', ' ,,, ')  # Reemplazar puntos por pausas
    texto = texto.replace('!', ' ! ')  # Reemplazar signos de exclamaciÃ³n por pausas
    texto = texto.replace('?', ' ? ')  # Reemplazar signos de interrogaciÃ³n por pausas

    # Eliminar caracteres inadecuados y reemplazar por su equivalente adecuado
    # texto = re.sub(r'[.,;?!]', ' ', texto)  # Reemplazar puntos, comas, punto y coma, signos de exclamaciÃ³n e interrogaciÃ³n por espacios
    # texto = re.sub(r'["\']', '', texto)  # Eliminar comillas dobles y simples
    # texto = re.sub(r'\\', '', texto)  # Eliminar barras invertidas

    # Reemplazar letras acentuadas por sus equivalentes sin acento
    # texto = texto.replace('Ã¡', 'a').replace('Ã©', 'e').replace('Ã­', 'i').replace('Ã³', 'o').replace('Ãº', 'u')
    # texto = texto.replace('Ã', 'A').replace('Ã‰', 'E').replace('Ã', 'I').replace('Ã“', 'O').replace('Ãš', 'U')

    # Eliminar retornos de carro y reemplazar por espacios
    texto = texto.replace('\n', ' ')

    # Eliminar caracteres de control o invisibles (opcional, depende del caso)
    texto = ''.join(c for c in texto if c.isprintable())

    # Convertir el texto a minÃºsculas (opcional, depende del caso)
    texto = texto.lower()

    return texto.strip()  # Eliminar espacios en blanco al inicio y final del texto

# Ejemplo de uso:
# texto_original = "Â¡Hola Mundo, quÃ© tal estÃ¡s?"
# texto_preprocesado = preprocesar_texto(texto_original)
# print(texto_preprocesado)  # Resultado: "Â¡hola mundo quÃ© tal estÃ¡s . "



@app.post("/generate_audio")
async def convert(request: Request) -&gt; FileResponse:
    try:
        data: dict = await request.json()
        text = data["text"]
        mp3_output = await convert_text_to_mp3(text)
        print(f"Generated MP3 of {len(mp3_output)} bytes")

        # Create temporary file to hold MP3 data
        with tempfile.NamedTemporaryFile(delete=False) as temp_file:
            temp_file.write(mp3_output)
            temp_file.seek(0)

            # Create and return FileResponse
            file_response = FileResponse(temp_file.name, media_type="audio/mp3", filename="output.mp3")
        
        return file_response
    except KeyError:
        raise HTTPException(status_code=422, detail="The 'text' field is required in the request body")
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Error converting text: {str(e)}")

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, port=8000)


# Arrancar con 
# .\.venv\Scripts\activate
# uvicorn app:app --host localhost --port 8000</pre></body></html>