Saltar al contenido principal
Jordi Izquierdo Montalbán
Blog

Por qué construí mi traductor en Tkinter y no en web

Decisiones de stack para una app de transcripción y traducción en tiempo real. Cuándo desktop nativo gana a una webapp moderna - y cuándo no.

4 min de lectura -

Cuando empecé a construir mi traductor en vivo, mi primer instinto fue la opción "moderna": Next.js, captura de audio con Web Audio API, Whisper en backend, WebSocket para latencia. Tres horas después de empezar el prototipo, lo abandoné y pasé a Python + Tkinter. La app lleva en producción siete meses.

Este post explica por qué - y, más importante, cuándo no debes tomar esta decisión.

El problema concreto

Necesitaba una app que:

  1. Capturara audio de un dispositivo Windows específico (CABLE Output, no el micrófono)
  2. Transcribiera localmente con GPU (Whisper CUDA en una GTX 1650)
  3. Tradujera a 8 idiomas
  4. Narrara la traducción con TTS (voz Helena, salida en HD65)
  5. Bajara automáticamente el volumen de Chrome/Firefox mientras hablaba
  6. Arrancara en silencio al inicio del sistema y se manejara con un atajo de teclado

Cada uno de esos puntos pesó en la decisión final. Vamos por ellos.

Punto 1 y 4: dispositivos de audio específicos

En el navegador, capturar audio requiere getUserMedia() que abre el selector estándar del browser. El usuario elige una vez y el sistema recuerda la elección. Cambiar el dispositivo activo desde código sin tocar la UI no se puede - es una limitación de seguridad del browser. Lo mismo para la salida de audio: audio.setSinkId() existe pero no enumera todos los dispositivos del sistema.

En Python con sounddevice lo controlas todo:

import sounddevice as sd
 
# Listar todos los dispositivos del sistema
print(sd.query_devices())
 
# Capturar de un dispositivo concreto sin tocar UI
sd.default.device = (DEVICE_ID, HD65_DEVICE_ID)  # input, output

Veredicto: para esto, desktop nativo gana sin discusión.

Punto 2: Whisper local

Whisper en navegador existe (whisper.cpp compilado a WebAssembly). Funciona - y es lento. La GPU dedicada acelera la inferencia 10-15x sobre WASM, pero el navegador no expone CUDA al JavaScript del usuario por motivos de seguridad. WebGPU está llegando, pero hoy no compite con CUDA puro.

En Python con openai-whisper es una línea:

import whisper
model = whisper.load_model("tiny", device="cuda")
result = model.transcribe(audio, language="es")

Una webapp tendría que mandar el audio al servidor → procesar → devolver. Latencia de red + carga del servidor + coste por minuto procesado. Para uso continuado, se paga la GPU varias veces al mes.

Punto 5: el ducking - donde la web se queda fuera

Esta fue la parte que me convenció definitivamente. Necesitaba que mientras la voz Helena habla la traducción, el volumen de Chrome bajara al 25%, y volviera al 100% al terminar. Sin esto la voz se solapa con el audio del navegador y no entiendes nada.

pycaw accede al Audio Session API de Windows vía COM:

from pycaw.pycaw import AudioUtilities
 
sessions = AudioUtilities.GetAllSessions()
for session in sessions:
    if session.Process and session.Process.name() in ["chrome.exe", "firefox.exe"]:
        session.SimpleAudioVolume.SetMasterVolume(0.25, None)

En navegador esto es imposible. Un sitio no puede controlar el volumen de otro proceso. Es una capacidad solo accesible a apps nativas con permisos de sistema.

Esta es la razón principal por la que la app vive en Tkinter.

Punto 6: atajo de teclado y arranque silencioso

Quería arrancar y pausar la transcripción con Ctrl+Alt+T, sin tocar el ratón ni cambiar de contexto mientras veía un vídeo.

Y quería que la app arrancara con Windows en modo silencioso (sin ventana, sin consola). Solución: un .vbs que lanza el .bat sin mostrar consola, programado en el inicio de Windows.

Una web no puede arrancar sola con el sistema operativo ni vivir en segundo plano así.

Cuándo SÍ habría elegido web

Si el problema fuera distinto - pongamos, una webapp de transcripción para usuarios casuales que quieren subir un MP3 y descargar la transcripción - la decisión correcta sería web:

  • Sin instalación (ventaja enorme para usuarios casuales)
  • Multi-plataforma sin esfuerzo (Windows, macOS, Linux, móvil)
  • Iteración más rápida (deploy en segundos, sin firmar binarios)
  • Mejor distribución (URL compartible, SEO, analytics)

Pero ese no era mi problema. Mi problema era una herramienta personal de uso diario, en Windows, que necesitaba acceso a APIs de sistema. La web pierde el 100% de los puntos críticos del problema.

Lo que aprendí

La elección entre desktop y web no es estética ni de modernidad. Es de capacidades:

NecesitasElige
Acceso a dispositivos de audio específicosDesktop
Hotkeys globalesDesktop
Control de otros procesos del sistemaDesktop
GPU local para inferencia pesadaDesktop
Distribución masiva sin instalaciónWeb
Multi-plataforma con poco esfuerzoWeb
Iteración rápidaWeb
Trabajo colaborativo / multi-usuarioWeb

Tkinter no está de moda. Python con UI nativa no es sexy en LinkedIn. Pero el día que pulsas Ctrl+Alt+T y todo el sistema responde como debe, mientras Chrome se calla solo, te das cuenta de que la decisión era correcta.

La regla de fondo: elige el stack según las capacidades que necesitas, no según el stack que querrías aprender. Las dos cosas son legítimas, pero no se mezclan.

Compartir