En este tutorial vamos a hacer una APP de texto-audio, es decir una aplicación que reproduzca el texto en notas de voz (audio), para ello vamos a enlazar una API, se trata de “Web Speech API”. Es una interfaz de navegador muy poderosa que permite grabar la voz y convertirla en texto o viceversa. En nuestra APP haremos que se reproduzca el audio con el texto que agreguemos en la casilla.

Ver ejemplo: Ejemplo – Hacer una APP de Texto-Audio

hacer-app-texto-ejemplo


Hacer una APP de texto-audio

Crearemos una APP muy simple que reproducirá el texto añadido en notas de audio, lo que esta APP realiza es lo siguiente:

  • Toma notas de audio usando Voz-Texto o el teclado.
  • Guarda las notas de audio en localStorage.
  • Muestra las notas de audio y da la opción de escucharlas por medio de Speech Synthesis.

La APP estará enlazada con los estilos CSS de Shoelace y con jQuery. Estas dependencias estarán incluidas por medio de su CDN para que el proyecto sea más simple. Tenemos además un archivo HTML y otro de estilos CSS que acompañaran al documento JavaScript.

Integrando la API

La API de Web Speech está separada en 2 interfaces totalmente independientes. Tenemos el reconocimiento de voz (SpeechRecognition | Discurso -> Texto), que reconoce el audio o voz y la convierte en texto y la síntesis de discurso (SpeechSynthesis | Texto -> Discurso), para leer cadenas de caracteres generando un audio para escuchar. A continuación encuentras el código del documento JavaScript, que se agregará en el archivo denominado “script.js”, más adelante explico de que se trata.

Explicando Archivo JavaScript

Lo primero que debemos hacer es chequear que el usuario pueda tener acceso a la API y si no es así, que muestre el mensaje de error correctamente. Hasta el momento solo funciona con Google Chrome y Firefox (con una bandera), por lo tanto ese mensaje aparecerá si entramos desde Internet Explorer.

La variable “recognition” nos dará acceso a todos los métodos y propiedades de la API. A continuación puedes ver todas las lineas del código (JavaScript) que debes agregar en el archivo que denominaremos “script.js”.

script.js – Código Archivo

try {
  var SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
  var recognition = new SpeechRecognition();
}
catch(e) {
  console.error(e);
  $('.no-browser-support').show();
  $('.app').hide();
}
 
 
var noteTextarea = $('#note-textarea');
var instructions = $('#recording-instructions');
var notesList = $('ul#notes');
 
var noteContent = '';
 
// Toma todas las notas de sesiones anteriores y las muestra.
var notes = getAllNotes();
renderNotes(notes);
 
 
 
/*-----------------------------
      Reconocimiento de voz 
------------------------------*/
 
// Si se deja - false, la grabacion se detiene despues de unos segundos de silencio.
// Si se deja - true, la grabacion se detiene despues de 15 segundos aprox, dando tiempo para que el usuario pause. 
recognition.continuous = true;
 
// Este bloque es llamado cada vez que el Speech APi captura una linea.
recognition.onresult = function(event) {
 
  // event es el objeto SpeechRecognitionEvent.
  // Guarda las lineas capturadas. 
  // Solo es necesaria la que esta activa.
  var current = event.resultIndex;
 
  // Toma una transcripcion de lo que se dijo.
  var transcript = event.results[current][0].transcript;
 
  // Añadir la trasncripcion actual al contenido de la nota.
  // Hay un bug en moviles, todo se repite 2 veces. 
  // No hay una solucion oficial, hasta ahora has servido esta.
  var mobileRepeatBug = (current == 1 && transcript == event.results[0][0].transcript);
 
  if(!mobileRepeatBug) {
    noteContent += transcript;
    noteTextarea.val(noteContent);
  }
};
 
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.');  
  };
}
 
 
 
/*-----------------------------
      Botones de App y input 
------------------------------*/
 
$('#start-record-btn').on('click', function(e) {
  if (noteContent.length) {
    noteContent += ' ';
  }
  recognition.start();
});
 
 
$('#pause-record-btn').on('click', function(e) {
  recognition.stop();
  instructions.text('Reconocimiento Pausado.');
});
 
// Sincroniza el texto dentro del area de texto con la variable noteContent
noteTextarea.on('input', function() {
  noteContent = $(this).val();
})
 
$('#save-note-btn').on('click', function(e) {
  recognition.stop();
 
  if(!noteContent.length) {
    instructions.text('No pudimos guardar la nota de voz. Por favor agrega un mensaje en tu nota.');
  }
  else {
    // Guarda la nota en localStorage.
    // key es la fecha, value es el contenido de la nota.
    saveNote(new Date().toLocaleString(), noteContent);
 
    // Reninicia variables y actualiza UI.
    noteContent = '';
    renderNotes(getAllNotes());
    noteTextarea.val('');
    instructions.text('Nota guardada satisfactoriamente');
  }
 
})
 
 
notesList.on('click', function(e) {
  e.preventDefault();
  var target = $(e.target);
 
  // Escuchar la nota de voz actual.
  if(target.hasClass('listen-note')) {
    var content = target.closest('.note').find('.content').text();
    readOutLoud(content);
  }
 
  // Eliminar nota.
  if(target.hasClass('delete-note')) {
    var dateTime = target.siblings('.date').text();  
    deleteNote(dateTime);
    target.closest('.note').remove();
  }
});
 
 
 
/*-----------------------------
      Sintesis de discurso
------------------------------*/
 
function readOutLoud(message) {
	var speech = new SpeechSynthesisUtterance();
 
  // Configura los atributos de texto y voz.
	speech.text = message;
	speech.volume = 1;
	speech.rate = 1;
	speech.pitch = 1;
 
	window.speechSynthesis.speak(speech);
}
 
 
 
/*-----------------------------
      Helper Functions 
------------------------------*/
 
function renderNotes(notes) {
  var html = '';
  if(notes.length) {
    notes.forEach(function(note) {
      html+= `<li class="note">
        <p class="header">
          <span class="date">${note.date}</span>
          <a href="#" class="listen-note" title="Listen to Note">Escuchar nota de voz</a>
          <a href="#" class="delete-note" title="Delete">Eliminar</a>
        </p>
        <p class="content">${note.content}</p>
      </li>`;    
    });
  }
  else {
    html = '<li><p class="content">Tu no tienes ninguna nota de voz.</p></li>';
  }
  notesList.html(html);
}
 
 
function saveNote(dateTime, content) {
  localStorage.setItem('note-' + dateTime, content);
}
 
 
function getAllNotes() {
  var notes = [];
  var key;
  for (var i = 0; i < localStorage.length; i++) {
    key = localStorage.key(i);
 
    if(key.substring(0,5) == 'note-') {
      notes.push({
        date: key.replace('note-',''),
        content: localStorage.getItem(localStorage.key(i))
      });
    } 
  }
  return notes;
}
 
 
function deleteNote(dateTime) {
  localStorage.removeItem('note-' + dateTime); 
}

Explicando archivo HTML

El archivo “HTML” contendrá la estructura de la APP de texto-audio, es lo que el usuario vera cuendo la abra, este archivo puede ser el que tu desees pero debes enlazarlo correctamente con las variables del archivo “JavaScript“. El archivo “HTML” se enlazara también al de estilos CSS que veremos mas adelante. Nuestro archivo HTML sera muy sencillo, pues solo se compone de la pestaña que muestra la APP de texto-audio, si tu deseas puedes agregar un menú para añadir mas contenido, puedes ver como hacerlo en el articulo “Hacer menú responsive“.  A continuación encuentras un ejemplo del código que debes agregar en el documento que nombraremos “index.html“.

Index.html – Código Archivo

<!DOCTYPE html>
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>APP para Reproducir texto en notas de voz</title>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
 
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/shoelace-css/1.0.0-beta16/shoelace.css">
        <link rel="stylesheet" href="styles.css">
 
    </head>
    <body>
        <div class="container">
 
            <h1>Hacer una APP de texto-audio</h1>
            <p class="page-description">APP para Reproducir texto en notas de voz usando HTML y JavaScript, esta APP te permitira reproducir el texto que agregues en notas de voz para escuchar instantaneamente.</p>
            <p><a class="enlace-inicio" href="https://internetedadinero.com/">Ver el tutorial completo en InterneTedaDinero.com</a></p>
 
            <h3 class="no-browser-support">Disculpa, tu navegador no soprta el Web Speech API. Intenta usando Google Chrome.</h3>
 
            <div class="app"> 
                <h3>Agregar una nota de voz</h3>
                <div class="input-single">
                    <textarea id="note-textarea" placeholder="Escribe el texto para crear una nota de voz..." rows="6"></textarea>
                </div>         
                <button id="start-record-btn" title="Start Recording">Iniciar Reconocimento</button>
                <button id="pause-record-btn" title="Pause Recording">Pausar Reconocimento</button>
                <button id="save-note-btn" title="Save Note">Guardar Nota y Escuchar</button>   
                <p id="recording-instructions">Oprime el boton <strong>Iniciar Reconocimento</strong> para empezar.</p>
                <hr>
                <h3>Mis notas de voz - Escuchar</h3>
                <ul id="notes">
                    <li>
                        <p class="no-notes">Tu no tienes ninguna nota de voz.</p>
                    </li>
                </ul>
 
            </div>
 
        </div>
 
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
        <script src="script.js"></script>
 
    </body>
</html>

Explicando archivo CSS

Por ultimo añadiremos algunos estilos “CSS” adicionales a la APP de texto-audio, pues ya tenemos la mayoría enlazados desde la API de Shoelace. También agregaremos estilos para apoyar la visualización en dispositivos móviles. A continuación veras un ejemplo de estilos CSS que puedes añadir a tu aplicacion, lo agregaremos en un archivo que denominamos “styles.css”.

styles.css – Código Archivo

ul {
list-style: none;
padding: 0;
}
 
p {
color: #444;
}
 
a {
color: #2a8d3a;
}
 
button:focus {
outline: 0;
}
 
.button, button {
background-color: #2a8d3a;
}
 
.button:hover, button:hover {
background-color: #333;
}
 
.container {
max-width: 700px;
margin: 0 auto;
padding: 20px 50px;
text-align: center;
}
 
.container h1 {
margin-bottom: 20px;
}
 
.page-description {
font-size: 1.1rem;
margin: 0 auto;
}
 
.enlace-inicio {
font-size: 1em;
color: #888;
text-decoration: none;
}
 
.enlace-inicio:hover {
color: #2a8d3a;
}
 
.no-browser-support {
display: none;
font-size: 1.2rem;
color: #e64427;
margin-top: 35px;
}
 
.app {
margin: 40px auto;
}
 
#note-textarea {
margin: 20px 0;
border: 1px solid #ccc;
}
 
#recording-instructions {
margin: 15px auto 20px;
}
 
#notes {
padding-top: 2px;
}
 
.note .header {
font-size: 0.9em;
color: #888;
margin-bottom: 10px;
}
 
.note .delete-note,
.note .listen-note {
text-decoration: none;
margin-left: 15px;
}
 
.note .content {
margin-bottom: 40px;
}
 
@media (max-width: 768px) {
.container {
padding: 50px 25px;
}
 
button {
margin-bottom: 10px;
}
 
}

Conclusión

La API de Web Speech funciona sin mayores dificultades, es una API muy poderosa que permite reproducir el texto con acentos e idiomas diferentes. El único inconveniente es su soporte entre diferentes navegadores, pues este soporte es bastante limitado, por lo que difícilmente nos sirva más allá de ejemplificar su uso. No olvides comentar si tienes alguna duda y si te ha gustado el articulo compártelo ¡Muchas Gracias!

Ver ejemplo: Ejemplo – Hacer una APP de Texto-Audio
Descargar archivos: Descargar – Hacer una APP de Texto-Audio

Share This