SpeechSynthesisUtterance: síntesis de voz con JavaScript nativo | Tutorial completo

- Andrés Cruz - EN In english

SpeechSynthesisUtterance: síntesis de voz con JavaScript nativo | Tutorial completo

Ver demo

Desde que asistentes como Siri, Google Assistant o Cortana se volvieron parte de nuestra vida diaria, la síntesis de voz dejó de ser una curiosidad para convertirse en una característica real y esperada en muchas aplicaciones web. Lo interesante es que, gracias a la Web Speech API de HTML5, JavaScript nos ofrece una API nativa para trabajar con síntesis de voz (text-to-speech o TTS) de manera sencilla, sin necesidad de librerías externas ni dependencias de terceros.

El sintetizador de voz nativo en JavaScript permite que cualquier texto se reproduzca directamente en el navegador, con control sobre el idioma, el tono y la velocidad. Lo que más me sorprendió cuando lo usé por primera vez fue lo poco que se necesita para tener un ejemplo funcional: apenas dos líneas de código.

Cómo empezar con la Speech Synthesis API en JavaScript

Crear tu primer objeto SpeechSynthesisUtterance

La clase SpeechSynthesisUtterance es el núcleo de todo esto: captura un texto y lo prepara para ser convertido en audio. Crear un objeto e iniciarlo es tan directo como esto:

var speechMessage = new SpeechSynthesisUtterance('Hola, mundo!');
window.speechSynthesis.speak(speechMessage);

Este mínimo ejemplo funciona de inmediato en navegadores modernos. Primero creamos una instancia de SpeechSynthesisUtterance pasándole el texto como parámetro, y luego lo procesamos a través de la interfaz window.speechSynthesis, que es quien realmente le da voz al navegador invocando el método speak().

Reproducir texto dinámico: ejemplo básico

Para leer texto que viene de una variable en lugar de un literal fijo, basta con asignarlo al crear la instancia:

var texto = "Bienvenido a mi aplicación web";
var speechMessage = new SpeechSynthesisUtterance(texto);
window.speechSynthesis.speak(speechMessage);

Esto abre la puerta a aplicaciones interactivas donde el contenido puede leer mensajes personalizados al usuario, como notificaciones, resultados de formularios o cualquier texto generado en tiempo real.

Propiedades esenciales de SpeechSynthesisUtterance

La clase SpeechSynthesisUtterance expone un conjunto de propiedades que permiten personalizar exactamente cómo el navegador hablará. Entre las más utilizadas están:

SpeechSynthesisUtterance.text

Es la propiedad más importante de todas. Permite establecer u obtener el texto que el navegador leerá en voz alta. También puedes asignarlo directamente en el constructor o modificarlo después:

speechMessage.text = "Texto actualizado dinámicamente";

SpeechSynthesisUtterance.lang

Permite especificar el idioma de la síntesis usando códigos de idioma estándar BCP 47. En mis pruebas, cambiar el idioma mejora notablemente la naturalidad de la pronunciación:

speechMessage.lang = 'es-ES'; // Español de España
speechMessage.lang = 'es-MX'; // Español de México
speechMessage.lang = 'en-US'; // Inglés americano

SpeechSynthesisUtterance.volume

Controla el volumen de la voz. Acepta un valor flotante entre 0 (silencio) y 1 (máximo). Útil para equilibrar el audio con otros sonidos de la página:

speechMessage.volume = 0.8; // 80% del volumen máximo

SpeechSynthesisUtterance.pitch

Establece el tono de la voz. El valor es un flotante entre 0 (el más grave) y 2 (el más agudo). El valor por defecto es 1:

speechMessage.pitch = 1.2; // tono ligeramente más alto que el normal

SpeechSynthesisUtterance.rate

Controla la velocidad de la locución. Acepta valores entre 0.1 (muy lento) y 10 (muy rápido), con 1 como velocidad normal. Bajarlo un poco a 0.9 puede resultar más cómodo para contenido educativo o de tutoriales:

speechMessage.rate = 0.9; // velocidad ligeramente más lenta

SpeechSynthesisUtterance.voice

Permite asignar una voz específica de las que el navegador tenga disponibles. Las voces se obtienen de forma asíncrona mediante window.speechSynthesis.getVoices(). Es importante escuchar el evento onvoiceschanged porque la lista de voces puede no estar disponible de forma inmediata:

window.speechSynthesis.onvoiceschanged = function() {
    var voices = window.speechSynthesis.getVoices();
    speechMessage.voice = voices[0]; // selecciona la primera voz disponible
};

Eventos y control del flujo de la síntesis de voz

La API también expone eventos que permiten reaccionar a los distintos momentos del ciclo de vida de la reproducción. Los más comunes son onstart y onend, útiles para sincronizar animaciones, indicadores visuales o cualquier efecto con la voz:

speechMessage.onstart = function(e) {
    console.log('Reproducción iniciada...');
};

speechMessage.onend = function(e) {
    console.log('Reproducción finalizada.');
};

Personalmente los usé en un proyecto de tutoriales interactivos para activar un icono animado mientras el navegador hablaba, y el resultado fue muy bueno en términos de experiencia de usuario.

Otros eventos útiles para proyectos avanzados

Además de onstart y onend, la API expone otros eventos que permiten un control más granular del flujo de reproducción:

  • onerror: se dispara si ocurre un error durante la síntesis. Ideal para manejar fallos sin romper la experiencia del usuario.
  • onpause y onresume: detectan cuando la reproducción es pausada o reanudada, lo que permite implementar controles de play/pausa en la UI.
  • onboundary: se dispara en cada límite de palabra o frase. Muy útil para resaltar el texto que se está leyendo en tiempo real (efecto karaoke).

Puedes consultar la lista completa de eventos en la documentación oficial de la Web Speech API.

La otra mitad de la Web Speech API: reconocimiento de voz

En una entrada anterior hablamos sobre la otra cara de la Web Speech API: el reconocimiento de voz con SpeechRecognition(), que permite a tus aplicaciones escuchar al usuario a través del micrófono del dispositivo y transcribir lo que dice según el idioma configurado:

Si el reconocimiento de voz es el "oído" del navegador, la síntesis de voz con SpeechSynthesisUtterance y window.speechSynthesis es su "boca". Juntas, forman el conjunto completo de la Web Speech API.

Soporte en navegadores modernos

La Web Speech API tiene buen soporte en los principales navegadores modernos: Chrome, Firefox, Edge y Safari la implementan, aunque las voces disponibles pueden variar según el sistema operativo y el idioma instalado. Antes de usarla, conviene verificar el soporte con una simple comprobación:

if ('speechSynthesis' in window) {
    // El navegador soporta la Speech Synthesis API
    console.log('¡Listo para hablar!');
} else {
    console.log('La API no es soportada en este navegador');
}

Es buena práctica incluir siempre esta verificación antes de inicializar cualquier funcionalidad de TTS, para evitar errores en navegadores que aún no la implementan o que la tienen desactivada.

Consejos para mejorar la experiencia del usuario

  • Ofrece al usuario la posibilidad de seleccionar entre las voces disponibles usando window.speechSynthesis.getVoices().
  • Ajusta el volume y el rate según el tipo de contenido: más lento para texto educativo, más rápido para notificaciones cortas.
  • Evita textos demasiado largos en una sola llamada a speak(). Algunos navegadores tienen límites de caracteres; divide el contenido en fragmentos si es necesario.
  • Usa el evento onboundary para resaltar visualmente el texto que se está leyendo y mejorar la accesibilidad.

Ejemplo completo de síntesis de voz en JavaScript

Un ejemplo encapsulado en una función reutilizable es la forma más limpia de integrar TTS en cualquier proyecto:

function hablar(texto, idioma, velocidad, tono) {
    if (!('speechSynthesis' in window)) {
        console.warn('La Speech Synthesis API no está disponible.');
        return;
    }

    var speechMessage = new SpeechSynthesisUtterance(texto);
    speechMessage.lang   = idioma    || 'es-ES';
    speechMessage.rate   = velocidad || 1;
    speechMessage.pitch  = tono      || 1;
    speechMessage.volume = 1;

    speechMessage.onstart = function() { console.log('Hablando...'); };
    speechMessage.onend   = function() { console.log('Listo.'); };

    window.speechSynthesis.speak(speechMessage);
}

// Uso:
hablar("¡Hola! Esto es un ejemplo dinámico.", 'es-ES', 0.9, 1.1);

En mi experiencia, permitir que el usuario ajuste el tono y la velocidad directamente desde la interfaz aumenta significativamente la accesibilidad y el engagement en proyectos educativos o de tutoriales interactivos.

Ver demo en vivo

Preguntas frecuentes sobre síntesis de voz en JavaScript

  1. ¿Qué navegadores soportan la Speech Synthesis API?
    1. Chrome, Firefox, Edge y Safari soportan window.speechSynthesis, aunque las voces disponibles y su calidad pueden variar según el sistema operativo. Chrome en Android y escritorio tiene el soporte más amplio.
  2. ¿Cómo puedo cambiar el idioma o la voz predeterminada?
    1. Usa la propiedad lang de SpeechSynthesisUtterance para el idioma (por ejemplo, 'es-ES' o 'en-US'), y la propiedad voice con un objeto obtenido de window.speechSynthesis.getVoices() para seleccionar una voz específica.
  3. ¿Puedo controlar la velocidad, el volumen y el tono de la voz?
    1. Sí. Usa rate para la velocidad (entre 0.1 y 10), volume para el volumen (entre 0 y 1), y pitch para el tono (entre 0 y 2).
  4. ¿Es posible reproducir texto dinámico desde una variable en JavaScript?
    1. Sí, simplemente asigna la variable al constructor de SpeechSynthesisUtterance o a su propiedad text, y llama a window.speechSynthesis.speak() con el objeto.
  5. ¿Cómo detener o pausar la síntesis de voz en JavaScript?
    1. Usa window.speechSynthesis.cancel() para detener completamente la reproducción, window.speechSynthesis.pause() para pausarla y window.speechSynthesis.resume() para reanudarla.

Aprende a usar la API SpeechSynthesisUtterance de JavaScript para convertir texto a voz sin librerías. Controla lang, pitch, rate, volume y voice con ejemplos de código listos para usar.


Únete a la comunidad de desarrolladores que han decidido dejar de picar código y empezar a construir productos reales. Recibe mis mejores trucos de arquitectura cada semana:

Acepto recibir anuncios de interes sobre este Blog.