salomonsky commited on
Commit
b179e87
verified
1 Parent(s): 80771fe

Upload audio_utils.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. audio_utils.py +130 -0
audio_utils.py ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pygame
2
+ import uuid
3
+ from pathlib import Path
4
+ import threading
5
+ import edge_tts
6
+ import asyncio
7
+ from gtts import gTTS
8
+ import shutil
9
+ import time
10
+
11
+ class AudioUtils:
12
+ AVAILABLE_MODELS = {
13
+ 'EDGE': {
14
+ 'name': "es-MX-JorgeNeural", # Voz en espa帽ol mexicano
15
+ 'description': "Voz de Edge TTS",
16
+ 'type': 'cloud',
17
+ 'fallback': 'gTTS'
18
+ },
19
+ 'VITS': {
20
+ 'name': "tts_models/es/css10/vits",
21
+ 'description': "Voz masculina clara y natural",
22
+ 'type': 'local',
23
+ 'fallback': 'gTTS'
24
+ },
25
+ 'gTTS': {
26
+ 'name': "google_tts",
27
+ 'description': "Google Text-to-Speech",
28
+ 'type': 'cloud'
29
+ }
30
+ }
31
+
32
+ def __init__(self, model_name='EDGE'):
33
+ self.is_speaking = False
34
+ self.should_stop = False
35
+ self.temp_dir = Path("static/temp_audio")
36
+ self.temp_dir.mkdir(parents=True, exist_ok=True)
37
+ self.current_model = model_name
38
+ self.play_lock = threading.Lock()
39
+ self.init_audio()
40
+ self.cleanup_old_files()
41
+
42
+ def init_audio(self):
43
+ try:
44
+ pygame.init()
45
+ pygame.mixer.init(frequency=44100, size=-16, channels=2, buffer=4096)
46
+ return True
47
+ except Exception as e:
48
+ print(f"Error inicializando audio: {e}")
49
+ return False
50
+
51
+ async def generate_edge_tts(self, text, output_file):
52
+ try:
53
+ communicate = edge_tts.Communicate(text, self.AVAILABLE_MODELS['EDGE']['name'])
54
+ await communicate.save(str(output_file))
55
+ return True
56
+ except Exception as e:
57
+ print(f"Error con Edge TTS: {e}")
58
+ return False
59
+
60
+ def text_to_speech(self, text, return_file=False):
61
+ if not text:
62
+ return None
63
+
64
+ try:
65
+ filename = f"{uuid.uuid4()}"
66
+ temp_file = self.temp_dir / filename
67
+
68
+ print(f"Generando audio con modelo {self.current_model}")
69
+
70
+ if self.current_model == 'EDGE':
71
+ temp_file = temp_file.with_suffix('.mp3')
72
+ # Ejecutar Edge TTS de manera as铆ncrona
73
+ loop = asyncio.new_event_loop()
74
+ asyncio.set_event_loop(loop)
75
+ success = loop.run_until_complete(self.generate_edge_tts(text, temp_file))
76
+ loop.close()
77
+
78
+ if not success:
79
+ print("Fallback a gTTS")
80
+ temp_file = temp_file.with_suffix('.mp3')
81
+ tts = gTTS(text=text, lang='es', slow=False)
82
+ tts.save(str(temp_file))
83
+ else: # gTTS como fallback por defecto
84
+ temp_file = temp_file.with_suffix('.mp3')
85
+ tts = gTTS(text=text, lang='es', slow=False)
86
+ tts.save(str(temp_file))
87
+
88
+ if not temp_file.exists():
89
+ raise Exception(f"El archivo no se gener贸: {temp_file}")
90
+
91
+ print(f"Archivo generado exitosamente: {temp_file}")
92
+ return temp_file.name if return_file else temp_file
93
+
94
+ except Exception as e:
95
+ print(f"Error cr铆tico en text_to_speech: {e}")
96
+ import traceback
97
+ traceback.print_exc()
98
+ return None
99
+
100
+ def play_audio(self, file_path):
101
+ try:
102
+ with self.play_lock:
103
+ if pygame.mixer.music.get_busy():
104
+ pygame.mixer.music.stop()
105
+
106
+ pygame.mixer.music.load(str(file_path))
107
+ pygame.mixer.music.play()
108
+
109
+ while pygame.mixer.music.get_busy():
110
+ if self.should_stop:
111
+ pygame.mixer.music.stop()
112
+ self.should_stop = False
113
+ break
114
+ pygame.time.Clock().tick(10)
115
+ except Exception as e:
116
+ print(f"Error reproduciendo audio: {e}")
117
+
118
+ def stop_audio(self):
119
+ self.should_stop = True
120
+
121
+ def cleanup_old_files(self, max_age_minutes=5):
122
+ try:
123
+ current_time = time.time()
124
+ for file in self.temp_dir.glob("*"):
125
+ if file.is_file():
126
+ file_age_minutes = (current_time - file.stat().st_mtime) / 60
127
+ if file_age_minutes > max_age_minutes:
128
+ file.unlink()
129
+ except Exception as e:
130
+ print(f"Error limpiando archivos temporales: {e}")