← Proyectos

Simple TTS

Extensión de Chrome y Edge que lee en voz alta cualquier texto de una web con las voces del propio navegador. Lee la selección o el artículo entero, tiene cola de lectura, tres modos de reproductor, resaltado de lo que se está leyendo y estadísticas. Sin servidores, sin APIs externas y gratis.

Un artículo leyéndose en voz alta, con el reproductor flotante y la palabra que suena resaltada en la página
El reproductor flotante con el texto, el progreso, el tiempo restante y los controlesLos ajustes de velocidad, tono, volumen, modo de reproductor, tema e idiomaEl reproductor en una ventana independienteSimple TTS leyendo un artículo en modo oscuro
servidores o APIs externas
0
servidores o APIs externas
tests (Vitest)
112
tests (Vitest)
idiomas
6
idiomas
versión
2.4.6
versión

Qué hace

  • Leer lo que selecciones. Clic derecho y «Leer texto seleccionado», o Alt+R.
  • Leer el artículo entero. Clic derecho en la página y «Leer artículo completo»: busca el cuerpo del artículo y deja fuera menús, barras laterales y anuncios.
  • Cola de lectura. «Agregar a la cola» suma otro texto, de la misma página o de otra, para que suene justo después.
  • Tres modos de reproductor. Flotante sobre la página (se mueve y se redimensiona), en una ventana independiente o en segundo plano, sin nada en pantalla.
  • Las voces del navegador. Un buscador agrupa las voces por idioma y deja oírlas antes de elegir. En Edge están sus voces naturales; en Chrome, las de Google.
  • Velocidad, tono y volumen. De 0,5× a 4×, también con atajo de teclado.
  • Seguir la lectura. La palabra que suena se resalta en el reproductor y, si quieres, también en la página, que se desplaza sola para no perderla.
  • Progreso y tiempo restante, y al volver a abrirla retoma donde lo dejaste.
  • Estadísticas. Sesiones, palabras leídas, tiempo escuchado y voz más usada.
  • En seis idiomas, con tema claro, oscuro o automático.

Cómo está hecho

Sin motor de voz propio

Toda la voz sale de chrome.tts, la API de síntesis del navegador. No hay servidor ni API externa: el texto no pasa por ningún servidor mío, y las voces disponibles son las que ya trae Chrome, Edge o el sistema.

Manifest V3 con WXT y Vue

WXT genera el manifest y empaqueta cada pieza por separado. El service worker lleva el estado y el motor de lectura. El reproductor flotante es un componente Vue montado dentro de un Shadow DOM, para que los estilos de la página no lo rompan. El popup y la ventana independiente son páginas Vue que hablan con el service worker por mensajes.

Lectura frase a frase

El texto se trocea en frases con Intl.Segmenter, guardando dónde empieza cada una. Así se puede saltar a la frase anterior o a la siguiente, cambiar la velocidad sin volver al principio y saber en todo momento qué parte del texto suena.

Resaltado sin tocar la página

El resaltado en la página usa la CSS Custom Highlight API: marca rangos de texto sin insertar ni un solo elemento en el HTML de la web.

Problemas que resolví

  • El service worker se dormía a mitad de un artículo largo. Un documento offscreen le manda una señal cada 20 segundos mientras hay lectura, y se cierra al pausar o parar.
  • Leía la frase del día anterior. Tras reiniciar el ordenador, el primer «Leer texto seleccionado» empezaba antes de que terminara de restaurarse el estado guardado, y ese estado viejo pisaba al nuevo. Ahora todos los puntos de entrada esperan a la restauración, y un test reproduce el orden exacto de eventos.
  • La voz se quedaba muda sin avisar. Un vigilante compara el progreso con lo que debería tardar la frase; si se atasca, la repite hasta tres veces y después pasa a la siguiente.
  • El resaltado se desfasaba de lo que se oía. El texto seleccionado y el HTML de la página no tienen los mismos espacios ni saltos de línea. Ahora se comparan sin tenerlos en cuenta, se realinean cuando se separan y se parte de donde estaba tu selección.
  • Cuatro etapas en ocho meses. Empezó en JavaScript sin framework, pasó a Vue con Vite, luego a WXT y por último a TypeScript con tests. Cada migración trajo sus problemas, como el CORS del servidor de desarrollo o montar Vue dentro de un Shadow DOM.

Stack

WXTVue 3TypeScriptManifest V3Chrome TTS APIOffscreen APIShadow DOMCSS Custom Highlight APIIntl.SegmenterChrome Storage (sync)Chrome i18nVitestPlaywright