discord.js v13语音机器人无声音输出问题排查及代码修复请求
Discord.js v13 语音转文字再转语音机器人无声音问题排查与修复
代码存在的核心问题
- 异步逻辑混乱:用
.then()处理转录请求,但后续代码直接同步执行,导致转录结果还没返回就执行翻译、TTS逻辑,texter变量未赋值,还存在未定义的response变量,触发报错后跳过播放流程。 - 音频流未触发结束事件:注释了结束音频流的
setTimeout,audioStream的end事件永远不会触发,转录和播放逻辑根本不会执行。 - TTS使用固定文本:硬编码播放"Hello world!",没有使用实际转录的用户语音文本。
- 变量作用域错误:
texter定义在.then()内部,外部代码无法访问该变量。
修复方案与完整代码
针对上述问题,调整后的代码如下:
const { Client, Intents } = require('discord.js'); const { createAudioPlayer, createAudioResource, joinVoiceChannel } = require('@discordjs/voice'); const { getAudioUrl } = require('google-tts-api'); const Transcriber = require("discord-speech-to-text"); const transcriber = new Transcriber("你的API密钥"); const DiscordTTS = require("discord-tts"); const axios = require('axios'); const client = new Client({ intents:[ Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES, Intents.FLAGS.GUILD_VOICE_STATES ] }); client.on('messageCreate', async (message) => { if (message.author.bot) return; if (!message.content.startsWith('!listen')) return; const voiceChannel = message.member.voice.channel; if (!voiceChannel) return message.reply('你得先加入一个语音频道!'); const connection = joinVoiceChannel({ channelId: voiceChannel.id, guildId: voiceChannel.guild.id, adapterCreator: voiceChannel.guild.voiceAdapterCreator, selfDeaf: false, selfMute: false, }); const audioStream = connection.receiver.subscribe(message.author.id, { mode: 'pcm' }); const audioChunks = []; audioStream.on('data', (chunk) => { audioChunks.push(chunk); }); audioStream.on('end', async () => { const audioBuffer = Buffer.concat(audioChunks); try { // 等待转录结果返回 const data = await transcriber.listen(audioBuffer); if (!data.transcript.text) return; let texter = data.transcript.text; console.log(`转录结果:${texter}`); // 翻译文本(可选,这里保留原逻辑) const translationResponse = await axios.get(`https://translate.googleapis.com/translate_a/single?client=gtx&sl=en&tl=fr&dt=t&q=${encodeURI(texter)}`); const translatedText = translationResponse.data[0][0][0]; console.log(`翻译结果:${translatedText}`); // 使用转录后的文本生成TTS流 const resource = DiscordTTS.getVoiceStream(texter); const player = createAudioPlayer(); player.play(resource); // 播放语音 connection.subscribe(player); // 播放结束后销毁连接(可选) player.on('stateChange', (oldState, newState) => { if (newState.status === 'idle') { connection.destroy(); } }); } catch (error) { console.error('处理出错:', error); } }); // 5秒后结束音频流,触发转录逻辑 setTimeout(() => { audioStream.destroy(); }, 5000); }); client.login('你的机器人Token');
额外说明
- 请替换代码中的
你的API密钥和你的机器人Token为实际值。 - 如果不需要翻译功能,可以删除翻译相关的代码块,直接使用
texter生成TTS。 - 5秒的录音时长可以根据需求调整,也可以优化为监听用户停止说话的事件来触发结束,定时结束是最简单的测试方案。
内容的提问来源于stack exchange,提问作者GEYO 5
相关产品推荐
相关产品推荐

