Discord.js音频Bot播放问题:如何实现检测语音时暂停续播而非从头播放
修复逻辑说明
你当前的代码在用户停止说话时直接销毁了播放实例,因此下次触发播放只能从头加载音频。我们可以通过pause()/resume()方法实现暂停续播,同时监听播放完成事件实现播放完毕后重置的需求。
核心修改点
- 修正原代码中
dispather的拼写错误(正确拼写为dispatcher,避免运行报错) - 用户停止说话时不销毁播放实例,仅调用
pause()暂停 - 用户恢复说话时,若存在已暂停的播放实例,直接调用
resume()续播 - 为播放实例添加
finish事件监听,音频自然播放结束后清空实例,下次播放自动从头加载
修改后完整代码
const fs = require('fs'), { Client, } = require('discord.js') const { token, bypass } = require('./config.json') const client = new Client() let previousChannel, connection, dispatcher; client .on('ready', () => { console.log(`Logged in as ${client.user.tag}`) }) .on('voiceStateUpdate', async (oldState, newState) => { if (newState.id == client.user.id) return if (newState.channelID !== null) previousChannel = newState.channelID if (newState.channelID == null && !bypass.includes(newState.id) && !!previousChannel) { client.channels.cache.get(previousChannel).leave() return [previousChannel, dispatcher] = [null, null]; } if (bypass.includes(newState.id)) return let channel = client.channels.cache.get(newState.channelID) if (!channel) return return connection = await channel.join() }) .on('guildMemberSpeaking', async (member, speaking) => { if (!connection) return if (bypass.includes(member.user.id)) return // 检测到用户开始说话 if (speaking.bitfield) { if (!dispatcher) { // 无播放实例,从头创建播放 dispatcher = connection.play(fs.createReadStream('./audio.mp3'), { volume: 1 }) // 音频播放完成后清空实例,下次从头播放 dispatcher.on('finish', () => { dispatcher = undefined }) } else if (dispatcher.paused) { // 存在暂停的实例,从暂停位置续播 dispatcher.resume() } } else { // 用户停止说话,暂停播放 if (dispatcher && !dispatcher.paused) { dispatcher.pause() } } }) .on('error', console.log) .on('warn', console.log) .login(token) process.on('unhandledRejection', console.log)
内容的提问来源于stack exchange,提问作者josh heil
相关产品推荐
相关产品推荐

