簡體   English   中英

如何使用 Node.js 在 localhost 上播放 IBM Watson Text To Speech 音頻

[英]How to play IBM Watson Text To Speech audio on localhost using Node.js

我正在構建一個 Web 應用程序,它接收來自用戶的輸入,將其傳遞給 IBM Watson Text To Speech API,然后播放結果。 應用程序的唯一頁面包含一個輸入列表,旁邊有一個“Listen”按鈕。 單擊按鈕時,我從數據庫中獲取相關文本並將其添加到 API 的有效負載中。

我能夠從 api 中獲得結果,該結果寫在 .mp3 文件上,但在應該播放音頻時,我遇到了兩種類型的問題:

  1. 第一次單擊該按鈕時,會創建文件但不播放音頻。 如果我再次按下相同的按鈕,它會播放音頻;
  2. 第二個問題是當我選擇不同的文本時,我收到以下錯誤:
    internal/buffer.js:72
  throw new ERR_OUT_OF_RANGE(type || 'offset',
  ^

RangeError [ERR_OUT_OF_RANGE]: The value of "offset" is out of range. It must be >= 0 and <= 15922. Received -1282654053
    at boundsError (internal/buffer.js:72:9)
    at Buffer.readInt32LE (internal/buffer.js:376:5)
    at TextToSpeechV1._this.repairWavHeader (C:\Users\Pedro\Documents\udemy\projetoNode\node_modules\ibm-watson\text-to-speech\v1.js:82:45)
    at IncomingMessage.<anonymous> (C:\Users\Pedro\Documents\udemy\projetoNode\node_modules\ibm-watson\text-to-speech\v1.js:45:35)
    at IncomingMessage.emit (events.js:228:7)
    at endReadableNT (_stream_readable.js:1185:12)
    at processTicksAndRejections (internal/process/task_queues.js:81:21) {
  code: 'ERR_OUT_OF_RANGE'

下面是負責調用 IBM TTS API 並播放音頻的部分代碼:

            // result from the mysql's query
            let comment = results[0].comentario;
            console.log("Comment: " + comment);

            //text_to_speech api
            let payload = {
                text: comment,
                accept: 'audio/mp3',
                voice: 'pt-BR_IsabelaV3Voice'
            }

            textToSpeech.synthesize(payload)
                .then(response => {
                    return textToSpeech.repairWavHeaderStream(response.result);
                })
                    .then(buffer => {
                        fs.writeFileSync('audio.mp3', buffer);
                        console.log('audio ok');
                    })
                .catch(err => {
                    console.log('error:', err);
                });

            const filePath = path.join(__dirname, 'audio.mp3')
            sound.play(filePath);

我正在使用 Express 和Sound-Play播放音頻文件。

你正在犯 Node.js 異步行為。 這意味着您嘗試在收到音頻之前播放音頻。 事實上,即使拋出錯誤,您也會嘗試播放音頻。 在隨后的播放中,您將播放之前下載的音頻文件。 您的緩沖區錯誤很可能與同一問題有關。

您正在響應synthesize方法的 promise,因此您可以將自己的代碼包裝到 promise 中,並且僅嘗試以 promise 的分辨率播放音頻。 如果您想保持與您相同的流程:


  textToSpeech.synthesize(payload)
    .then(response => {
      return textToSpeech.repairWavHeaderStream(response.result);
    })
    .then(buffer => {
      fs.writeFileSync('audio.mp3', buffer);
      console.log('audio ok');
      return Promise.resolve();
    })
    .then(() => {
      const filePath = path.join(__dirname, 'audio.mp3');
      sound.play(filePath);
    })
    .catch(err => {
      console.log('error:', err);
             
    });

在評論中的討論之后,很明顯您的緩沖區錯誤是因為您試圖在 .mp3 文件上調用repairWavHeaderStream 你不需要這一步,你的代碼流應該是:


  textToSpeech.synthesize(payload)
    .then(response => {
      fs.writeFileSync('audio.mp3', response.result);
      console.log('audio ok');
      return Promise.resolve();
    })
    .then(() => {
      const filePath = path.join(__dirname, 'audio.mp3');
      sound.play(filePath);
    })
    .catch(err => {
      console.log('error:', err);
             
    });

盡管理想情況下您應該在實際嘗試將其寫入文件之前添加一個檢查 response.result 實際上是緩沖區的步驟。

您應該與您對;的使用保持一致。 要么使用它們,要么不使用!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM