javascript - Google Text-toSpeech - 在前端获取音频文件

标签 javascript node.js vue.js arraybuffer google-text-to-speech

我有一个要求,我需要使用 Google Text to Speech 将一些文本转换为音频。

我正在使用 Nodejs 将文本转换为音频文件,并希望将音频输出发送到前端。

Node 代码:

const client = new textToSpeech.TextToSpeechClient();
const request = {
  input: {text: 'Hello World'},
  // Select the language and SSML voice gender (optional)
  voice: {languageCode: 'en-US', ssmlGender: 'NEUTRAL'},
  // select the type of audio encoding
  audioConfig: {audioEncoding: 'MP3'},
};

const [response] = await client.synthesizeSpeech(request);
response.audioContent包含作为缓冲区对象的音频数据,如下所示:
<Buffer ff f3 44 c4 00 00 00 03 48 00 00 00 00 ff 88 89 40 04 06 3d d1 38 20 e1 3b f5 83 f0 7c 1f 0f c1 30 7f 83 ef 28 08 62 00 c6 20 0c 62 03 9f e2 77 d6 0f ... > 

我将此作为 api 响应发送到前端。但是,我在前端得到的是一个带有数组的普通对象,如下所示:
{ "type": "Buffer", "data": [ 255, 243, 68, 196, 0, 0, 0, 3, 72, 0, 0, 0, 0, 255, 136, 137, 64, 4, 6, 61, 209, 56, 32, 225, 59, 245, 131, 240.......]}

我的问题:

1)既然前端从api接收到的数据已经不是buffer了,怎么把这个数据转回Buffer。

2)一旦我在前端有一个适当的缓冲区,我如何使用它来播放音频。

就我而言,要转换的文本将始终是 3-4 个单词的短语。所以,我不需要任何流媒体能力。

我的前端是 VueJS。

最佳答案

您可以下载音频并使用 html 音频播放器播放。

我们需要两个文件,index.js (Node.js) 代码和 index.html (Vue.js/Client)。

这将合成您输入的文本并播放。

运行 Node 脚本并转到http://localhost:8000/看演示。

您可以省略“控件”属性以隐藏音频播放器,但它仍应播放声音!

index.js

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

app.use(express.static("./"));

app.get('/download-audio', async (req, res) => { 

    let textToSynthesize = req.query.textToSynthesize;
    console.log("textToSynthesize:", textToSynthesize);

    const client = new textToSpeech.TextToSpeechClient();
    const request = {
        input: {text: textToSynthesize || 'Hello World'},
        // Select the language and SSML voice gender (optional)
        voice: {languageCode: 'en-US', ssmlGender: 'NEUTRAL'},
        // select the type of audio encoding
        audioConfig: {audioEncoding: 'MP3'},
    };

    const [response] = await client.synthesizeSpeech(request);
    console.log(`Audio synthesized, content-length: ${response.audioContent.length} bytes`)
    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);
});

app.listen(port);
console.log(`Serving at http://localhost:${port}`);

index.html
<!DOCTYPE html>
<html>
<body>
<script src="https://unpkg.com/vue@2.2.6/dist/vue.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js"></script>

<div class="container m-3" id="app">
<h2>Speech synthesis demo</h2>
<h4>Press synthesize and play to hear</h4>
<audio :src="audio" ref="audio" controls autoplay>
</audio>
<div class="form-group">
    <label for="text">Text to synthesize:</label>
    <input type="text" class="form-control" v-model="synthesisText" placeholder="Enter text" id="text">
</div>
<div>
    <button @click="downloadAudio">Synthesize and play</button>
</div>
</div>

<script>

    new Vue({
        el: "#app",
        data: {
            audio: null,
            synthesisText: "Gatsby believed in the green light, the orgiastic future that year by year recedes before us."
        },
        methods: {
            downloadAudio() {
                this.audio = "/download-audio?textToSynthesize=" + encodeURIComponent(this.synthesisText);
                this.$refs.audio.load();
                this.$refs.audio.play();
            }
        }
    });

</script>
</body>
</html> 

关于javascript - Google Text-toSpeech - 在前端获取音频文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61948764/

相关文章:

javascript - 我如何在 JavaScript 中使用 innerhtml?

node.js - OpenShift 问题中的 ExpressJS 4

node.js - 尽管项目在 docker 容器上,但如何在我的 IDE 上提供 linting 功能?

performance - PhpStorm 在编辑 vue.js 文件时速度极慢

json - 为什么我的 v-for 不循环? VUE.JS 与 JSON

javascript - Jquery 选择按名称或 ID 删除属性

javascript - 如何在 pagedown 编辑器中提供我自己的插入链接对话框?

mysql - 使用nodeJS Express和EJS发布mySQL值返回

html-table - Vue - 如何将表列绑定(bind)到数据对象?

javascript - 如何在 Javascript 中打开带有默认目录的文件浏览器?