123 lines
3.9 KiB
Python
123 lines
3.9 KiB
Python
"""
|
|
aviso_sonoro.py — Reproduce un aviso de voz al terminar una tarea.
|
|
|
|
Uso: python scripts/aviso_sonoro.py [tipo]
|
|
Tipos:
|
|
fin (defecto) -> voz de aviso normal
|
|
ok -> aviso normal
|
|
error -> aviso normal
|
|
importante -> voz destacada
|
|
dalia <frase> -> sintetiza y reproduce con edge-tts voz es-MX-DaliaNeural
|
|
(gratis e ilimitado). Voz preferida del usuario para
|
|
respuestas cortas.
|
|
toca <frase> -> sintetiza y reproduce con edge-tts (misma voz Dalia)
|
|
alarma <frase> -> sintetiza y reproduce alarma con prioridad alta
|
|
|
|
Reproduccion: usa PowerShell + WPF MediaPlayer (System.Windows.Media.MediaPlayer,
|
|
PresentationCore), fiable para MP3 en Windows, en modo STA (apartment STA).
|
|
"""
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
import tempfile
|
|
|
|
BASE = os.path.dirname(os.path.abspath(__file__))
|
|
SND = os.path.join(BASE, "sounds")
|
|
|
|
# Voz por defecto: Dalia (edge-tts, gratis)
|
|
DEFAULT_VOICE = "es-MX-DaliaNeural"
|
|
DEFAULT_RATE = "-8%"
|
|
|
|
|
|
def reproducir_ps(ruta):
|
|
"""Reproduce un MP3 via PowerShell + WPF MediaPlayer."""
|
|
r = ruta.replace("'", "''")
|
|
ps = (
|
|
"Add-Type -AssemblyName PresentationCore; "
|
|
"Add-Type -AssemblyName WindowsBase; "
|
|
"$p = New-Object System.Windows.Media.MediaPlayer; "
|
|
"$p.Open([Uri]'%s'); "
|
|
"$p.Play(); "
|
|
"Start-Sleep -Seconds 5; "
|
|
"$p.Stop(); $p.Close()" % r
|
|
)
|
|
subprocess.run(
|
|
["powershell", "-NoProfile", "-STA", "-Command", ps],
|
|
capture_output=True, timeout=20,
|
|
)
|
|
|
|
|
|
def sintetizar_dalia(texto, salida=None):
|
|
"""Sintetiza texto con edge-tts (gratis/ilimitado) usando la voz Dalia.
|
|
Voz preferida del usuario para respuestas cortas de OpenCode."""
|
|
import asyncio
|
|
try:
|
|
import edge_tts
|
|
except ImportError:
|
|
print("[aviso_sonoro] ERROR: no esta instalado edge-tts (pip install edge-tts)")
|
|
sys.exit(4)
|
|
if salida is None:
|
|
salida = os.path.join(SND, "aviso_dalia.mp3")
|
|
try:
|
|
asyncio.run(edge_tts.Communicate(
|
|
texto, DEFAULT_VOICE, rate=DEFAULT_RATE).save(salida))
|
|
except Exception as e:
|
|
print("[aviso_sonoro] ERROR edge-tts: %s" % e)
|
|
sys.exit(5)
|
|
reproducir_ps(salida)
|
|
return salida
|
|
|
|
|
|
def sintetizar_voz(texto, voz=None, rate=None, salida=None):
|
|
"""Sintetiza texto con edge-tts usando la voz indicada."""
|
|
import asyncio
|
|
try:
|
|
import edge_tts
|
|
except ImportError:
|
|
print("[aviso_sonoro] ERROR: no esta instalado edge-tts")
|
|
sys.exit(4)
|
|
voz = voz or DEFAULT_VOICE
|
|
rate = rate or DEFAULT_RATE
|
|
if salida is None:
|
|
salida = os.path.join(SND, "temporal_voz.mp3")
|
|
try:
|
|
asyncio.run(edge_tts.Communicate(
|
|
texto, voz, rate=rate).save(salida))
|
|
except Exception as e:
|
|
print("[aviso_sonoro] ERROR edge-tts: %s" % e)
|
|
sys.exit(5)
|
|
reproducir_ps(salida)
|
|
return salida
|
|
|
|
|
|
def main():
|
|
args = sys.argv[1:]
|
|
|
|
if args and args[0] == "dalia":
|
|
frase = args[1] if len(args) > 1 else "Hola."
|
|
salida = os.path.join(SND, "aviso_dalia.mp3")
|
|
rut = sintetizar_dalia(frase, salida)
|
|
print("[aviso_sonoro] dalia -> %s" % rut)
|
|
return
|
|
|
|
if args and args[0] == "toca":
|
|
frase = args[1] if len(args) > 1 else "Aviso."
|
|
salida = os.path.join(SND, "temporal_toca.mp3")
|
|
rut = sintetizar_dalia(frase, salida)
|
|
print("[aviso_sonoro] toca -> %s" % rut)
|
|
return
|
|
|
|
if args and args[0] == "alarma":
|
|
frase = args[1] if len(args) > 1 else "Alerta de sistema."
|
|
salida = os.path.join(SND, "temporal_alarma.mp3")
|
|
rut = sintetizar_voz(frase, voz="es-ES-AlvaroNeural", rate="-5%", salida=salida)
|
|
print("[aviso_sonoro] alarma -> %s" % rut)
|
|
return
|
|
|
|
tipo = args[0] if args else "fin"
|
|
print("[aviso_sonoro] %s" % tipo)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|