Aplikace Express.js převádí text na řeč pomocí služeb Cognitive Services Speech.

V tomto kurzu přidejte službu Cognitive Services Speech do existující aplikace Express.js a přidejte převod z textu na řeč pomocí služby Cognitive Services Speech. Převod textu na řeč umožňuje poskytovat zvuk bez nákladů na ruční generování zvuku.

Tento kurz ukazuje 3 různé způsoby převodu textu na řeč ze služby Azure Cognitive Services Speech:

  • Klientský JavaScript získá přímo zvuk.
  • Server JavaScript získává zvuk ze souboru (*.MP3)
  • Server JavaScript získává zvuk z pole v pamětiBuffer

Architektura aplikace

Tento kurz používá minimální aplikaci Express.js a přidává funkce pomocí kombinace:

  • nová trasa pro serverové rozhraní API pro zajištění převodu textu na řeč a vrácení datového proudu MP3
  • nová trasa formuláře HTML, která vám umožní zadat informace
  • Nový formulář HTML s JavaScriptem poskytuje volání služby Speech na straně klienta.

Tato aplikace poskytuje tři různá volání převodu řeči na text:

  • První volání serveru vytvoří na serveru soubor a pak ho vrátí klientovi. Obvykle byste ho použili pro delší text nebo text, který víte, by se měl obsloužit více než jednou.
  • Druhé volání serveru je určené pro kratší text a uchovává se v paměti před vrácením klientovi.
  • Volání klienta ukazuje přímé volání služby Speech pomocí sady SDK. Toto volání můžete provést, pokud máte aplikaci jen pro klienta bez serveru.

Požadavky

  • Node.js LTS – nainstalovaný na místním počítači.
  • Visual Studio Code – nainstalovaný na místním počítači.
  • Rozšíření služby Aplikace Azure pro VS Code (nainstalované z VS Code).
  • Git – použitý k nasdílení změn do GitHubu – který aktivuje akci GitHubu.
  • Použití Azure Cloud Shellu pomocí bashe Embed launch
  • Pokud tomu dáváte přednost, můžete nainstalovat Azure CLI a spouštět referenční příkazy CLI.
    • Pokud používáte místní instalaci, přihlaste se s Azure CLI pomocí příkazu az login. Pokud chcete dokončit proces ověřování, postupujte podle kroků zobrazených na terminálu. Další možnosti přihlášení najdete v tématu Přihlášení pomocí Azure CLI .
    • Po zobrazení výzvy nainstalujte rozšíření Azure CLI při prvním použití. Další informace o rozšířeních najdete v tématu Využití rozšíření v Azure CLI.
    • Spuštěním příkazu az version zjistěte verzi a závislé knihovny, které jsou nainstalované. Pokud chcete upgradovat na nejnovější verzi, spusťte az upgrade.

Stažení ukázkového úložiště Express.js

  1. Pomocí Gitu naklonujte ukázkové úložiště Express.js do místního počítače.

    git clone https://github.com/Azure-Samples/js-e2e-express-server
    
  2. Přejděte do nového adresáře ukázky.

    cd js-e2e-express-server
    
  3. Otevřete projekt v editoru Visual Studio Code.

    code .
    
  4. Otevřete nový terminál v editoru Visual Studio Code a nainstalujte závislosti projektu.

    npm install
    

Instalace sady Cognitive Services Speech SDK pro JavaScript

Z terminálu Visual Studio Code nainstalujte sadu Azure Cognitive Services Speech SDK.

npm install microsoft-cognitiveservices-speech-sdk

Vytvoření modulu Speech pro aplikaci Express.js

  1. Pokud chcete integrovat sadu Speech SDK do aplikace Express.js, vytvořte soubor ve src složce s názvem azure-cognitiveservices-speech.js.

  2. Přidejte následující kód pro vyžádání závislostí a vytvoření funkce pro převod textu na řeč.

    // 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
    };
    
    • Parametry – soubor načítá závislosti pro použití sady SDK, datových proudů, vyrovnávacích pamětí a systému souborů (fs). Funkce textToSpeech přebírá čtyři argumenty. Pokud se odešle název souboru s místní cestou, text se převede na zvukový soubor. Pokud se neodesílají název souboru, vytvoří se zvukový stream v paměti.
    • Metoda sady Speech SDK – Syntetizátor.speakTextAsync sady Speech SDK vrací různé typy na základě konfigurace, kterou přijímá. Metoda vrátí výsledek, který se liší podle toho, co byla metoda požádána:
      • Vytvořit soubor
      • Vytvoření datového proudu v paměti jako pole vyrovnávacích pamětí
    • Formát zvuku – Vybraný formát zvuku je MP3, ale existují i jiné formáty spolu s dalšími metodami konfigurace zvuku.

    Místní metoda , textToSpeechzabalí a převede funkci zpětného volání sady SDK na příslib.

Vytvoření nové trasy pro aplikaci Express.js

  1. Otevřete soubor src/server.js.

  2. azure-cognitiveservices-speech.js Přidejte modul jako závislost v horní části souboru:

    const { textToSpeech } = require('./azure-cognitiveservices-speech');
    
  3. Přidejte novou trasu rozhraní API pro volání metody textToSpeech vytvořené v předchozí části kurzu. Přidejte tento kód za trasu /api/hello .

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

    Tato metoda přebírá požadované a volitelné parametry pro metodu textToSpeech z řetězce dotazu. Pokud je potřeba vytvořit soubor, vytvoří se jedinečný název souboru. Metoda textToSpeech se nazývá asynchronně a kanáluje výsledek do objektu odpovědi (res).

Aktualizace webové stránky klienta pomocí formuláře

Aktualizujte webovou stránku HTML klienta formulářem, který shromažďuje požadované parametry. Volitelný parametr se předává na základě toho, který ovládací prvek zvuku uživatel vybere. Vzhledem k tomu, že tento kurz poskytuje mechanismus pro volání služby Azure Speech z klienta, poskytuje se také JavaScript.

/public/client.html Otevřete soubor a nahraďte jeho obsah následujícím kódem:

<!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>

Zvýrazněné řádky v souboru:

  • Řádek 74: Sada Azure Speech SDK se načte do klientské knihovny pomocí cdn.jsdelivr.net lokality k doručení balíčku NPM.
  • Řádek 102: Metoda updateSrc aktualizuje adresu URL ovládacích prvků src zvuku řetězcem dotazu, včetně klíče, oblasti a textu.
  • Řádek 137: Pokud uživatel tlačítko vybere Get directly from Azure , webová stránka zavolá přímo do Azure ze stránky klienta a zpracuje výsledek.

Vytvoření prostředku služby Cognitive Services Speech

Vytvořte prostředek služby Speech pomocí příkazů Azure CLI v Azure Cloud Shellu.

  1. Přihlaste se ke službě Azure Cloud Shell. To vyžaduje, abyste se ověřili v prohlížeči pomocí svého účtu, který má oprávnění k platnému předplatnému Azure.

  2. Vytvořte skupinu prostředků pro prostředek služby Speech.

    az group create \
        --location eastus \
        --name tutorial-resource-group-eastus
    
  3. Vytvořte prostředek služby Speech ve skupině prostředků.

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

    Tento příkaz selže, pokud už byl vytvořen váš jediný prostředek bezplatné služby Speech.

  4. Pomocí příkazu získejte hodnoty klíče pro nový prostředek služby Speech.

    az cognitiveservices account keys list \
        --name tutorial-speech \
        --resource-group tutorial-resource-group-eastus \
        --output table
    
  5. Zkopírujte jeden z klíčů.

    Klíč použijete tak, že ho vložíte do webové formy aplikace Express k ověření ve službě Azure Speech.

Spuštěním aplikace Express.js převeďte text na řeč.

  1. Spusťte aplikaci pomocí následujícího příkazu Bash.

    npm start
    
  2. Otevřete webovou aplikaci v prohlížeči.

    http://localhost:3000    
    
  3. Vložte klávesu Speech do zvýrazněného textového pole.

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

  4. Volitelně můžete změnit text na něco nového.

  5. Výběrem jednoho ze tří tlačítek zahájíte převod na zvukový formát:

    • Získání přímo z Azure – volání na straně klienta do Azure
    • Ovládací prvek zvuku pro zvuk ze souboru
    • Ovládací prvek zvuku pro zvuk z vyrovnávací paměti

    Mezi výběrem ovládacího prvku a přehráváním zvuku si můžete všimnout malé prodlevy.

Vytvoření nové služby Aplikace Azure v editoru Visual Studio Code

  1. Na paletě příkazů (Ctrl+Shift+P) zadejte "create web" a vyberte Aplikace Azure Service: Create New Web App... Upřesnit. Pomocí rozšířeného příkazu můžete mít úplnou kontrolu nad nasazením, včetně skupiny prostředků, plánu služby App Service a operačního systému, a ne k použití výchozích hodnot Linuxu.

  2. Na tyto výzvy odpovíte následujícím způsobem:

    • Vyberte svůj účet předplatného .
    • Zadejte globálně jedinečný název , například my-text-to-speech-app.
      • Zadejte název, který je jedinečný ve všech Azure. Používejte pouze alfanumerické znaky (A-Z, a-z a-z a 0-9) a spojovníky (-).
    • Vyberte tutorial-resource-group-eastus skupinu prostředků.
    • Vyberte zásobník modulu runtime verze, která obsahuje Node a LTS.
    • Vyberte operační systém Linux.
    • Vyberte Vytvořit nový plán služby App Service a zadejte název, například my-text-to-speech-app-plan.
    • Vyberte cenovou úroveň F1 Free. Pokud už vaše předplatné má bezplatnou webovou aplikaci, vyberte Basic úroveň.
    • Pro prostředek Přehledy aplikace vyberte Přeskočit.
    • eastus Vyberte umístění.
  3. Po krátké době vás Visual Studio Code upozorní, že vytvoření je hotové. Zavřete oznámení tlačítkem X .

Nasazení místní aplikace Express.js do vzdálené služby App Service v editoru Visual Studio Code

  1. S webovou aplikací nasaďte kód z místního počítače. Výběrem ikony Azure otevřete Aplikace Azure Service Explorer, rozbalte uzel předplatného, klikněte pravým tlačítkem na název webové aplikace, kterou jste právě vytvořili, a vyberte Nasadit do webové aplikace.

  2. Pokud se zobrazí výzvy k nasazení, vyberte kořenovou složku aplikace Express.js, znovu vyberte svůj účet předplatného a pak vyberte název webové aplikace, my-text-to-speech-appkterou jste vytvořili dříve.

  3. Pokud se zobrazí výzva ke spuštění npm install při nasazování do Linuxu, vyberte ano , pokud se zobrazí výzva k aktualizaci konfigurace, aby se spustila npm install na cílovém serveru.

    Prompt to update configuration on the target Linux server

  4. Po dokončení nasazení vyberte na příkazovém řádku procházet web , abyste zobrazili nově nasazenou webovou aplikaci.

  5. (Volitelné): V souborech kódu můžete provádět změny a pak pomocí rozšíření služby Aplikace Azure aktualizovat webovou aplikaci pomocí nástroje Deploy to Web App( v rozšíření služby Aplikace Azure).

Streamování protokolů vzdálené služby v editoru Visual Studio Code

Zobrazte (tail) jakýkoli výstup, který spuštěná aplikace generuje prostřednictvím volání console.log. Tento výstup se zobrazí v okně Výstup v editoru Visual Studio Code.

  1. V Aplikace Azure Service Exploreru klikněte pravým tlačítkem na nový uzel aplikace a zvolte Spustit protokoly streamování.

     Starting Live Log Stream ---
     
  2. Aktualizujte webovou stránku několikrát v prohlížeči, abyste viděli další výstup protokolu.

Vyčištění prostředků odebráním skupiny prostředků

Po dokončení tohoto kurzu je potřeba odebrat skupinu prostředků, která obsahuje prostředek, abyste se ujistili, že se vám neúčtuje žádné další využití.

V Azure Cloud Shellu pomocí příkazu Azure CLI odstraňte skupinu prostředků:

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

Tento příkaz může trvat několik minut.

Další kroky