File size: 4,653 Bytes
dcc2c7c
 
 
 
 
 
0dd2770
 
54412ba
dcc2c7c
 
 
 
 
0dd2770
631c13e
 
dcc2c7c
 
7b23cd3
 
 
 
 
 
dcc2c7c
 
 
 
 
 
 
 
811ad8f
0dd2770
dcc2c7c
 
0dd2770
dcc2c7c
0dd2770
dcc2c7c
 
811ad8f
dcc2c7c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54412ba
5e3bfe7
dcc2c7c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5e3bfe7
631c13e
 
dcc2c7c
 
 
631c13e
 
 
dcc2c7c
631c13e
dcc2c7c
 
54412ba
dcc2c7c
 
 
 
 
 
 
 
 
 
 
54412ba
 
dcc2c7c
54412ba
dcc2c7c
54412ba
 
dcc2c7c
 
 
51e2649
631c13e
dcc2c7c
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
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 = os.path.join(file_folder, 'temp_audio')
temp_audio_folder= "/home/app/temp_audio/"
#model_folder = os.path.join(file_folder, 'models')
model_folder = "/home/app/models/"
#piper_binary_path = os.path.join(file_folder, 'piper', 'piper')
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 = text.replace('(', ',').replace(')', ',').replace('?', ',').replace('¿', ',').replace(':', ',')
    filtered_text = re.sub(r'[^\w\s,.\(\):\u00C0-\u00FF]', '', filtered_text)
    filtered_text = filtered_text.replace('\n', ' ')
    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):
        if 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}")
                    return None
            else:
                logging.error(f"Modelo '{model}' no encontrado en la ubicación especificada.")
                return None
        else:
            logging.error(f"No se ha asignado un modelo para el nombre '{model}'.")
            return None
    else:
        logging.error(f"No se encontró el binario de Piper en la ubicación especificada.")
        return None

# Define una función decoradora para restringir el acceso a la ruta /convert
def restrict_access(func):
    @wraps(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

@app.route('/')
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)

@app.route('/convert', methods=['POST'])
@restrict_access
def convert_text():
    text = request.form['text']
    model = request.form['model']
    output_file = convert_text_to_speech(text, model)

    @after_this_request
    def remove_file(response):
        try:
            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 is not None:
        with open(output_file, 'rb') as audio_file:
            audio_content = audio_file.read()

        audio_base64 = base64.b64encode(audio_content).decode('utf-8')

        response = jsonify({'audio_base64': audio_base64})
    else:
        response = jsonify({'error': 'Error al convertir texto a voz'})

    return response

if __name__ == '__main__':
    logging.info("Se está iniciando la aplicación.")
    app.run(host='0.0.0.0', port=7860, debug=False)