javascript

Texto a voz con JavaScript y la API de speechSynthesis

En este post vamos a ver cómo usar la API de speechSynthesis con JavaScript, presente en la mayoría de los navegadores web. Esto permitirá hacer un conversor de texto a voz con JS, sin librerías externas ni frameworks.

La tecnología TTS, Text to speech, texto a voz o síntesis de voz es algo que permite convertir texto a habla, es decir, ingresamos el texto y luego escuchamos una voz que lo “lee”.

Conversor texto a audio con JavaScript

Gracias a esta API de speechSynthesis con JavaScript podemos agregar más funcionalidades a nuestras aplicaciones web, y hay buenas noticias, pues funciona (al momento de escribir esto) en Chrome, Firefox y Edge. También en Android usando Chrome y Firefox.

Veamos entonces cómo consumir esta API.

Código completo y demostración

Puedes ver el vídeo en mi canal de YT (si vas por ahí, suscríbete): https://youtu.be/BlUOl6ze2Aw

También puedes probar la webapp directamente aquí, y ver el código fuente completo en el repositorio de GitHub (durante el post mostraré solamente las partes más importantes).

Comprobar si existe la API de speechSynthesis

Para saber si existe la API en el navegador del usuario comprobamos que "speechSynthesis" sea una propiedad de window, usamos el operador in aunque podríamos usar un if(window.speechSynthesis)

See the gist on github.

Pequeña aclaración de window.speechSynthesis y speechSyntesis

Al inicio comprobamos que la variable esté en window usando in, pero más tarde al usar la API no usamos window.speechSynthesis, sino simplemente speechSynthesis.

Esto es porque cualquier cosa que le pertenece a window es global, así que podemos usar a speechSynthesis sin acceder a window.

Las voces

Dependiendo del navegador web, idiomas, sistemas operativos y todas esas cosas habrán más o menos lenguajes. Por ejemplo, Chrome tiene más idiomas que los que ofrece Edge. Desconozco la razón, pero las voces no siempre serán las mismas.

Para obtener las voces que podemos usar llamamos a getVoices. Eso regresará un arreglo de objetos que tienen la siguiente estructura:

See the gist on github.

Al indicarle a speechSynthesis que “hable” debemos indicarle el idioma obtenido de esta lista de getVoices.

En el ejemplo obtenemos las voces y las ponemos en un select.

See the gist on github.

El evento onvoiceschanged

Las voces, en algunos navegadores, son cargadas de manera asíncrona para no interrumpir el hilo principal ni congelar la app.

Por ello es que en ocasiones getVoices devolverá un arreglo vacío, pues todavía no hay voces. Para asegurarnos de que hay voces esperamos el evento onvoiceschanged:

See the gist on github.

Tal vez te preguntes ¿por qué llamar a getVoices dos veces, no se supone que debemos llamarlo hasta que el evento se dispare? sí y no. JavaScript y los navegadores son caprichosos, así que debemos aplicar trucos.

Por ejemplo, en algunos navegadores el evento no se dispara hasta que se intenta usar la API, es como una paradoja porque, ¿cómo vas a usar la API de TTS si estás esperando el evento, pero para que se dispare el evento debes usar la API?

Así que intentamos cargar las voces, el navegador dirá: oh, quieres cargar voces, seguramente quieres usar la API de speechSynthesis así que voy a cargarla y a desencadenar el evento.

Por otro lado, en algunos navegadores como Safari (me gusta llamarlo El nuevo internet explorer, porque da tantos problemas ahora como Explorer en su tiempo) el evento no existe, así que por eso el código que comprueba y escucha.

Parla

Después de obtener las voces podemos construir un objeto que es instancia de SpeechSynthesisUtterance.

Tiene algunos valores que le establecemos después de crearlo, por ejemplo, la voz o el volumen. A continuación trato de explicar los valores:

  • text: el texto que convertirá a audio.
  • voice: la voz en la que “hablará”.
  • rate: velocidad con la que se dice el texto. Puede ir desde 0.1 hasta 10. Entre más alto sea el valor, más alta la velocidad. Si se pone muy bajo, la reproducción será lenta.
  • pitch: tono de voz. Puede ir desde 0 hasta 2, se permiten los valores flotantes.
  • volume: el volumen. Puede estar entre 0 y 1, se permiten los valores flotantes.

Después de crear nuestro objeto llamamos al método speak y entonces el texto será convertido a audio.

See the gist on github.

El código es llamado desde el click de un botón.

Limitaciones

Según las investigaciones y pruebas que he hecho no se puede convertir texto a voz sin interacción del usuario. Es decir, no se puede usar inmediatamente al cargar la página, tiene que ser en el click de un botón o algo con lo que el usuario haga interacción.

Me parece que esa limitante es para no entrar a una página y escuchar “Has ganado un premio” o cosas de esas. Sigue las mismas razones por las que un vídeo no puede tener sonido sin interacción del usuario.

Otra limitante es que el audio generado a partir del texto no puede ser guardado como un archivo.

Conclusión

Ahora el chiste de:

¿Puedes hacer que el sistema diga “Bienvenido” y después mi nombre, al iniciar sesión?

Ya no será más un chiste.

Con esto podemos agregar unas pequeñas características a nuestras webapps. Esperemos que estas APIs evolucionen y se queden, porque aunque existen todavía son calificadas como experimentales.

Mira más cosas sobre JavaScript en mi blog.

Encantado de ayudarte


Estoy disponible para trabajar en tu proyecto, modificar el programa del post o realizar tu tarea pendiente, no dudes en ponerte en contacto conmigo.

No te pierdas ninguno de mis posts

Suscríbete a mi canal de Telegram para recibir una notificación cuando escriba un nuevo tutorial de programación.
parzibyte

Programador freelancer listo para trabajar contigo. Aplicaciones web, móviles y de escritorio. PHP, Java, Go, Python, JavaScript, Kotlin y más :) https://parzibyte.me/blog/software-creado-por-parzibyte/

Ver comentarios

  • Sigo sin entender por que hacen esto "mensaje.voice = vocesDisponibles[$voces.value];",a osea se que quieres cambiar la voz pero no entiendo el $voces.value ya que no veo declarado $voces antes.

Entradas recientes

Imprimir PDF con Bot de Telegram

La impresión de un PDF en cualquier impresora se puede automatizar con un bot de…

3 días hace

Enviar mensaje con bot de Telegram usando JavaScript (lado del cliente)

Hoy te enseñaré cómo enviar un mensaje a un usuario desde un bot de Telegram…

4 días hace

PHP: incrustar imagen en base64

El día de hoy te enseñaré algo muy sencillo pero útil al programar con PHP:…

4 días hace

Plugin ESC POS – Actualización 3.4.0: imprimir HTML

El plugin para imprimir en impresoras térmicas alcanza hoy su versión 3.4.0 agregando soporte para…

5 días hace

JavaScript (lado del cliente): leer pixeles de imagen

En ocasiones es necesario leer los pixeles y colores de una imagen con JavaScript del…

2 semanas hace

PHP y JavaScript: llenar select con AJAX

Siguiendo con los tutoriales de listas desplegables o select con JavaScript, vamos a ver cómo…

2 semanas hace

Esta web usa cookies.