Dela via


Express.js-appen konverterar text till tal med Cognitive Services Speech

I den här självstudien lägger du till Cognitive Services Speech i en befintlig Express.js-app för att lägga till konvertering från text till tal med hjälp av Cognitive Services Speech-tjänsten. Om du konverterar text till tal kan du tillhandahålla ljud utan att behöva generera ljudet manuellt.

Den här självstudien visar tre olika sätt att konvertera text till tal från Azure Cognitive Services Speech:

  • JavaScript-klienten hämtar ljud direkt
  • Server JavaScript hämtar ljud från filen (*.MP3)
  • Server JavaScript hämtar ljud från minnesintern matrisBuffer

Programmets arkitektur

Självstudien tar en minimal Express.js-app och lägger till funktioner med hjälp av en kombination av:

  • ny väg för server-API:et för att tillhandahålla konvertering från text till tal och returnera en MP3-ström
  • ny väg för ett HTML-formulär så att du kan ange din information
  • nytt HTML-formulär, med JavaScript, tillhandahåller ett anrop på klientsidan till Speech-tjänsten

Det här programmet tillhandahåller tre olika anrop för att konvertera tal till text:

  • Det första serveranropet skapar en fil på servern och returnerar den sedan till klienten. Du använder vanligtvis detta för längre text eller text som du vet bör hanteras mer än en gång.
  • Det andra serveranropet är för kortare text och lagras i minnet innan det returneras till klienten.
  • Klientanropet visar ett direktanrop till Speech-tjänsten med hjälp av SDK:et. Du kan välja att göra det här anropet om du har ett klientprogram utan server.

Förutsättningar

Ladda ned express.js-exempel-lagringsplats

  1. Med git klonar du express.js-exempelrepoen till den lokala datorn.

    git clone https://github.com/Azure-Samples/js-e2e-express-server
    
  2. Ändra till den nya katalogen för exemplet.

    cd js-e2e-express-server
    
  3. Öppna projektet i Visual Studio Code.

    code .
    
  4. Öppna en ny terminal i Visual Studio Code och installera projektberoendena.

    npm install
    

Installera Cognitive Services Speech SDK för JavaScript

Från Visual Studio Code-terminalen installerar du Azure Cognitive Services Speech SDK.

npm install microsoft-cognitiveservices-speech-sdk

Skapa en Speech-modul för Express.js-appen

  1. Om du vill integrera Speech SDK i Express.js-programmet skapar du en fil i src mappen med namnet azure-cognitiveservices-speech.js.

  2. Lägg till följande kod för att hämta beroenden och skapa en funktion för att konvertera text till tal.

    // 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
    };
    
    • Parametrar – Filen hämtar beroendena för att använda SDK, strömmar, buffertar och filsystemet (fs). Funktionen textToSpeech tar fyra argument. Om ett filnamn med lokal sökväg skickas konverteras texten till en ljudfil. Om ett filnamn inte skickas skapas en minnesintern ljudström.
    • Speech SDK-metod – Speech SDK-metoden synthesizer.speakTextAsync returnerar olika typer, baserat på den konfiguration som den tar emot. Metoden returnerar resultatet, som skiljer sig beroende på vad metoden ombads att göra:
      • Skapa fil
      • Skapa minnesintern ström som en matris med buffertar
    • Ljudformat – Det valda ljudformatet är MP3, men det finns andra format , tillsammans med andra ljudkonfigurationsmetoder.

    Den lokala metoden, textToSpeech, omsluter och konverterar SDK-återanropsfunktionen till ett löfte.

Skapa en ny väg för Express.js-appen

  1. Öppna src/server.js-filen.

  2. Lägg till modulen azure-cognitiveservices-speech.js som ett beroende överst i filen:

    const { textToSpeech } = require('./azure-cognitiveservices-speech');
    
  3. Lägg till en ny API-väg för att anropa metoden textToSpeech som skapades i föregående avsnitt i självstudien. Lägg till den här koden efter /api/hello vägen.

    // 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);
    });
    

    Den här metoden tar de obligatoriska och valfria parametrarna textToSpeech för metoden från frågesträngen. Om en fil behöver skapas utvecklas ett unikt filnamn. Metoden textToSpeech kallas asynkront och skickar resultatet till svarsobjektet (res).

Uppdatera klientwebbsidan med ett formulär

Uppdatera klientens HTML-webbsida med ett formulär som samlar in nödvändiga parametrar. Den valfria parametern skickas in baserat på vilken ljudkontroll användaren väljer. Eftersom den här självstudien innehåller en mekanism för att anropa Azure Speech-tjänsten från klienten tillhandahålls även JavaScript.

/public/client.html Öppna filen och ersätt dess innehåll med följande:

<!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&region=${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>

Markerade rader i filen:

  • Rad 74: Azure Speech SDK hämtas till klientbiblioteket med hjälp av cdn.jsdelivr.net platsen för att leverera NPM-paketet.
  • Rad 102: Metoden updateSrc uppdaterar ljudkontrollernas src URL med frågesträngen, inklusive nyckel, region och text.
  • Rad 137: Om en användare väljer knappen anropar Get directly from Azure webbsidan direkt till Azure från klientsidan och bearbetar resultatet.

Skapa Cognitive Services Speech-resurs

Skapa Speech-resursen med Azure CLI-kommandon i ett Azure Cloud Shell.

  1. Logga in på Azure Cloud Shell. Detta kräver att du autentiserar i en webbläsare med ditt konto, som har behörighet för en giltig Azure-prenumeration.

  2. Skapa en resursgrupp för din Speech-resurs.

    az group create \
        --location eastus \
        --name tutorial-resource-group-eastus
    
  3. Skapa en Speech-resurs i resursgruppen.

    az cognitiveservices account create \
        --kind SpeechServices \
        --location eastus \
        --name tutorial-speech \
        --resource-group tutorial-resource-group-eastus \
        --sku F0
    

    Det här kommandot misslyckas om din enda kostnadsfria Speech-resurs redan har skapats.

  4. Använd kommandot för att hämta nyckelvärdena för den nya Speech-resursen.

    az cognitiveservices account keys list \
        --name tutorial-speech \
        --resource-group tutorial-resource-group-eastus \
        --output table
    
  5. Kopiera en av nycklarna.

    Du använder nyckeln genom att klistra in den i webbformen för Express-appen för att autentisera till Azure Speech-tjänsten.

Kör Express.js-appen för att konvertera text till tal

  1. Starta appen med följande bash-kommando.

    npm start
    
  2. Öppna webbappen i en webbläsare.

    http://localhost:3000    
    
  3. Klistra in talnyckeln i den markerade textrutan.

    Browser screenshot of web form with Speech key input field highlighted.

  4. Du kan också ändra texten till något nytt.

  5. Välj en av de tre knapparna för att påbörja konverteringen till ljudformatet:

    • Hämta direkt från Azure – anrop på klientsidan till Azure
    • Ljudkontroll för ljud från fil
    • Ljudkontroll för ljud från buffert

    Du kanske märker en liten fördröjning mellan att välja kontrollen och ljudet som spelas upp.

Skapa en ny Azure App Service i Visual Studio Code

  1. Från kommandopaletten (Ctrl+Skift+P) skriver du "skapa webb" och väljer Azure App Service: Skapa ny webbapp... Avancerat. Du använder det avancerade kommandot för att ha fullständig kontroll över distributionen, inklusive resursgrupp, App Service-plan och operativsystem i stället för att använda Linux-standardvärden.

  2. Svara på anvisningarna på följande sätt:

    • Välj ditt prenumerationskonto .
    • För Ange ett globalt unikt namn som my-text-to-speech-app.
      • Ange ett namn som är unikt i hela Azure. Använd endast alfanumeriska tecken ('A-Z', 'a-z', '0-9') och bindestreck ('-')
    • Välj tutorial-resource-group-eastus för resursgruppen.
    • Välj en körningsstack av en version som innehåller Node och LTS.
    • Välj operativsystemet Linux.
    • Välj Skapa en ny App Service-plan och ange ett namn som my-text-to-speech-app-plan.
    • Välj den kostnadsfria prisnivån F1. Om din prenumeration redan har en kostnadsfri webbapp väljer du Basic nivån.
    • Välj Hoppa över för tillfället för Application Insights-resursen.
    • Välj platsen eastus .
  3. Efter en kort stund meddelar Visual Studio Code att skapandet är klart. Stäng meddelandet med X-knappen .

Distribuera lokal Express.js-app till fjärrapptjänsten i Visual Studio Code

  1. När webbappen är på plats distribuerar du koden från den lokala datorn. Välj Azure-ikonen för att öppna Azure App Service-utforskaren, expandera din prenumerationsnod, högerklicka på namnet på den webbapp som du nyss skapade och välj Distribuera till webbapp.

  2. Om det finns distributionsprompter väljer du rotmappen för Express.js-appen, väljer ditt prenumerationskonto igen och väljer sedan namnet på webbappen, my-text-to-speech-app, som skapades tidigare.

  3. Om du uppmanas att köra npm install när du distribuerar till Linux väljer du Ja om du uppmanas att uppdatera konfigurationen så att den körs npm install på målservern.

    Prompt to update configuration on the target Linux server

  4. När distributionen är klar väljer du Bläddra på webbplatsen i prompten för att visa din nyligen distribuerade webbapp.

  5. (Valfritt): Du kan göra ändringar i kodfilerna och sedan använda Distribuera till webbapp i Azure App Service-tillägget för att uppdatera webbappen.

Strömma fjärrtjänstloggar i Visual Studio Code

Visa (tail) alla utdata som appen som körs genererar via anrop till console.log. Utdata visas i utdatafönstret i Visual Studio Code.

  1. I Azure App Service-utforskaren högerklickar du på den nya appnoden och väljer Starta direktuppspelningsloggar.

     Starting Live Log Stream ---
     
  2. Uppdatera webbsidan några gånger i webbläsaren för att se ytterligare loggutdata.

Rensa resurser genom att ta bort resursgruppen

När du har slutfört den här självstudien måste du ta bort resursgruppen, som innehåller resursen, för att se till att du inte debiteras för mer användning.

I Azure Cloud Shell använder du Azure CLI-kommandot för att ta bort resursgruppen:

az group delete --name tutorial-resource-group-eastus  -y

Det här kommandot kan ta några minuter.

Nästa steg