En este tutorial vamos a experimentar con la API Web Speech. Es una API muy potente que te permite grabar voz humana y convertirla en texto. Ojo, en este artÃculo también haremos lo contrario, leer cadenas de texto y convertirlas en voz “humana”. ¡Vamos allá!
Para ver lo que puede llegar a hacer la API, vamos a crear una aplicación de notas sencilla basada en voz. Esta app hará 3 cosas:
- Tomar notas mediante el uso de la voz que convertiremos en texto o bien, mediante teclado como siempre.
- Guardar notas en localStorage.
- Mostrar todas las notas y ofrecer la opción de escucharlas a través de Speech Synthesis.
No utilizaremos dependencias, solamente jQuery para las operaciones DOM más sencillas y Shoelace para el CSS. Las incluiremos directamente a través de CDN, no hay necesidad de involucrar NPM en un proyecto tan pequeño.
Utilizaremos un HTML y CSS bastante estándar, asà que por eso vamos a omitirlos y vamos directamente a lo importante, el Javascript.
Voz a texto
La API Web Speech en realidad está separada en dos interfaces totalmente independientes. Tenemos SpeechRecognition para comprender la voz humana y convertirla en texto (Speech -> Text) y SpeechSynthesis para leer strings y convertirlos en una voz generada por ordenador (Text -> Speech). Empezaremos con el primero.
La API de reconocimiento de voz es sorprendentemente precisa para una función de navegador gratuita. En unas pruebas que he realizado ha reconocido correctamente casi todas mis frases y supo qué palabras van juntas hasta formar discursos que tenÃan sentido. También te permite dictar caracteres especiales como puntos y aparte, signos de interrogación y lÃneas nuevas.
Lo primero que tienes que hacer es verificar si el usuario tiene acceso a la API y mostrar un mensaje de error en el caso de que no. Desafortunadamente, la API de voz a texto solo está soportada por Chrome y Firefox, por lo que muchas personas probablemente verán ese mensaje.
try { var SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition; var recognition = new SpeechRecognition(); } catch(e) { console.error(e); $('.no-browser-support').show(); $('.app').hide(); }
La variable de reconocimiento nos dará acceso a todos los métodos y propiedades de la API. Hay varias opciones disponibles, pero solo definiremos recognition.continuous a true. Esto permitirá a los usuarios hablar con pausas más largas entre palabras y frases.
Antes de que podamos usar el reconocimiento de voz, también tenemos que configurar un par de controladores de eventos. La mayorÃa de ellos simplemente escuchan los cambios en el estado de reconocimiento:
recognition.onstart = function() { instructions.text('Voice recognition activated. Try speaking into the microphone.'); } recognition.onspeechend = function() { instructions.text('You were quiet for a while so voice recognition turned itself off.'); } recognition.onerror = function(event) { if(event.error == 'no-speech') { instructions.text('No speech was detected. Try again.'); }; }
Sin embargo, el evento especial onresult es muy importante. Se ejecuta cada vez que el usuario pronuncia una palabra o varias en rápida sucesión, lo que nos da acceso a una transcripción de texto de lo que se dijo.
Cuando capturamos algo con el controlador onresult lo guardamos en una variable global y lo mostramos en un textarea:
recognition.onresult = function(event) { // event is a SpeechRecognitionEvent object. // It holds all the lines we have captured so far. // We only need the current one. var current = event.resultIndex; // Get a transcript of what was said. var transcript = event.results[current][0].transcript; // Add the current transcript to the contents of our Note. noteContent += transcript; noteTextarea.val(noteContent); }
El anterior código está ligeramente simplificado. Hay un error muy extraño en los dispositivos Android que hace que todo se repita dos veces. TodavÃa no hay una solución oficial, pero logramos resolver el problema sin efectos secundarios obvios. Con ese error en mente, el código se ve asÃ:
var mobileRepeatBug = (current == 1 && transcript == event.results[0][0].transcript); if(!mobileRepeatBug) { noteContent += transcript; noteTextarea.val(noteContent); }
Una vez que tengamos todo configurado, podemos comenzar a usar la función de reconocimiento de voz del navegador. Para iniciarlo simplemente llamamos al método start():
$('#start-record-btn').on('click', function(e) { recognition.start(); });
Esto hará que los usuarios den su permiso. Si asà se hace, se activará el micrófono del dispositivo. El navegador escuchará por un momento y cada frase o palabra reconocida será transcrita. La API dejará de escuchar automáticamente después de unos segundos de silencio o cuando se detenga manualmente.
$('#pause-record-btn').on('click', function(e) { recognition.stop(); });
Con esto, la parte de voz a texto de nuestra aplicación está completa. Ahora, ¡hagamos lo contrario!
Texto a voz
Utilizar Speech Synthesys es realmente muy sencillo. Se puede acceder a la API a través del objeto speechSynthesis y hay un par de métodos para reproducir, pausar y otras cosas relacionadas con el audio. También tiene un par de opciones interesantes que cambian el tono, la frecuencia e incluso la voz del lector.
Todo lo que necesitamos para nuestra demo es el método speak(). Espera un argumento, una instancia de la clase SpeechSynthesisUtterance.
Aquà está el código completo necesario para leer una cadena.
function readOutLoud(message) { var speech = new SpeechSynthesisUtterance(); // Set the text and voice attributes. speech.text = message; speech.volume = 1; speech.rate = 1; speech.pitch = 1; window.speechSynthesis.speak(speech); }