Node.js调用Google Cloud TTS生成MP3同时实时播放音频的问题求解
解决方案
误区澄清
你调整的effectsProfileId参数仅用于针对不同播放设备优化音频音质,和实时输出到扬声器、边生成边播放的需求没有关联。你当前使用的非流式synthesizeSpeech接口会等待全部音频生成完成后才一次性返回完整二进制内容,天然不支持实时播放。
实现步骤
你需要同时用到Google TTS的流式合成接口、音频解码播放模块、流分发能力,具体操作如下:
1. 安装额外依赖
需要安装MP3解码和扬声器输出的相关依赖:
npm install speaker lame
2. 替换为流式实现代码
修改后的代码可以同时实现边合成边播放、本地文件保存两个功能:
const textToSpeech = require('@google-cloud/text-to-speech'); const fs = require('fs'); const lame = require('lame'); const Speaker = require('speaker'); const { PassThrough } = require('stream'); const client = new textToSpeech.TextToSpeechClient(); // 配置部分保持你的原有参数即可 const text1 = 'The rain in Spain stays mainly on the plain'; const outputFile = './audiofiles/sample1.mp3'; process.env.GOOGLE_APPLICATION_CREDENTIALS = "./key/runningzebra-7d04161f3149.json"; const voice1 = { languageCode:"en-US", ssmlGender:"MALE", name:"en-US-Wavenet-B" } const audioConfig1 = { // 这里的effectsProfileId按需保留即可,只影响音质不影响播放 effectsProfileId: ["headphone-class-device", "large-automotive-class-device", "telephony-class-application"], pitch: -10.0, speakingRate: 0.75, audioEncoding: "MP3" } const input1 = { text:text1 } const request = { input:input1, voice:voice1, audioConfig:audioConfig1 } async function streamAndPlayAudio(request, outputFile) { // 调用流式合成接口 const stream = client.streamingSynthesize(request); // 创建分流器,一份写入文件,一份送播放 const passThrough = new PassThrough(); const writeStream = fs.createWriteStream(outputFile); // 播放链路:MP3流 -> 解码 -> 扬声器输出 const decoder = new lame.Decoder(); const speaker = new Speaker({ channels: 2, bitDepth: 16, sampleRate: 24000 // 对应Wavenet音色的采样率,可根据实际返回调整 }); // 管道分发 stream.pipe(passThrough); passThrough.pipe(writeStream); passThrough.pipe(decoder).pipe(speaker); // 事件监听 stream.on('error', err => console.error('合成出错:', err)); writeStream.on('finish', () => console.log(`音频已写入文件:${outputFile}`)); speaker.on('finish', () => console.log('播放完成')); } streamAndPlayAudio(request, outputFile);
注意事项
- 如果出现播放卡顿,可以在
PassThrough中配置highWaterMark参数适当增加缓冲,或者先缓冲前几帧音频再启动播放链路 - 部分Windows环境下
speaker模块安装失败时,可以替换为play-sound模块,将音频块写入临时缓冲文件后调用系统播放器播放
内容的提问来源于stack exchange,提问作者user3567761
相关产品推荐
相关产品推荐

