O aplicativo Express.js converte texto em fala com a Fala dos Serviços Cognitivos
Neste tutorial, adicione a Fala dos Serviços Cognitivos a um aplicativo Express.js existente a fim de adicionar a conversão de texto em fala usando o serviço de Fala dos Serviços Cognitivos. A conversão de texto em fala permite que você forneça áudio sem o custo da geração manual de áudio.
Este tutorial mostra três maneiras diferentes de converter texto em fala por meio da Fala dos Serviços Cognitivos do Azure:
- O JavaScript do cliente obtém áudio diretamente
- O JavaScript do servidor obtém áudio de um arquivo (*.MP3)
- O JavaScript do servidor obtém áudio de um arrayBuffer na memória
Arquitetura do aplicativo
O tutorial usa um aplicativo Express.js mínimo e adiciona funcionalidade usando uma combinação de:
- nova rota para a API do servidor a fim de fornecer conversão de texto em fala, retornando um fluxo de MP3
- nova rota para um formulário HTML a fim de permitir que você insira as informações
- novo formulário HTML, com JavaScript, fornece uma chamada do lado do cliente para o serviço de Fala
Esse aplicativo fornece três chamadas diferentes para conversão de fala em texto:
- A primeira chamada ao servidor cria um arquivo no servidor e o retorna ao cliente. Normalmente, você usa isso para textos mais longos ou textos que você sabe que poderão ser usados mais de uma vez.
- A segunda chamada do servidor é para texto de curto prazo e é mantida na memória antes de retornar ao cliente.
- A chamada ao cliente demonstra uma chamada direta ao serviço de Fala usando o SDK. Você poderá optar por fazer essa chamada se tiver um aplicativo somente de cliente sem um servidor.
Pré-requisitos
- Nó.js LTS - instalado em sua máquina local.
- Visual Studio Code – instalado no computador local.
- A extensão do Serviço de Aplicativo do Azure para VS Code (instalada de dentro do VS Code).
- Git – usado para enviar por push para o GitHub, o que ativa a ação do GitHub.
- Usar o Azure Cloud Shell usando o bash
- Se preferir, instale a CLI do Azure para executar comandos de referência da CLI.
- Se estiver usando uma instalação local, entre com a CLI do Azure usando o comando az login. Para concluir o processo de autenticação, siga as etapas exibidas no terminal. Confira Entrar com a CLI do Azure para ver mais opções de entrada.
- Quando solicitado, instale as extensões da CLI do Azure no primeiro uso. Para obter mais informações sobre extensões, confira Usar extensões com a CLI do Azure.
- Execute az version para localizar a versão e as bibliotecas dependentes que estão instaladas. Para fazer a atualização para a versão mais recente, execute az upgrade.
Baixar o repositório de exemplo Express.js
Usando o Git, clone o repositório de exemplo Express.js no computador local.
git clone https://github.com/Azure-Samples/js-e2e-express-server
Altere para o novo diretório para o exemplo.
cd js-e2e-express-server
Abra o projeto no Visual Studio Code.
code .
Abra um novo terminal no Visual Studio Code e instale as dependências do projeto.
npm install
Instale o SDK de Fala dos Serviços Cognitivos para JavaScript
Por meio do terminal do Visual Studio Code, instale o SDK de Fala dos Serviços Cognitivos do Azure.
npm install microsoft-cognitiveservices-speech-sdk
Criar um módulo de Fala para o aplicativo Express.js
Para integrar o SDK de Fala ao aplicativo Express.js, crie um arquivo na pasta do
src
chamadaazure-cognitiveservices-speech.js
.Adicione o código a seguir para efetuar pull de dependências e criar uma função para conversão de texto em fala.
// 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 – O arquivo efetua pull das dependências para usar o SDK, os fluxos, os buffers e o FS (sistema de arquivos). A função
textToSpeech
usa quatro argumentos. Se um nome de arquivo com caminho local for enviado, o texto será convertido em um arquivo de áudio. Se um nome de arquivo não for enviado, um fluxo de áudio na memória será criado. - Método SDK de Fala – O método SDK de Fala synthesizer.speakTextAsync retorna tipos diferentes, com base na configuração que recebe.
O método retorna o resultado, que difere com base no que o método foi solicitado a fazer:
- Criar arquivo
- Criar um fluxo na memória como matriz de buffers
- Formato de áudio – O formato de áudio selecionado é MP3, mas existem outros formatos, juntamente com outros Métodos de configuração de áudio.
O método local,
textToSpeech
, encapsula e converte a função de retorno de chamada do SDK em uma promessa.- Parâmetros – O arquivo efetua pull das dependências para usar o SDK, os fluxos, os buffers e o FS (sistema de arquivos). A função
Criar uma rota para o aplicativo Express.js
Abra o arquivo
src/server.js
.Adicione o módulo
azure-cognitiveservices-speech.js
como uma dependência na parte superior do arquivo:const { textToSpeech } = require('./azure-cognitiveservices-speech');
Adicione uma nova rota de API para chamar o método textToSpeech criado na seção anterior do tutorial. Adicione este código após a
/api/hello
rota.// 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); });
Esse método usa os parâmetros obrigatórios e opcionais para o método
textToSpeech
da QueryString. Se for necessário criar um arquivo, um nome de arquivo exclusivo será desenvolvido. O métodotextToSpeech
é chamado de maneira assíncrona e canaliza o resultado para o objeto de resposta (res
).
Atualizar a página da Web do cliente com um formulário
Atualize a página da Web HTML do cliente com um formulário que coleta os parâmetros necessários. O parâmetro opcional é passado com base em qual controle de áudio o usuário seleciona. Como este tutorial fornece um mecanismo para chamar o serviço de Fala do Azure do cliente, esse JavaScript também é fornecido.
Abra o arquivo /public/client.html
e substitua o conteúdo pelo seguinte código:
<!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>
Linhas realçadas no arquivo:
- Linha 74: O SDK de Fala do Azure é puxado para a biblioteca do cliente, usando o site para entregar o
cdn.jsdelivr.net
pacote NPM. - Linha 102: O
updateSrc
método atualiza a URL dossrc
controles de áudio com a cadeia de caracteres de consulta, incluindo a chave, a região e o texto. - Linha 137: se um usuário selecionar o botão, a página da Web chamará diretamente para o Azure a partir da página do cliente e processará o
Get directly from Azure
resultado.
Criar recurso de Fala dos Serviços Cognitivo
Cria o recurso de Fala com comandos da CLI do Azure em um Azure Cloud Shell.
Entrar no Azure Cloud Shell. Isso exige que você se autentique em um navegador com sua conta, que tem permissão em uma assinatura válida do Azure.
Crie um grupo de recursos para o recurso de Fala.
az group create \ --location eastus \ --name tutorial-resource-group-eastus
Crie um recurso de Fala no grupo de recursos.
az cognitiveservices account create \ --kind SpeechServices \ --location eastus \ --name tutorial-speech \ --resource-group tutorial-resource-group-eastus \ --sku F0
Esse comando falhará se o único recurso de Fala gratuito já tiver sido criado.
Use o comando para obter os valores de chave para o novo recurso de Fala.
az cognitiveservices account keys list \ --name tutorial-speech \ --resource-group tutorial-resource-group-eastus \ --output table
Copie uma das chaves.
Use a chave colando-a no formulário da Web do aplicativo Express para se autenticar no serviço de Fala do Azure.
Executar o aplicativo Express.js para converter texto em fala
Inicie o aplicativo com o comando bash a seguir.
npm start
Abra o aplicativo Web em um navegador.
http://localhost:3000
Cole a chave de Fala na caixa de texto realçada.
Opcionalmente, altere o texto para algo novo.
Selecione um dos três botões para iniciar a conversão ao formato de áudio:
- Obtenha diretamente do Azure – Chamada do lado do cliente ao Azure
- Controle de áudio para áudio do arquivo
- Controle de áudio para áudio do buffer
Você pode notar um pequeno atraso entre a seleção do controle e a reprodução do áudio.
Criar Serviço de Aplicativo do Azure no Visual Studio Code
Na paleta de comandos (Ctrl+Shift+P), digite "create web" e selecione Serviço de Aplicativo do Azure: Criar novo aplicativo Web... Avançado. Use o comando avançado para ter controle completo sobre a implantação, incluindo o grupo de recursos, o Plano do Serviço de Aplicativo e o sistema operacional, em vez de usar padrões do Linux.
Responda aos prompts da seguinte maneira:
- Selecionar sua conta de Assinatura.
- Para Inserir um nome globalmente exclusivo como
my-text-to-speech-app
.- Insira um nome que seja exclusivo em todo o Azure. Use apenas caracteres alfanuméricos ("A-Z", "a-z" e "0-9") e hifens ("-")
- Selecione
tutorial-resource-group-eastus
para o grupo de recursos. - Selecione uma pilha de runtime de uma versão que inclui
Node
eLTS
. - Selecione o sistema operacional Linux.
- Selecione Criar um Plano do Serviço de Aplicativo e forneça um nome como
my-text-to-speech-app-plan
. - Selecione o tipo de preço gratuito F1. Se sua assinatura já tem um aplicativo Web gratuito, selecione a camada
Basic
. - Selecione Ignorar por enquanto para o recurso do Application Insights.
- Selecione a localização
eastus
.
Após um breve período, o Visual Studio Code notificará você de que a criação foi concluída. Feche a notificação por meio do botão X.
Implantar o aplicativo local Express.js no serviço de aplicativo remoto no Visual Studio Code
Com o aplicativo Web em vigor, implante o código por meio do computador local. Selecione o ícone do Azure para abrir o gerenciador do Serviço de Aplicativo do Azure, expanda o nó de assinatura, clique com o botão direito do mouse no nome do aplicativo Web que acabou de criar e selecione Implantar no aplicativo Web.
Se houver prompts de implantação, selecione a pasta raiz do aplicativo Express.js, escolha a conta de assinatura novamente e selecione o nome do aplicativo Web,
my-text-to-speech-app
, criado anteriormente.Se receber um prompt para executar
npm install
ao implantar no Linux, selecione Sim se solicitado a atualizar a configuração para executarnpm install
no servidor de destino.Quando a implantação for concluída, selecione Procurar no Site no prompt para exibir seu aplicativo Web implantado recentemente.
(Opcional): você pode fazer alterações em seus arquivos de código e usar o Implantar no Aplicativo Web, na extensão de serviço do Aplicativo do Azure, para atualizar o aplicativo Web.
Transmitir logs de serviço remoto no Visual Studio Code
Exibir (acompanhar) qualquer saída que o aplicativo em execução gerar por meio de chamadas a console.log
. Essa saída aparece na janela Saída no Visual Studio Code.
No gerenciador do Serviço de Aplicativo do Azure, clique com o botão direito do mouse no novo nó do aplicativo e escolha Iniciar Fluxo de Logs.
Starting Live Log Stream ---
Atualize a página da Web algumas vezes no navegador para ver saída de log adicional.
Limpar os recursos por meio da remoção do grupo de recursos
Depois de concluir este tutorial, você precisará remover o grupo de recursos, que inclui todos os recursos, a fim de garantir que você não será cobrado por mais nenhum uso.
No Azure Cloud Shell, use o comando da CLI do Azure para excluir o grupo de recursos:
az group delete --name tutorial-resource-group-eastus -y
Esse comando pode levar alguns minutos.