Express.js aplicativo converte texto em fala com o Azure AI Speech
Neste tutorial, adicione o Azure AI Speech a um aplicativo Express.js existente para adicionar conversão de texto em fala usando o serviço Azure AI Speech. A conversão de texto em fala permite que você forneça áudio sem o custo de gerar manualmente o áudio.
Este tutorial mostra 3 maneiras diferentes de converter texto em fala do Azure AI Speech:
- O JavaScript do cliente obtém áudio diretamente
- O JavaScript do servidor obtém áudio do arquivo (*.MP3)
- O JavaScript do servidor obtém áudio de arrayBuffer na memória
Arquitetura da aplicação
O tutorial usa um aplicativo de Express.js mínimo e adiciona funcionalidade usando uma combinação de:
- nova rota para a API do servidor fornecer conversão de texto para fala, retornando um fluxo MP3
- nova rota para um formulário HTML para permitir que você insira suas informações
- novo formulário HTML, com JavaScript, fornece uma chamada do lado do cliente para o serviço de fala
Esta aplicação fornece três chamadas diferentes para converter fala em texto:
- A primeira chamada do servidor cria um arquivo no servidor e o retorna ao cliente. Normalmente, você usaria isso para texto mais longo ou texto que você sabe que deve ser servido 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 de cliente demonstra uma chamada direta para o serviço de fala usando o SDK. Você pode optar por fazer essa chamada se tiver um aplicativo somente cliente sem um servidor.
Pré-requisitos
Node.js LTS - instalado na sua máquina local.
Visual Studio Code - instalado em sua máquina 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 - que ativa a ação do GitHub.
Usar o Azure Cloud Shell usando o bash
Se preferir, instale o CLI do Azure para executar comandos de referência de CLI.
- Se estiver a utilizar uma instalação local, inicie sessão com o CLI do Azure ao utilizar o comando az login. Para concluir o processo de autenticação, siga os passos apresentados no seu terminal. Consulte Entrar com a CLI do Azure para obter mais opções de entrada.
- Quando lhe for pedido, instale as extensões do CLI do Azure durante a primeira utilização. Para obter mais informações sobre as extensões, veja Utilizar extensões com o CLI do Azure.
- Execute o comando az version para localizar a versão e as bibliotecas dependentes instaladas. Para atualizar para a versão mais recente, execute o comando az upgrade.
Download de exemplo Express.js repositório
Usando o git, clone o repositório de amostra Express.js para o computador local.
git clone https://github.com/Azure-Samples/js-e2e-express-server
Mude 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
Instalar o SDK de Fala do Azure AI para JavaScript
No terminal do Visual Studio Code, instale o SDK de Fala do Azure AI.
npm install microsoft-cognitiveservices-speech-sdk
Criar um módulo de Fala para o aplicativo Express.js
Para integrar o SDK de fala no aplicativo Express.js, crie um arquivo na
src
pasta chamadaazure-cognitiveservices-speech.js
.Adicione o código a seguir para puxar dependências e criar uma função para converter 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 obtém as dependências para usar o SDK, fluxos, buffers e o sistema de arquivos (fs). A
textToSpeech
função 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 Speech SDK - O método Speech SDK synthesizer.speakTextAsync retorna diferentes tipos, 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 ficheiro
- Criar fluxo na memória como uma 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 obtém as dependências para usar o SDK, fluxos, buffers e o sistema de arquivos (fs). A
Criar uma nova rota para o aplicativo Express.js
Abra o ficheiro
src/server.js
.Adicione o
azure-cognitiveservices-speech.js
módulo 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 necessários e opcionais para o
textToSpeech
método da querystring. Se um arquivo precisar ser criado, um nome de arquivo exclusivo será desenvolvido. OtextToSpeech
método é chamado de forma assíncrona e canaliza o resultado para o objeto response (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 ficheiro e substitua o /public/client.html
seu conteúdo pelo seguinte:
<!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 ficheiro:
- Linha 74: O SDK de Fala do Azure é puxado para a biblioteca do cliente, usando o
cdn.jsdelivr.net
site para entregar o 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
Get directly from Azure
botão, a página da Web chamará diretamente para o Azure a partir da página do cliente e processará o resultado.
Criar um recurso de Fala do Azure AI
Crie o recurso de Fala com comandos da CLI do Azure em um Azure Cloud Shell.
Faça logon no Azure Cloud Shell. Isso requer 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
Este comando falhará se o seu único recurso de liberdade de expressão já tiver sido criado.
Use o comando para obter os valores-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 autenticar no serviço de Fala do Azure.
Execute o aplicativo Express.js para converter texto em fala
Inicie o aplicativo com o seguinte comando bash.
npm start
Abra o aplicativo Web em um navegador.
http://localhost:3000
Cole a tecla 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 para o formato de áudio:
- Obter diretamente do Azure - chamada do lado do cliente para o Azure
- Controle de áudio para áudio de arquivo
- Controle de áudio para áudio do buffer
Você pode notar um pequeno atraso entre a seleção do controle e a reprodução de áudio.
Criar novo serviço de Aplicativo do Azure no Visual Studio Code
Na paleta de comandos (Ctrl+Shift+P), digite "create web" e selecione Azure App Service: Create New Web App... Avançado. Você usa o comando avançado para ter controle total sobre a implantação, incluindo grupo de recursos, Plano de Serviço de Aplicativo e sistema operacional, em vez de usar os padrões do Linux.
Responda às solicitações da seguinte maneira:
- Selecione a sua conta de Subscrição .
- Para Insira um nome globalmente exclusivo como
my-text-to-speech-app
.- Insira um nome exclusivo em todo o Azure. Utilizar apenas carateres alfanuméricos («A-Z», «a-z» e «0-9») e hífenes («-»)
- Selecione
tutorial-resource-group-eastus
para o grupo de recursos. - Selecione uma pilha de tempo de execução de uma versão que inclua
Node
eLTS
. - Selecione o sistema operacional Linux.
- Selecione Criar um novo plano do Serviço de Aplicativo, forneça um nome como
my-text-to-speech-app-plan
. - Selecione o nível de preço gratuito da F1. Se a sua subscrição já tiver uma aplicação Web gratuita, selecione o
Basic
nível. - Selecione Ignorar por enquanto para o recurso do Application Insights.
- Selecione o
eastus
local.
Após um curto período de tempo, o Visual Studio Code notifica que a criação foi concluída. Feche a notificação com o botão X .
Implantar aplicativo Express.js local no serviço de aplicativo remoto no Visual Studio Code
Com o aplicativo Web instalado, implante seu código a partir do computador local. Selecione o ícone do Azure para abrir o explorador 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 você acabou de criar e selecione Implantar no Aplicativo Web.
Se houver prompts de implantação, selecione a pasta raiz do aplicativo Express.js, selecione sua conta de assinatura novamente e, em seguida, selecione o nome do aplicativo Web,
my-text-to-speech-app
criado anteriormente.Se for solicitado a executar
npm install
durante a implantação no Linux, selecione Sim se for solicitado a atualizar sua configuração para ser executadanpm install
no servidor de destino.Quando a implantação estiver concluída, selecione Procurar site no prompt para exibir seu aplicativo Web recém-implantado.
(Opcional): você pode fazer alterações em seus arquivos de código e, em seguida, usar a opçã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
Visualize (cauda) qualquer saída que o aplicativo em execução gera por meio de chamadas para console.log
. Essa saída aparece na janela Saída no Visual Studio Code.
No explorador do Serviço de Aplicativo do Azure, clique com o botão direito do mouse no novo nó do aplicativo e escolha Iniciar Logs de Streaming.
Starting Live Log Stream ---
Atualize a página da Web algumas vezes no navegador para ver a saída de log adicional.
Limpar recursos removendo o grupo de recursos
Depois de concluir este tutorial, você precisa remover o grupo de recursos, que inclui o recurso, para garantir que você não seja cobrado por mais uso.
No Azure Cloud Shell, use o comando Azure CLI para excluir o grupo de recursos:
az group delete --name tutorial-resource-group-eastus -y
Este comando pode demorar alguns minutos.