Cómo crear una aplicación de reconocimiento de voz simple

“En este período de 10 años, creo que no solo usaremos el teclado y el mouse para interactuar, sino que durante ese tiempo habremos perfeccionado el reconocimiento de voz y la salida de voz lo suficientemente bien como para que se conviertan en una parte estándar del interfaz." - Bill Gates, 1 de octubre de 1997

La tecnología ha recorrido un largo camino y, con cada nuevo avance, la raza humana se apega más a ella y anhela estas nuevas funciones geniales en todos los dispositivos.

Con la llegada de Siri, Alexa y Google Assistant, los usuarios de tecnología han anhelado el reconocimiento de voz en su uso diario de Internet. En esta publicación, cubriré cómo integrar el reconocimiento de voz nativo y la síntesis de voz en el navegador utilizando la API de JavaScript WebSpeech.

Según los documentos web de Mozilla:

La API Web Speech le permite incorporar datos de voz en aplicaciones web. La API de Web Speech tiene dos partes: SpeechSynthesis (Text-to-Speech) y SpeechRecognition (Reconocimiento de voz asincrónico).

Requisitos que necesitaremos para construir nuestra aplicación

Para esta sencilla aplicación de reconocimiento de voz, trabajaremos con solo tres archivos que residirán en el mismo directorio:

  • index.html que contiene el HTML de la aplicación.
  • style.css que contiene los estilos CSS.
  • index.js que contiene el código JavaScript.

Además, necesitamos tener algunas cosas en su lugar. Son los siguientes:

  • Conocimientos básicos de JavaScript.
  • Un servidor web para ejecutar la aplicación. El servidor web para Chromeserá suficiente para este propósito.

Configurar nuestra aplicación de reconocimiento de voz

Comencemos configurando HTML y CSS para la aplicación. A continuación se muestra el marcado HTML:

      Speech Recognition  //soundbible.com/1598-Electronic-Chime.html -->

Aquí está el estilo CSS que lo acompaña:

body { background: #1e2440; color: #f2efe2; font-size: 16px; font-family: 'Kaushan Script', cursive; font-family: 'Shadows Into Light', cursive; } .container { position: relative; border: 1px solid #f2efe2; width: 40vw; max-width: 60vw; margin: 0 auto; border-radius: 0.1rem; background: #f2efe2; padding: 0.2rem 1rem; color: #1e2440; overflow: scroll; margin-top: 10vh; } .text-box { max-height: 70vh; overflow: scroll; } .text-box:focus { outline: none; } .text-box p { border-bottom: 1px dotted black; margin: 0px !important; } .fa { color: white; background: #1e2440; border-radius: 50%; cursor: pointer; margin-top: 1rem; float: right; width: 2rem; height: 2rem; display: flex !important; align-items: center; justify-content: center; } @media (max-width: 768px) { .container { width: 85vw; max-width: 85vw; } .text-box { max-height: 55vh; } }

Copiar el código anterior debería resultar en algo similar a esto:

Encendido de nuestra aplicación de reconocimiento de voz con la API WebSpeech

En el momento de escribir este artículo, la API de WebSpeech solo está disponible en Firefox y Chrome. Su interfaz de síntesis de voz vive en el windowobjeto del navegador speechSynthesismientras que su interfaz de reconocimiento de voz vive en el windowobjeto del navegador como SpeechRecognitionen Firefox y como webkitSpeechRecognitionen Chrome.

Vamos a configurar la interfaz de reconocimiento SpeechRecognitionindependientemente del navegador en el que estemos:

window.SpeechRecognition = window.webkitSpeechRecognition || window.SpeechRecognition;

A continuación, crearemos una instancia de la interfaz de reconocimiento de voz:

const recognition = new SpeechRecognition(); const icon = document.querySelector('i.fa.fa-microphone') let paragraph = document.createElement('p'); let container = document.querySelector('.text-box'); container.appendChild(paragraph); const sound = document.querySelector('.sound');

En el código anterior, además de instanciar el reconocimiento de voz, también seleccionamos los elementos icon, text-box,y sounden la página. También creamos un elemento de párrafo que contendrá las palabras que decimos, y lo agregamos al text-box.

Siempre que se hace clic en el icono del micrófono en la página, queremos reproducir nuestro sonido e iniciar el servicio de reconocimiento de voz. Para lograr esto, agregamos un detector de eventos de clic al icono:

icon.addEventListener('click', () => { sound.play(); dictate(); }); const dictate = () => { recognition.start(); }

En el oyente de eventos, después de reproducir el sonido, seguimos adelante y creamos y llamamos a una dictatefunción. La dictatefunción inicia el servicio de reconocimiento de voz llamando al startmétodo en la instancia de reconocimiento de voz.

Para devolver un resultado para lo que sea que diga un usuario, debemos agregar un resultevento a nuestra instancia de reconocimiento de voz. La dictatefunción se verá así:

const dictate = () => { recognition.start(); recognition.onresult = (event) => { const speechToText = event.results[0][0].transcript; paragraph.textContent = speechToText; } }

El resultado eventdevuelve un SpeechRecognitionEventque contiene un resultsobjeto. Esto, a su vez, contiene la transcriptpropiedad que contiene el discurso reconocido en el texto. Guardamos el texto reconocido en una variable llamada speechToTexty lo colocamos en el paragraphelemento de la página.

Si ejecutamos la aplicación en este punto, haga clic en icony digamos algo, debería aparecer en la página.

Resumiendo con texto a voz

Para agregar texto a voz a nuestra aplicación, usaremos la speechSynthesisinterfaz de la API WebSpeech. Comenzaremos creando una instancia:

const synth = window.speechSynthesis;

A continuación, crearemos una función a la speakque llamaremos siempre que queramos que la aplicación diga algo:

const speak = (action) => { utterThis = new SpeechSynthesisUtterance(action()); synth.speak(utterThis); };

La speakfunción toma una función llamada actioncomo parámetro. La función devuelve una cadena a la que se le pasa SpeechSynthesisUtterance. SpeechSynthesisUtterancees la interfaz API de WebSpeech que contiene el contenido que debe leer el servicio de reconocimiento de voz. speakLuego se llama al método speechSynthesis en su instancia y se pasa el contenido para leer.

Para probar esto, necesitamos saber cuándo el usuario termina de hablar y dice: keyword.Afortunadamente, hay un método para verificar que:

const dictate = () => { ... if (event.results[0].isFinal) { if (speechToText.includes('what is the time')) { speak(getTime); }; if (speechToText.includes('what is today\'s date ')) { speak(getDate); }; if (speechToText.includes('what is the weather in')) { getTheWeather(speechToText); }; } ... } const getTime = () => { const time = new Date(Date.now()); return `the time is ${time.toLocaleString('en-US', { hour: 'numeric', minute: 'numeric', hour12: true })}` }; const getDate = () => { const time = new Date(Date.now()) return `today is ${time.toLocaleDateString()}`; }; const getTheWeather = (speech) => { fetch(`//api.openweathermap.org/data/2.5/weather?q=${speech.split(' ')[5]}&appid=58b6f7c78582bffab3936dac99c31b25&units=metric`) .then(function(response){ return response.json(); }) .then(function(weather){ if (weather.cod === '404') { utterThis = new SpeechSynthesisUtterance(`I cannot find the weather for ${speech.split(' ')[5]}`); synth.speak(utterThis); return; } utterThis = new SpeechSynthesisUtterance(`the weather condition in ${weather.name} is mostly full of ${weather.weather[0].description} at a temperature of ${weather.main.temp} degrees Celcius`); synth.speak(utterThis); }); };

En el código anterior, llamamos al isFinalmétodo en el resultado de nuestro evento que regresa trueo falsedependiendo de si el usuario terminó de hablar.

Si el usuario ha terminado de hablar, verificamos si la transcripción de lo dicho contiene palabras clave como what is the time, etc. Si es así, llamamos a nuestra speakfunción y le pasamos una de las tres funciones getTime, getDateo getTheWeathertodas devuelven una cadena para que la lea el navegador.

Nuestro index.jsarchivo ahora debería verse así:

window.SpeechRecognition = window.webkitSpeechRecognition || window.SpeechRecognition; const synth = window.speechSynthesis; const recognition = new SpeechRecognition(); const icon = document.querySelector('i.fa.fa-microphone') let paragraph = document.createElement('p'); let container = document.querySelector('.text-box'); container.appendChild(paragraph); const sound = document.querySelector('.sound'); icon.addEventListener('click', () => { sound.play(); dictate(); }); const dictate = () => { recognition.start(); recognition.onresult = (event) => { const speechToText = event.results[0][0].transcript; paragraph.textContent = speechToText; if (event.results[0].isFinal) { if (speechToText.includes('what is the time')) { speak(getTime); }; if (speechToText.includes('what is today\'s date')) { speak(getDate); }; if (speechToText.includes('what is the weather in')) { getTheWeather(speechToText); }; } } } const speak = (action) => { utterThis = new SpeechSynthesisUtterance(action()); synth.speak(utterThis); }; const getTime = () => { const time = new Date(Date.now()); return `the time is ${time.toLocaleString('en-US', { hour: 'numeric', minute: 'numeric', hour12: true })}` }; const getDate = () => { const time = new Date(Date.now()) return `today is ${time.toLocaleDateString()}`; }; const getTheWeather = (speech) => { fetch(`//api.openweathermap.org/data/2.5/weather?q=${speech.split(' ')[5]}&appid=58b6f7c78582bffab3936dac99c31b25&units=metric`) .then(function(response){ return response.json(); }) .then(function(weather){ if (weather.cod === '404') { utterThis = new SpeechSynthesisUtterance(`I cannot find the weather for ${speech.split(' ')[5]}`); synth.speak(utterThis); return; } utterThis = new SpeechSynthesisUtterance(`the weather condition in ${weather.name} is mostly full of ${weather.weather[0].description} at a temperature of ${weather.main.temp} degrees Celcius`); synth.speak(utterThis); }); };

Hagamos clic en el icono e intentemos una de las siguientes frases:

  • ¿Qué hora es?
  • ¿Cuál es la fecha de hoy?
  • ¿Qué tiempo hace en Lagos?

Deberíamos obtener una respuesta de la aplicación.

Conclusión

En este artículo, hemos podido crear una aplicación de reconocimiento de voz simple. Hay algunas cosas más interesantes que podríamos hacer, como seleccionar una voz diferente para leer a los usuarios, pero lo dejo para que lo haga usted.

If you have questions or feedback, please leave them as a comment below. I can’t wait to see what you build with this. You can hit me up on Twitter @developia_.