Express.js-app converteert tekst naar spraak met Azure AI Speech
In deze zelfstudie voegt u Azure AI Speech toe aan een bestaande Express.js-app om conversie van tekst naar spraak toe te voegen met behulp van de Azure AI Speech-service. Als u tekst naar spraak converteert, kunt u audio leveren zonder de kosten van het handmatig genereren van de audio.
In deze zelfstudie ziet u drie verschillende manieren om tekst te converteren naar spraak vanuit Azure AI Speech:
- Client JavaScript haalt audio rechtstreeks op
- JavaScript van server haalt audio op uit bestand (*.MP3)
- JavaScript van server haalt audio op uit de geheugenmatrixBuffer
Toepassingsarchitectuur
De zelfstudie maakt gebruik van een minimale Express.js app en voegt functionaliteit toe met behulp van een combinatie van:
- nieuwe route voor de server-API om conversie van tekst naar spraak te bieden, die een MP3-stream retourneert
- nieuwe route voor een HTML-formulier zodat u uw gegevens kunt invoeren
- nieuw HTML-formulier, met JavaScript, biedt een aanroep aan de clientzijde van de Speech-service
Deze toepassing biedt drie verschillende aanroepen om spraak naar tekst te converteren:
- De eerste serveroproep maakt een bestand op de server en retourneert het vervolgens naar de client. Normaal gesproken gebruikt u dit voor langere tekst of tekst die u weet meer dan één keer moet worden weergegeven.
- De tweede serveroproep is bedoeld voor tekst op kortere termijn en wordt in het geheugen bewaard voordat deze naar de client wordt geretourneerd.
- De clientoproep demonstreert een directe aanroep naar de Speech-service met behulp van de SDK. U kunt ervoor kiezen om deze aanroep uit te voeren als u een clienttoepassing zonder server hebt.
Vereisten
Node.js LTS - geïnstalleerd op uw lokale computer.
Visual Studio Code - geïnstalleerd op uw lokale computer.
De Azure-app-service-extensie voor VS Code (geïnstalleerd vanuit VS Code).
Git : wordt gebruikt om naar GitHub te pushen, waarmee de GitHub-actie wordt geactiveerd.
Azure Cloud Shell gebruiken met behulp van de bash
Installeer de Azure CLI, indien gewenst, om CLI-referentieopdrachten uit te voeren.
- Als u een lokale installatie gebruikt, meldt u zich aan bij Azure CLI met behulp van de opdracht AZ login. Volg de stappen die worden weergegeven in de terminal, om het verificatieproces te voltooien. Zie Aanmelden met Azure CLI voor meer aanmeldingsopties.
- Installeer de Azure CLI-extensie bij het eerste gebruik, wanneer u hierom wordt gevraagd. Zie Extensies gebruiken met Azure CLI voor meer informatie over extensies.
- Voer az version uit om de geïnstalleerde versie en afhankelijke bibliotheken te vinden. Voer az upgrade uit om te upgraden naar de nieuwste versie.
Voorbeeld van Express.js opslagplaats downloaden
Kloon met git de Express.js voorbeeldopslagplaats naar uw lokale computer.
git clone https://github.com/Azure-Samples/js-e2e-express-server
Ga naar de nieuwe map voor het voorbeeld.
cd js-e2e-express-server
Open het project in Visual Studio Code.
code .
Open een nieuwe terminal in Visual Studio Code en installeer de projectafhankelijkheden.
npm install
Azure AI Speech SDK voor JavaScript installeren
Installeer de Azure AI Speech SDK vanuit de Visual Studio Code-terminal.
npm install microsoft-cognitiveservices-speech-sdk
Een Speech-module maken voor de Express.js-app
Als u de Speech SDK wilt integreren in de Express.js-toepassing, maakt u een bestand in de map met de
src
naamazure-cognitiveservices-speech.js
.Voeg de volgende code toe om afhankelijkheden op te halen en een functie te maken om tekst naar spraak te converteren.
// 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 };
- Parameters: het bestand haalt de afhankelijkheden op voor het gebruik van de SDK, streams, buffers en het bestandssysteem (fs). De
textToSpeech
functie heeft vier argumenten. Als een bestandsnaam met een lokaal pad wordt verzonden, wordt de tekst geconverteerd naar een audiobestand. Als er geen bestandsnaam wordt verzonden, wordt er een audiostream in het geheugen gemaakt. - Speech SDK-methode: de Speech SDK-methode synthesizer.speakTextAsync retourneert verschillende typen, op basis van de configuratie die wordt ontvangen.
De methode retourneert het resultaat, wat verschilt op basis van wat de methode is gevraagd om te doen:
- Bestand maken
- Een stroom in het geheugen maken als een matrix van buffers
- Audio-indeling: de geselecteerde audio-indeling is MP3, maar andere indelingen bestaan, samen met andere audioconfiguratiemethoden.
De lokale methode,
textToSpeech
verpakt en converteert de SDK-call-back-functie naar een belofte.- Parameters: het bestand haalt de afhankelijkheden op voor het gebruik van de SDK, streams, buffers en het bestandssysteem (fs). De
Een nieuwe route maken voor de Express.js-app
Open het bestand
src/server.js
.Voeg de
azure-cognitiveservices-speech.js
module toe als een afhankelijkheid boven aan het bestand:const { textToSpeech } = require('./azure-cognitiveservices-speech');
Voeg een nieuwe API-route toe om de textToSpeech-methode aan te roepen die in de vorige sectie van de zelfstudie is gemaakt. Voeg deze code toe na de
/api/hello
route.// 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); });
Deze methode gebruikt de vereiste en optionele parameters voor de
textToSpeech
methode uit de querystring. Als er een bestand moet worden gemaakt, wordt er een unieke bestandsnaam ontwikkeld. DetextToSpeech
methode wordt asynchroon aangeroepen en geeft het resultaat door aan het antwoordobject (res
).
De clientwebpagina bijwerken met een formulier
Werk de HTML-webpagina van de client bij met een formulier waarmee de vereiste parameters worden verzameld. De optionele parameter wordt doorgegeven op basis van welk audio-besturingselement de gebruiker selecteert. Omdat deze zelfstudie een mechanisme biedt voor het aanroepen van de Azure Speech-service van de client, wordt dat JavaScript ook geleverd.
Open het /public/client.html
bestand en vervang de inhoud door het volgende:
<!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>
Gemarkeerde regels in het bestand:
- Regel 74: De Azure Speech SDK wordt in de clientbibliotheek opgehaald met behulp van de
cdn.jsdelivr.net
site om het NPM-pakket te leveren. - Regel 102: De
updateSrc
methode werkt de URL van de audiobesturingselementensrc
bij met de querytekenreeks, inclusief de sleutel, regio en tekst. - Regel 137: Als een gebruiker de
Get directly from Azure
knop selecteert, roept de webpagina rechtstreeks aan naar Azure vanaf de clientpagina en verwerkt het resultaat.
Een Azure AI Speech-resource maken
Maak de Spraakresource met Azure CLI-opdrachten in een Azure Cloud Shell.
Meld u aan bij Azure Cloud Shell. Hiervoor moet u zich verifiëren in een browser met uw account, dat is gemachtigd voor een geldig Azure-abonnement.
Maak een resourcegroep voor uw Speech-resource.
az group create \ --location eastus \ --name tutorial-resource-group-eastus
Maak een Spraak-resource in de resourcegroep.
az cognitiveservices account create \ --kind SpeechServices \ --location eastus \ --name tutorial-speech \ --resource-group tutorial-resource-group-eastus \ --sku F0
Deze opdracht mislukt als uw enige vrije Spraak-resource al is gemaakt.
Gebruik de opdracht om de sleutelwaarden voor de nieuwe Spraak-resource op te halen.
az cognitiveservices account keys list \ --name tutorial-speech \ --resource-group tutorial-resource-group-eastus \ --output table
Kopieer een van de sleutels.
U gebruikt de sleutel door deze in het webformulier van de Express-app te plakken om te verifiëren bij de Azure Speech-service.
De Express.js-app uitvoeren om tekst naar spraak te converteren
Start de app met de volgende bash-opdracht.
npm start
Open de web-app in een browser.
http://localhost:3000
Plak uw spraaktoets in het gemarkeerde tekstvak.
U kunt de tekst desgewenst wijzigen in iets nieuws.
Selecteer een van de drie knoppen om de conversie naar de audio-indeling te starten:
- Rechtstreeks vanuit Azure ophalen - aanroepen aan de clientzijde naar Azure
- Audiobesturing voor audio uit bestand
- Audiobesturing voor audio vanuit buffer
U ziet mogelijk een kleine vertraging tussen het selecteren van het besturingselement en het afspelen van het geluid.
Nieuwe Azure-app-service maken in Visual Studio Code
Typ 'web maken' in het opdrachtenpalet (Ctrl+Shift+P) en selecteer Azure-app Service: Nieuwe web-app maken... Geavanceerd. U gebruikt de geavanceerde opdracht om volledige controle te hebben over de implementatie, inclusief resourcegroep, App Service-plan en besturingssysteem in plaats van linux-standaardinstellingen te gebruiken.
Reageer als volgt op de aanwijzingen:
- Selecteer uw abonnementsaccount .
- Voer een wereldwijd unieke naam in, zoals
my-text-to-speech-app
.- Voer een naam in die uniek is in heel Azure. Gebruik alleen alfanumerieke tekens ('A-Z', 'a-z' en '0-9') en afbreekstreepjes ('-')
- Selecteer
tutorial-resource-group-eastus
deze optie voor de resourcegroep. - Selecteer een runtimestack van een versie die deze bevat
Node
enLTS
. - Selecteer het Linux-besturingssysteem.
- Selecteer Een nieuw App Service-plan maken, geef een naam op zoals
my-text-to-speech-app-plan
. - Selecteer de gratis F1-prijscategorie. Als uw abonnement al een gratis web-app heeft, selecteert u de
Basic
laag. - Selecteer Nu overslaan voor de Application Insights-resource.
- Selecteer de
eastus
locatie.
Na een korte tijd meldt Visual Studio Code u dat het maken is voltooid. Sluit de melding met de X-knop .
Lokale Express.js-app implementeren in externe App Service in Visual Studio Code
Implementeer uw code vanaf de lokale computer met de web-app. Selecteer het Azure-pictogram om de Azure-app Service Explorer te openen, vouw uw abonnementsknooppunt uit, klik met de rechtermuisknop op de naam van de web-app die u zojuist hebt gemaakt en selecteer Implementeren in web-app.
Als er implementatieprompts zijn, selecteert u de hoofdmap van de Express.js-app, selecteert u uw abonnementsaccount opnieuw en selecteert u vervolgens de naam van de web-app,
my-text-to-speech-app
die u eerder hebt gemaakt.Als u wordt gevraagd om uit te voeren
npm install
bij de implementatie in Linux, selecteert u Ja als u wordt gevraagd de configuratie bij te werken die op de doelserver moet worden uitgevoerdnpm install
.Zodra de implementatie is voltooid, selecteert u Bladeren website in de prompt om uw nieuw geïmplementeerde web-app weer te geven.
(Optioneel): U kunt wijzigingen aanbrengen in uw codebestanden en vervolgens de web-app implementeren in de Azure-app-serviceextensie gebruiken om de web-app bij te werken.
Externe servicelogboeken streamen in Visual Studio Code
Bekijk (tail) uitvoer die de actieve app genereert via aanroepen naar console.log
. Deze uitvoer wordt weergegeven in het uitvoervenster in Visual Studio Code.
Klik in de Azure-app Service Explorer met de rechtermuisknop op het nieuwe app-knooppunt en kies Streaminglogboeken starten.
Starting Live Log Stream ---
Vernieuw de webpagina een paar keer in de browser om extra logboekuitvoer weer te geven.
Resources opschonen door resourcegroep te verwijderen
Nadat u deze zelfstudie hebt voltooid, moet u de resourcegroep, die de resource bevat, verwijderen om ervoor te zorgen dat u niet meer wordt gefactureerd voor gebruik.
Gebruik in Azure Cloud Shell de Azure CLI-opdracht om de resourcegroep te verwijderen:
az group delete --name tutorial-resource-group-eastus -y
Deze opdracht kan enkele minuten duren.