Nodejs & Angular - Google 文字转语音

Nodejs & Angular - Google Text-To-Speech

我想通过 REST 从我的客户端 (Angular v.12) 发送文本到后端 API 这样我就可以取回音频,然后在客户端使用新的音频(...)并能够在用户点击时播放声音。

我的后台是这样的:

const express = require("express");
const cors = require("cors");
const textToSpeech = require('@google-cloud/text-to-speech');
const stream = require("stream");
const app = express();

app.get('/api/tts', async (req, res) => {
  const txt = req.query.txt
  console.log('txt', txt);
  const client = new textToSpeech.TextToSpeechClient();
  const request = {
    input: {text: txt},
    voice: {languageCode: 'en-US', ssmlGender: 'NEUTRAL'},
    audioConfig: {audioEncoding: 'MP3'},
  };
  const [response] = await client.synthesizeSpeech(request);
  const readStream = new stream.PassThrough();

  readStream.end(response.audioContent);
  res.set("Content-disposition", 'attachment; filename=' + 'audio.mp3');
  res.set("Content-Type", "audio/mpeg");

  readStream.pipe(res);
})

现在在我的客户端中,我刚刚创建了一个按钮进行测试,点击后我发送了一个 HTTP 请求,如下所示:

  public textToSpeech(txt: string) {
    let httpParams: HttpParams = new HttpParams()
      .set('txt', txt)
    return this.http.get('//localhost:3030/api/tts', { params: httpParams, responseType: 'text' })

  }

我收到一个 200 OK 代码和一个长字符串作为响应。

在我的组件中:

  onButtonClick() {
this.speechService.textToSpeech('testing')
.subscribe(res => {
  this.audio = new Audio(res)
  this.audio.play()
})

}

但我收到以下错误:

GET http://localhost:4200/��D�

Uncaught (in promise) DOMException: The media resource indicated by the src attribute or assigned media provider object was not suitable.

好的,所以我用不同的方法解决了它。 在后端,我使用 fs 将 MP3 文件写入并创建到 public 文件夹,然后在前端,我将 link 作为源文件放入文件中,如下所示:

后端:

app.get('/api/tts', async (req, res) => {
  const {text} = req.query
  const client = new textToSpeech.TextToSpeechClient();
  const request = {
    input: {text},
    voice: {languageCode: 'en-US', ssmlGender: 'FEMALE'},
    audioConfig: {audioEncoding: 'MP3'},
  };
  const [response] = await client.synthesizeSpeech(request);
  const writeFile = util.promisify(fs.writeFile);
  await writeFile(`./public/audio/${text}.mp3`, response.audioContent, 'binary');
  res.end()
})

前端:

  onButtonClick() {
    this.speechService.textToSpeech('hello')
      .subscribe(res => {
        
        this.audio = new Audio(`//localhost:3030/audio/hello.mp3`)
        this.audio.play()
      })
  }

它现在是硬编码的,但我打算让它动态化,只是想测试一下。

我不知道这是否是最好的方法,但我让它按照我想要的方式工作。