Express.js aplicación convierte texto a voz con Voz de Azure AI
En este tutorial, agregue Voz de Azure AI a una aplicación de Express.js existente para agregar la conversión de texto a voz mediante el servicio Azure AI Speech. La conversión de texto a voz le permite proporcionar audio sin el costo de generar manualmente el audio.
En este tutorial se muestran tres maneras diferentes de convertir texto a voz de Azure AI Speech:
- El código JavaScript del cliente recibe el audio directamente
- El código JavaScript del servidor obtiene el audio de un archivo (*.MP3)
- El código JavaScript del servidor obtiene el audio de un elemento arrayBuffer en memoria
Arquitectura de la aplicación
El tutorial toma una aplicación de Express.js mínima y agrega funcionalidad mediante una combinación de:
- nueva ruta para la API de servidor para proporcionar conversión de texto a voz y devolver un flujo MP3
- nueva ruta para un formulario HTML que le permite escribir la información
- nuevo formulario HTML, con JavaScript, que proporciona una llamada del lado cliente al servicio de Voz
Esta aplicación proporciona tres llamadas diferentes para convertir voz en texto:
- La primera llamada de servidor crea un archivo en el servidor y, a continuación, lo devuelve al cliente. Normalmente se usaría para texto más largo o para texto que se sabe que se debe atender más de una vez.
- La segunda llamada al servidor es para texto a corto plazo y se mantiene en memoria antes de volver al cliente.
- La llamada de cliente muestra una llamada directa al servicio de Voz mediante el SDK. Puede optar por realizar esta llamada si tiene una aplicación solo de cliente sin servidor.
Requisitos previos
Node.js LTS : instalado en el equipo local.
Visual Studio Code: instalado en la máquina local.
La extensión de Azure App Service para VS Code (se instala desde VS Code).
Git: se usa para insertar en GitHub, lo que activa la acción de GitHub.
Uso de Azure Cloud Shell mediante Bash
Si lo prefiere, instale la CLI de Azure para ejecutar sus comandos de referencia.
- Si usa una instalación local, inicie sesión con la CLI de Azure mediante el comando az login. Siga los pasos que se muestran en el terminal para completar el proceso de autenticación. Para más opciones de inicio de sesión, consulte Inicio de sesión con la CLI de Azure.
- Cuando se le solicite, instale las extensiones de la CLI de Azure la primera vez que la use. Para más información, consulte Uso de extensiones con la CLI de Azure.
- Ejecute az version para buscar cuál es la versión y las bibliotecas dependientes que están instaladas. Para realizar la actualización a la versión más reciente, ejecute az upgrade.
Descarga del repositorio de ejemplo de Express.js
Con git, clone el repositorio de ejemplo de Express.js en el equipo local.
git clone https://github.com/Azure-Samples/js-e2e-express-server
Cambie al nuevo directorio del ejemplo.
cd js-e2e-express-server
Abra el proyecto en Visual Studio Code.
code .
Abra un nuevo terminal en Visual Studio Code e instale las dependencias del proyecto.
npm install
Instalación del SDK de Voz de Azure AI para JavaScript
Desde el terminal de Visual Studio Code, instale el SDK de Voz de Azure AI.
npm install microsoft-cognitiveservices-speech-sdk
Creación de un módulo de Voz para la aplicación de Express.js
Para integrar el SDK de Voz en la aplicación de Express.js, cree un archivo en la carpeta
src
llamadoazure-cognitiveservices-speech.js
.Agregue el código siguiente para extraer las dependencias y crear una función para convertir texto a voz.
// azure-cognitiveservices-speech.js const sdk = require('microsoft-cognitiveservices-speech-sdk'); const { Buffer } = require('buffer'); const { PassThrough } = require('stream'); const fs = require('fs'); /** * Node.js server code to convert text to speech * @returns stream * @param {*} key your resource key * @param {*} region your resource region * @param {*} text text to convert to audio/speech * @param {*} filename optional - best for long text - temp file for converted speech/audio */ const textToSpeech = async (key, region, text, filename)=> { // convert callback function to promise return new Promise((resolve, reject) => { const speechConfig = sdk.SpeechConfig.fromSubscription(key, region); speechConfig.speechSynthesisOutputFormat = 5; // mp3 let audioConfig = null; if (filename) { audioConfig = sdk.AudioConfig.fromAudioFileOutput(filename); } const synthesizer = new sdk.SpeechSynthesizer(speechConfig, audioConfig); synthesizer.speakTextAsync( text, result => { const { audioData } = result; synthesizer.close(); if (filename) { // return stream from file const audioFile = fs.createReadStream(filename); resolve(audioFile); } else { // return stream from memory const bufferStream = new PassThrough(); bufferStream.end(Buffer.from(audioData)); resolve(bufferStream); } }, error => { synthesizer.close(); reject(error); }); }); }; module.exports = { textToSpeech };
- Parámetros: el archivo extrae las dependencias para usar el SDK, las secuencias, los búferes y el sistema de archivos (fs). La función
textToSpeech
toma cuatro argumentos. Si se envía un nombre de archivo con una ruta de acceso local, el texto se convierte en un archivo de audio. Si no se envía un nombre de archivo, se crea una secuencia de audio en memoria. - Método del SDK de Voz: el método synthesizer.speakTextAsync del SDK de Voz devuelve tipos diferentes, en función de la configuración que recibe.
El método devuelve el resultado, que difiere en función de lo que se le pidió que hiciera el método:
- Crear archivo
- Crear una secuencia en memoria como una matriz de búferes
- Formato de audio: el formato de audio seleccionado es MP3, pero hay otros formatos, junto con otros métodos de configuración de audio.
El método local,
textToSpeech
, encapsula y convierte la función de devolución de llamada del SDK en una promesa.- Parámetros: el archivo extrae las dependencias para usar el SDK, las secuencias, los búferes y el sistema de archivos (fs). La función
Creación de una nueva ruta para la aplicación de Express.js
Abra el archivo
src/server.js
.Agregue el módulo
azure-cognitiveservices-speech.js
como una dependencia en la parte superior del archivo:const { textToSpeech } = require('./azure-cognitiveservices-speech');
Agregue una nueva ruta de API para llamar al método textToSpeech creado en la sección anterior del tutorial. Agregue este código después de la
/api/hello
ruta.// creates a temp file on server, the streams to client /* eslint-disable no-unused-vars */ app.get('/text-to-speech', async (req, res, next) => { const { key, region, phrase, file } = req.query; if (!key || !region || !phrase) res.status(404).send('Invalid query string'); let fileName = null; // stream from file or memory if (file && file === true) { fileName = `./temp/stream-from-file-${timeStamp()}.mp3`; } const audioStream = await textToSpeech(key, region, phrase, fileName); res.set({ 'Content-Type': 'audio/mpeg', 'Transfer-Encoding': 'chunked' }); audioStream.pipe(res); });
Este método toma los parámetros obligatorios y opcionales para el método
textToSpeech
de la cadena de consulta. Si es necesario crear un archivo, se desarrolla un nombre de archivo único. Se llama al métodotextToSpeech
de forma asincrónica y este canaliza el resultado al objeto de respuesta (res
).
Actualización de la página web del cliente con un formulario
Actualice la página web HTML del cliente con un formulario que recopile los parámetros necesarios. El parámetro opcional se pasa en función del control de audio que seleccione el usuario. Dado que este tutorial proporciona un mecanismo para llamar al servicio de Voz de Azure desde el cliente, también se proporciona ese código JavaScript.
Abra el archivo /public/client.html
y reemplace su contenido por lo siguiente:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Microsoft Cognitive Services Demo</title>
<meta charset="utf-8" />
</head>
<body>
<div id="content" style="display:none">
<h1 style="font-weight:500;">Microsoft Cognitive Services Speech </h1>
<h2>npm: microsoft-cognitiveservices-speech-sdk</h2>
<table width="100%">
<tr>
<td></td>
<td>
<a href="https://docs.microsoft.com/azure/cognitive-services/speech-service/get-started" target="_blank">Azure
Cognitive Services Speech Documentation</a>
</td>
</tr>
<tr>
<td align="right">Your Speech Resource Key</td>
<td>
<input id="resourceKey" type="text" size="40" placeholder="Your resource key (32 characters)" value=""
onblur="updateSrc()">
</tr>
<tr>
<td align="right">Your Speech Resource region</td>
<td>
<input id="resourceRegion" type="text" size="40" placeholder="Your resource region" value="eastus"
onblur="updateSrc()">
</td>
</tr>
<tr>
<td align="right" valign="top">Input Text (max 255 char)</td>
<td><textarea id="phraseDiv" style="display: inline-block;width:500px;height:50px" maxlength="255"
onblur="updateSrc()">all good men must come to the aid</textarea></td>
</tr>
<tr>
<td align="right">
Stream directly from Azure Cognitive Services
</td>
<td>
<div>
<button id="clientAudioAzure" onclick="getSpeechFromAzure()">Get directly from Azure</button>
</div>
</td>
</tr>
<tr>
<td align="right">
Stream audio from file on server</td>
<td>
<audio id="serverAudioFile" controls preload="none" onerror="DisplayError()">
</audio>
</td>
</tr>
<tr>
<td align="right">Stream audio from buffer on server</td>
<td>
<audio id="serverAudioStream" controls preload="none" onerror="DisplayError()">
</audio>
</td>
</tr>
</table>
</div>
<!-- Speech SDK reference sdk. -->
<script
src="https://cdn.jsdelivr.net/npm/microsoft-cognitiveservices-speech-sdk@latest/distrib/browser/microsoft.cognitiveservices.speech.sdk.bundle-min.js">
</script>
<!-- Speech SDK USAGE -->
<script>
// status fields and start button in UI
var phraseDiv;
var resultDiv;
// subscription key and region for speech services.
var resourceKey = null;
var resourceRegion = "eastus";
var authorizationToken;
var SpeechSDK;
var synthesizer;
var phrase = "all good men must come to the aid"
var queryString = null;
var audioType = "audio/mpeg";
var serverSrc = "/text-to-speech";
document.getElementById('serverAudioStream').disabled = true;
document.getElementById('serverAudioFile').disabled = true;
document.getElementById('clientAudioAzure').disabled = true;
// update src URL query string for Express.js server
function updateSrc() {
// input values
resourceKey = document.getElementById('resourceKey').value.trim();
resourceRegion = document.getElementById('resourceRegion').value.trim();
phrase = document.getElementById('phraseDiv').value.trim();
// server control - by file
var serverAudioFileControl = document.getElementById('serverAudioFile');
queryString += `%file=true`;
const fileQueryString = `file=true®ion=${resourceRegion}&key=${resourceKey}&phrase=${phrase}`;
serverAudioFileControl.src = `${serverSrc}?${fileQueryString}`;
console.log(serverAudioFileControl.src)
serverAudioFileControl.type = "audio/mpeg";
serverAudioFileControl.disabled = false;
// server control - by stream
var serverAudioStreamControl = document.getElementById('serverAudioStream');
const streamQueryString = `region=${resourceRegion}&key=${resourceKey}&phrase=${phrase}`;
serverAudioStreamControl.src = `${serverSrc}?${streamQueryString}`;
console.log(serverAudioStreamControl.src)
serverAudioStreamControl.type = "audio/mpeg";
serverAudioStreamControl.disabled = false;
// client control
var clientAudioAzureControl = document.getElementById('clientAudioAzure');
clientAudioAzureControl.disabled = false;
}
function DisplayError(error) {
window.alert(JSON.stringify(error));
}
// Client-side request directly to Azure Cognitive Services
function getSpeechFromAzure() {
// authorization for Speech service
var speechConfig = SpeechSDK.SpeechConfig.fromSubscription(resourceKey, resourceRegion);
// new Speech object
synthesizer = new SpeechSDK.SpeechSynthesizer(speechConfig);
synthesizer.speakTextAsync(
phrase,
function (result) {
// Success function
// display status
if (result.reason === SpeechSDK.ResultReason.SynthesizingAudioCompleted) {
// load client-side audio control from Azure response
audioElement = document.getElementById("clientAudioAzure");
const blob = new Blob([result.audioData], { type: "audio/mpeg" });
const url = window.URL.createObjectURL(blob);
} else if (result.reason === SpeechSDK.ResultReason.Canceled) {
// display Error
throw (result.errorDetails);
}
// clean up
synthesizer.close();
synthesizer = undefined;
},
function (err) {
// Error function
throw (err);
audioElement = document.getElementById("audioControl");
audioElement.disabled = true;
// clean up
synthesizer.close();
synthesizer = undefined;
});
}
// Initialization
document.addEventListener("DOMContentLoaded", function () {
var clientAudioAzureControl = document.getElementById("clientAudioAzure");
var resultDiv = document.getElementById("resultDiv");
resourceKey = document.getElementById('resourceKey').value;
resourceRegion = document.getElementById('resourceRegion').value;
phrase = document.getElementById('phraseDiv').value;
if (!!window.SpeechSDK) {
SpeechSDK = window.SpeechSDK;
clientAudioAzure.disabled = false;
document.getElementById('content').style.display = 'block';
}
});
</script>
</body>
</html>
Líneas resaltadas en el archivo:
- Línea 74: El SDK de Voz de Azure se extrae en la biblioteca cliente mediante el
cdn.jsdelivr.net
sitio para entregar el paquete NPM. - Línea 102: el
updateSrc
método actualiza la dirección URL de los controlessrc
de audio con la cadena de consulta, incluida la clave, la región y el texto. - Línea 137: Si un usuario selecciona el
Get directly from Azure
botón, la página web llama directamente a Azure desde la página del cliente y procesa el resultado.
Crear un recurso de Voz de Azure AI
Cree el recurso de Voz con comandos de la CLI de Azure en una instancia de Azure Cloud Shell.
Inicie sesión en Azure Cloud Shell. Esto requiere que se autentique en un explorador con su cuenta, que tiene permisos en una suscripción válida de Azure.
Cree un grupo de recursos para el recurso de Voz.
az group create \ --location eastus \ --name tutorial-resource-group-eastus
Cree un recurso de Voz en el grupo de recursos.
az cognitiveservices account create \ --kind SpeechServices \ --location eastus \ --name tutorial-speech \ --resource-group tutorial-resource-group-eastus \ --sku F0
Este comando producirá un error si ya se ha creado el recurso de Voz gratis.
Use el comando para obtener los valores de clave del nuevo recurso de Voz.
az cognitiveservices account keys list \ --name tutorial-speech \ --resource-group tutorial-resource-group-eastus \ --output table
Copie una de las claves.
Para usarla, péguela en el formulario web de la aplicación Express para autenticarse en el servicio de voz de Azure.
Ejecución de la aplicación de Express.js para convertir texto a voz
Inicie la aplicación con el siguiente comando bash.
npm start
Abra la aplicación web en un explorador.
http://localhost:3000
Pegue la clave del servicio de Voz en el cuadro de texto resaltado.
Opcionalmente, cambie el texto a algo nuevo.
Seleccione uno de los tres botones para iniciar la conversión al formato de audio:
- Obtener directamente de Azure: llamada del lado cliente a Azure
- Control de audio para audio desde archivo
- Control de audio para audio desde búfer
Es posible que observe un pequeño retraso entre la selección del control y la reproducción del audio.
Creación de una nueva instancia de Azure App Service en Visual Studio Code
En la paleta de comandos (Ctrl+Mayús+P), escriba "crear web" y seleccione App de Azure Servicio: Crear nueva aplicación web... Avanzado. En lugar de usar los valores predeterminados de Linux, use el comando avanzado para tener control total sobre la implementación, incluido el grupo de recursos, el plan de App Service y el sistema operativo.
Responda a los mensajes como se indica a continuación:
- Seleccione la cuenta de Suscripción.
- Para Escriba un nombre único global, escriba algo como
my-text-to-speech-app
.- Escriba un nombre que sea único en todo Azure. Use solo caracteres alfanuméricos (A-Z, a-z y 0-9) y guiones ("-").
- Seleccione
tutorial-resource-group-eastus
para el grupo de recursos. - Seleccione una pila de tiempo de ejecución de una versión que incluya
Node
yLTS
. - Seleccione el sistema operativo Linux.
- Seleccione Crear un nuevo plan de App Service y proporcione un nombre, como
my-text-to-speech-app-plan
. - Seleccione el plan de tarifa gratis F1. Si la suscripción ya tiene una aplicación web gratuita, seleccione el nivel
Basic
. - Seleccione Omitir por ahora para el recurso de Application Insights.
- Seleccione la ubicación
eastus
.
Tras unos momentos, Visual Studio Code notifica que se ha completado la creación. Cierre la notificación con el botón X.
Implementación de una aplicación local de Express.js en el servicio de aplicaciones remoto en Visual Studio Code
Una vez implementada la aplicación web, implemente el código desde el equipo local. Seleccione el icono de Azure para abrir el explorador de Azure App Service, expanda el nodo de la suscripción, haga clic con el botón derecho en el nombre de la aplicación web que acaba de crear y seleccione Deploy to Web App (Implementar en aplicación web).
Si hay avisos de implementación, seleccione la carpeta raíz de la aplicación de Express.js, vuelva a seleccionar la cuenta de la suscripción y, luego, elija el nombre de la aplicación web creada anteriormente,
my-text-to-speech-app
.Si, al realizar la implementación en Linux, se le pide que ejecute
npm install
y se le pregunta si quiere actualizar la configuración para ejecutarnpm install
en el servidor de destino, seleccione Sí.Una vez finalizada la implementación, seleccione Browse Website (Examinar sitio web) en el mensaje para ver la aplicación web recién implementada.
(Opcional): puede realizar cambios en los archivos de código y, a continuación, usar La implementación en la aplicación web, en la extensión de servicio App de Azure, para actualizar la aplicación web.
Transmisión de registros de servicio remoto en Visual Studio Code
Vea o consulte el final de los archivos de salida que la aplicación en ejecución genere mediante llamadas a console.log
. Esta salida aparece en la ventana Salida de Visual Studio Code.
En el explorador de Azure App Service, haga clic con el botón derecho en el nodo de la aplicación y elija Start Streaming Logs (Iniciar transmisión de registros).
Starting Live Log Stream ---
Actualice la página web varias veces en el explorador para ver otras salidas de registros.
Limpieza de recursos mediante la eliminación del grupo de recursos
Una vez que haya completado este tutorial, deberá eliminar el grupo de recursos que incluye el recurso para asegurarse de que no se le facturará por ningún uso adicional.
En Azure Cloud Shell, use el comando de la CLI de Azure para eliminar el grupo de recursos:
az group delete --name tutorial-resource-group-eastus -y
Este comando puede tardar unos minutos.