Aplikasi Express.js mengonversi teks ke ucapan dengan Ucapan Cognitive Services

Dalam tutorial ini, tambahkan Cognitive Services untuk Ucapan ke aplikasi Express.js yang ada untuk menambahkan konversi dari teks ke ucapan menggunakan layanan Cognitive Services untuk ucapan. Mengonversi teks ke ucapan memungkinkan Anda menyediakan audio tanpa biaya menghasilkan audio secara manual.

Tutorial ini menunjukkan 3 cara berbeda untuk mengonversi teks ke ucapan dari Ucapan Azure Cognitive Services:

  • JavaScript Klien mendapatkan audio secara langsung
  • JavaScript Server mendapatkan audio dari file (*.MP3)
  • JavaScript Server mendapatkan audio dari arrayBuffer dalam memori

Arsitektur aplikasi

Tutorial ini menggunakan aplikasi Express.js minimal dan menambahkan fungsionalitas menggunakan kombinasi dari:

  • rute baru untuk API server guna memberikan konversi dari teks ke ucapan, mengembalikan aliran MP3
  • rute baru untuk formulir HTML guna memungkinkan Anda memasukkan informasi
  • formulir HTML baru, dengan JavaScript, yang menyediakan panggilan sisi klien ke layanan Ucapan

Aplikasi ini menyediakan tiga panggilan berbeda untuk mengonversi ucapan ke teks:

  • Panggilan server pertama membuat file di server kemudian mengembalikannya ke klien. Anda biasanya akan menggunakan ini untuk teks yang lebih panjang atau teks yang Anda tahu harus disajikan lebih dari sekali.
  • Panggilan server kedua adalah untuk teks jangka pendek dan disimpan dalam memori sebelum ditampilkan ke klien.
  • Panggilan klien menunjukkan panggilan langsung ke layanan Ucapan menggunakan SDK. Anda dapat memilih untuk melakukan panggilan ini jika Anda memiliki aplikasi khusus klien tanpa server.

Prasyarat

  • Node.js LTS - diinstal ke komputer lokal Anda.
  • Visual Studio Code - diinstal ke komputer lokal Anda.
  • Ekstensi Azure App Service untuk Visual Studio Code (diinstal dari dalam Visual Studio Code).
  • Git - digunakan untuk mendorong ke GitHub - yang mengaktifkan tindakan GitHub.
  • Menggunakan Azure Cloud Shell menggunakan bash Embed launch
  • Jika mau, instal Azure CLI untuk menjalankan perintah referensi CLI.
    • Jika Anda menggunakan instalasi lokal, masuk ke Azure CLI dengan menggunakan perintah login az. Untuk menyelesaikan proses autentikasi, ikuti langkah-langkah yang ditampilkan di terminal Anda. Lihat Masuk dengan Azure CLI untuk opsi masuk tambahan.
    • Saat diminta, pasang ekstensi saat pertama kali menggunakan Azure CLI. Untuk informasi selengkapnya tentang ekstensi, lihat Menggunakan ekstensi dengan Azure CLI.
    • Jalankan versi az untuk menemukan versi dan pustaka dependen yang diinstal. Untuk meningkatkan ke versi terbaru, jalankan peningkatan az.

Unduh sampel repositori Express.js

  1. Dengan menggunakan git, kloning repositori sampel Express.js ke komputer lokal Anda.

    git clone https://github.com/Azure-Samples/js-e2e-express-server
    
  2. Ubah ke direktori baru untuk sampel.

    cd js-e2e-express-server
    
  3. Buka proyek di Visual Studio Code.

    code .
    
  4. Buka terminal baru di Visual Studio Code dan instal dependensi proyek.

    npm install
    

Instal SDK Ucapan Cognitive Services untuk JavaScript

Dari terminal Visual Studio Code, instal SDK Ucapan Azure Cognitive Services.

npm install microsoft-cognitiveservices-speech-sdk

Membuat modul Azure Cognitive Service untuk Ucapan untuk aplikasi Express.js

  1. Untuk mengintegrasikan SDK Azure Cognitive Service untuk Ucapan ke dalam aplikasi Express.js, buat file di folder src bernama azure-cognitiveservices-speech.js.

  2. Tambahkan kode berikut untuk menarik dependensi dan membuat fungsi untuk mengonversi teks ke ucapan.

    // 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
    };
    
    • Parameter - File menarik dependensi untuk menggunakan SDK, aliran, buffer, dan sistem file (fs). Fungsi textToSpeech membutuhkan empat argumen. Jika nama file dengan jalur lokal dikirim, teks dikonversi ke file audio. Jika nama file tidak dikirim, aliran audio dalam memori akan dibuat.
    • Metode SDK Azure Cognitive Service untuk Ucapan - Metode SDK Azure Cognitive Service untuk Ucapan synthesizer.speakTextAsync menampilkan berbagai jenis, berdasarkan konfigurasi yang diterimanya. Metode mengembalikan hasil, yang berbeda berdasarkan apa yang diminta untuk dilakukan metode:
      • Membuat file
      • Membuat aliran dalam memori sebagai array Buffer
    • Format audio - Format audio yang dipilih adalah MP3, tetapi format lain ada, bersama dengan Metode konfigurasi audio lainnya.

    Metode lokal, textToSpeech, membungkus dan mengubah fungsi panggilan balik SDK menjadi janji.

Membuat rute baru untuk aplikasi Express.js

  1. Buka file src/server.js.

  2. Tambahkan modul azure-cognitiveservices-speech.js sebagai dependensi di bagian atas file:

    const { textToSpeech } = require('./azure-cognitiveservices-speech');
    
  3. Tambahkan rute API baru untuk memanggil metode textToSpeech yang dibuat di bagian tutorial sebelumnya. Tambahkan kode ini setelah /api/hello rute.

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

    Metode ini mengambil parameter yang diperlukan dan opsional untuk metode textToSpeech dari querystring. Jika file perlu dibuat, nama file unik akan dikembangkan. Metode textToSpeech dipanggil secara asinkron dan mengalirkan hasil ke objek respons (res).

Memperbarui halaman web klien dengan formulir

Perbarui halaman web HTML klien dengan formulir yang mengumpulkan parameter yang diperlukan. Parameter opsional dilewatkan berdasarkan kontrol audio yang dipilih pengguna. Karena tutorial ini menyediakan mekanisme untuk memanggil layanan Ucapan Azure dari klien, JavaScript itu juga disediakan.

Buka file /public/client.html dan ganti isinya dengan yang berikut:

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

Baris yang disorot dalam file:

  • Baris 74: SDK Ucapan Azure ditarik ke pustaka klien, menggunakan situs cdn.jsdelivr.net untuk mengirimkan paket NPM.
  • Baris 102: Metode updateSrc memperbarui URL src kontrol audio dengan querystring termasuk kunci, wilayah, dan teks.
  • Baris 137: Jika pengguna memilih tombol Get directly from Azure, halaman web memanggil langsung ke Azure dari halaman klien dan memproses hasilnya.

Membuat sumber daya Ucapan Cognitive Services

Buat sumber daya Ucapan dengan perintah Azure CLI di Azure Cloud Shell.

  1. Masuk ke Azure Cloud Shell. Langkah ini mengharuskan Anda untuk mengautentikasi di browser dengan akun Anda, yang memiliki izin pada Langganan Azure yang valid.

  2. Buat grup sumber daya untuk sumber daya Azure Cognitive Service untuk Ucapan Anda.

    az group create \
        --location eastus \
        --name tutorial-resource-group-eastus
    
  3. Buat sumber daya Azure Cognitive Service untuk Ucapan di grup sumber daya.

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

    Perintah ini akan gagal jika satu-satunya sumber daya Azure Cognitive Service untuk Ucapan Anda yang gratis telah dibuat.

  4. Gunakan perintah tersebut guna mendapatkan nilai kunci untuk sumber daya Azure Cognitive Service untuk Ucapan yang baru.

    az cognitiveservices account keys list \
        --name tutorial-speech \
        --resource-group tutorial-resource-group-eastus \
        --output table
    
  5. Salin salah satu kunci.

    Anda menggunakan kunci dengan menempelkannya ke dalam formulir web aplikasi Ekspres untuk mengautentikasi ke layanan Ucapan Azure.

Menjalankan aplikasi Express.js untuk mengonversi teks ke ucapan

  1. Mulai aplikasi dengan perintah bash berikut.

    npm start
    
  2. Buka aplikasi web di browser.

    http://localhost:3000    
    
  3. Tempelkan kunci Azure Cognitive Service untuk Ucapan Anda ke dalam kotak teks yang disorot.

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

  4. Secara opsional, ubah teks menjadi sesuatu yang baru.

  5. Pilih salah satu dari tiga tombol untuk memulai konversi ke format audio:

    • Dapatkan langsung dari Azure - panggilan sisi klien ke Azure
    • Kontrol audio untuk audio dari file
    • Kontrol audio untuk audio dari buffer

    Anda mungkin mengalami penundaan kecil di antara memilih kontrol dan pemutaran audio.

Membuat layanan Azure App baru di Visual Studio Code

  1. Dari palet perintah (Ctrl+Shift+P), ketik "buat web" dan pilihAzure App Service: Buat Aplikasi Web Baru...Tingkat Lanjut. Anda menggunakan perintah tingkat lanjut untuk memiliki kontrol penuh atas penyebaran termasuk grup sumber daya, Paket App Service, dan sistem operasi daripada menggunakan default Linux.

  2. Tanggapi perintah sebagai berikut:

    • Pilih akun Langganan Anda.
    • Untuk Masukkan nama yang unik secara global seperti my-text-to-speech-app.
      • Masukkan nama yang unik di seluruh Azure. Gunakan hanya karakter alfanumerik ('A-Z', 'a-z', dan '0-9') dan tanda hubung ('-')
    • Pilih tutorial-resource-group-eastus untuk grup sumber daya.
    • Pilih tumpukan runtime dari versi yang menyertakan Node dan LTS.
    • Pilih sistem operasi Linux.
    • Pilih Buat paket App Service baru, berikan nama seperti my-text-to-speech-app-plan.
    • Pilih tingkat harga gratis F1. Jika langganan Anda sudah memiliki aplikasi web gratis, pilih tingkat Basic.
    • Pilih Lewati untuk saat ini untuk sumber daya Application Insights.
    • Pilih lokasi eastus.
  3. Sesaat kemudian, Visual Studio Code memberi tahu Anda bahwa pembuatan selesai. Tutup notifikasi menggunakan tombol X.

Menyebarkan aplikasi Express.js lokal ke layanan Aplikasi jarak jauh di Visual Studio Code

  1. Dengan aplikasi web di tempat, sebarkan kode Anda dari komputer lokal. Pilih ikon Azure untuk membuka penjelajah Azure App Service, perluas node langganan Anda, klik kanan nama aplikasi web yang baru saja Anda buat, dan pilih Sebarkan ke Aplikasi Web.

  2. Jika terdapat perintah penyebaran, pilih folder akar aplikasi Express.js, pilih akun langganan Anda lagi lalu pilih nama aplikasi web, my-text-to-speech-app, yang dibuat sebelumnya.

  3. Jika diminta untuk menjalankan npm install saat menyebarkan ke Linux, pilih Ya saat diminta untuk memperbarui konfigurasi Anda guna menjalankan npm install pada server Linux target.

    Prompt to update configuration on the target Linux server

  4. Setelah penyebaran selesai, pilih Telusuri Situs Web dalam permintaan guna menampilkan aplikasi web Anda yang baru disebarkan.

  5. (Opsional): Anda dapat membuat perubahan pada file kode Anda, lalu menggunakan Sebarkan ke Aplikasi Web, di ekstensi layanan Azure App, untuk memperbarui aplikasi web.

Streaming log layanan jarak jauh di Visual Studio Code

Tampilkan (ekor) output apa pun yang dihasilkan aplikasi yang sedang berjalan melalui panggilan ke console.log. Output ini muncul di jendela Output di Visual Studio Code.

  1. Di penjelajah Azure App Service, klik kanan node aplikasi dan pilih Mulai Log Streaming.

     Starting Live Log Stream ---
     
  2. Refresh halaman web beberapa kali di browser untuk melihat output log tambahan.

Membersihkan sumber daya dengan menghapus grup sumber daya

Setelah Anda menyelesaikan tutorial ini, Anda perlu menghapus grup sumber daya, yang mencakup sumber daya, untuk memastikan Anda tidak ditagih untuk penggunaan lagi.

Di Azure Cloud Shell, gunakan perintah Azure CLI untuk menghapus grup sumber daya:

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

Perintah ini memakan waktu beberapa menit untuk dijalankan.

Langkah berikutnya