You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Discord.js v14:如何让机器人播放完MP3后退出语音频道?

问题:Discord.js v14 机器人播放MP3后无法自动退出语音频道

使用斜杠命令调用机器人进入语音频道播放MP3文件后,无法实现播放完毕自动退出。目前通过setTimeout临时实现需求,但希望找到Discord.js v14官方推荐的正确实现方式。

原代码中尝试通过if (player.pause(), () => voiceConnection.disconnect())实现退出,但该逻辑无效。


解决方案

在Discord.js v14配合@discordjs/voice库时,正确的做法是监听音频播放器的**Idle事件**——当音频资源播放完成后,播放器会自动触发该事件,此时即可执行断开语音连接的操作。

修改要点:

  • 移除原代码中无效的if (player.pause(), () => voiceConnection.disconnect())语句
  • 为player添加Idle事件监听器,在回调内调用voiceConnection.disconnect()或voiceConnection.destroy()(后者会彻底销毁连接,适合单次播放场景)

修改后的完整代码:

const { SlashCommandBuilder, ChannelType } = require('discord.js');
const { getVoiceConnection, entersState, joinVoiceChannel, createAudioPlayer, createAudioResource, VoiceConnectionStatus } = require('@discordjs/voice');
const { join } = require('node:path');

module.exports = {
    data: new SlashCommandBuilder()
        .setName('padoru')
        .setDescription('Elle est partout.....fuyez..')
        .addChannelOption(option => option.setName('channel').setDescription('Le channel vocal à rejoindre.').setRequired(true).addChannelTypes(ChannelType.GuildVoice)),

    async execute(interaction) {
        if (interaction.isChatInputCommand() && interaction.commandName === 'padoru') {
            const voiceChannel = interaction.options.getChannel('channel');
            const voiceConnection = joinVoiceChannel({
                channelId: voiceChannel.id,
                guildId: interaction.guild.id,
                adapterCreator: interaction.guild.voiceAdapterCreator,
                selfDeaf: false,
            });

            const player = createAudioPlayer();
            const resource = createAudioResource(join(__dirname, '../../medias/sound_effect/padorupadoru.mp3'));

            try {
                await entersState(voiceConnection, VoiceConnectionStatus.Ready, 5000);
                console.log("Connected: " + voiceChannel.guild.name);
            } catch (error) {
                console.log("Voice Connection not ready within 5s.", error);
                voiceConnection.destroy(); // 连接失败时销毁连接
                return;
            }

            // 监听播放完成事件
            player.on('idle', () => {
                voiceConnection.disconnect(); // 断开连接
                // 若需要彻底销毁连接,可改用 voiceConnection.destroy();
                console.log("Playback finished, disconnected from voice channel.");
            });

            voiceConnection.subscribe(player);
            player.play(resource);
            
            // 回复交互,避免超时
            await interaction.reply({ content: `正在播放Padoru在${voiceChannel.name}`, ephemeral: true });
        }
    }
};

补充说明:

  • Idle事件仅在播放器没有待播放的资源且处于空闲状态时触发,刚好对应单音频播放完成的场景
  • 记得在交互中调用interaction.reply(),否则Discord会判定命令超时失败
  • 连接失败时调用voiceConnection.destroy()可以避免残留无效连接

内容的提问来源于stack exchange,提问作者Cyber Moika

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 18:03:14