Spaces:
Running
Running
import logging | |
from flask import Flask, render_template, request, jsonify, after_this_request | |
from functools import wraps | |
from io import BytesIO | |
import base64 | |
import subprocess | |
import os | |
import random | |
import string | |
import re | |
import sys | |
# Configuración del registro | |
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') | |
app = Flask(__name__) | |
# Define el directorio donde se guardan los archivos | |
file_folder = getattr(sys, '_MEIPASS', os.path.abspath(os.path.dirname(__file__))) | |
temp_audio_folder = "/home/app/temp_audio/" | |
model_folder = "/home/app/" | |
piper_binary_path = "/home/app/piper" | |
# Define los nombres asignados a modelos específicos | |
model_names = { | |
"Español México | Claude": "es_MX-claude-14947-epoch-high.onnx", | |
"Español México | Cortana v1": "es_MX-cortana-19669-epoch-high.onnx", | |
"Español México | TheGevy": "es_MX-gevy-10196-epoch-high.onnx", | |
"English United States Example": "en_US-ljspeech-high.onnx" | |
} | |
def filter_text(text): | |
filtered_text = re.sub(r'[^\w\s,.\(\):\u00C0-\u00FF]', '', text) # Filtra caracteres no deseados | |
filtered_text = filtered_text.replace('\n', ' ') # Reemplaza saltos de línea con espacios | |
return filtered_text | |
def convert_text_to_speech(text, model): | |
filtered_text = filter_text(text) | |
random_name = ''.join(random.choices(string.ascii_letters + string.digits, k=8)) + '.wav' | |
output_file = os.path.join(temp_audio_folder, random_name) | |
if os.path.isfile(piper_binary_path) and model in model_names: | |
model_path = os.path.join(model_folder, model_names[model]) | |
if os.path.isfile(model_path): | |
# Construye el comando para ejecutar Piper | |
command = f'echo "{filtered_text}" | "{piper_binary_path}" -m {model_path} -f {output_file}' | |
try: | |
subprocess.run(command, shell=True, check=True) | |
return output_file | |
except subprocess.CalledProcessError as e: | |
logging.error(f"Error al ejecutar el comando: {e}") | |
else: | |
logging.error(f"Modelo '{model}' no encontrado en la ubicación especificada.") | |
else: | |
logging.error(f"No se encontró el binario de Piper en la ubicación especificada o modelo no asignado.") | |
return None | |
# Define una función decoradora para restringir el acceso a la ruta /convert | |
def restrict_access(func): | |
def wrapper(*args, **kwargs): | |
# Verifica si la solicitud se hizo desde la página index.html | |
referer = request.headers.get("Referer") | |
if referer and referer.endswith("/"): | |
# Permite el acceso a la función si la solicitud proviene de la página index.html | |
return func(*args, **kwargs) | |
else: | |
# Devuelve un mensaje de error o redirecciona a otra página | |
return "Acceso no autorizado", 403 # Código de respuesta HTTP 403 - Forbidden | |
return wrapper | |
def index(): | |
model_options = list(model_names.keys()) | |
# Registra el contenido de la carpeta actual | |
logging.info("Contents of current folder: %s", os.listdir(file_folder)) | |
return render_template('index.html', model_options=model_options) | |
def convert_text(): | |
try: | |
text = request.form['text'] | |
model = request.form['model'] | |
output_file = convert_text_to_speech(text, model) | |
def remove_file(response): | |
try: | |
if output_file and os.path.exists(output_file): | |
os.remove(output_file) | |
logging.info("Audio file deleted: %s", output_file) | |
except Exception as error: | |
logging.error("Error deleting file: %s", error) | |
return response | |
if output_file: | |
with open(output_file, 'rb') as audio_file: | |
audio_content = audio_file.read() | |
audio_base64 = base64.b64encode(audio_content).decode('utf-8') | |
return jsonify({'audio_base64': audio_base64}) | |
else: | |
return jsonify({'error': 'Error al convertir texto a voz'}), 500 # Internal Server Error | |
except Exception as e: | |
logging.error("Error processing request: %s", e) | |
return jsonify({'error': 'Error interno del servidor'}), 500 # Internal Server Error | |
if __name__ == '__main__': | |
logging.info("Se está iniciando la aplicación.") | |
app.run(host='0.0.0.0', port=7860, debug=False) | |