繁体   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