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

discord.js v13 音乐机器人play命令queue队列调用异常问题求助

问题根源

你遇到的报错是由以下几个问题共同导致的:

  1. messageCreate.js中单独声明了局部queue变量,没有复用你在index.js里挂载到client实例上的全局共享队列
  2. play.js中调用自定义函数video_player时没有传入queue参数,导致该函数内部读取queue时返回undefined,调用queue.get()直接抛出类型错误
  3. video_player函数内部直接使用了未声明的connection变量,销毁连接时会触发第二次报错

修复步骤

第一步:修改messageCreate.js,复用全局队列

删除messageCreate.js中单独声明的局部queue,直接使用client.queue,修改后代码如下:

const del = require('../../functions.js');
const Levels = require('discord-xp');
require('dotenv').config();
const prefix = process.env.PREFIX;

module.exports = async (Discord, client, message) => {
    
    if (message.author.bot || !message.guild) return;
    
    const randomXP = Math.floor(Math.random() * 14) + 1; //1-15
    const hasLeveledUP = await Levels.appendXp(message.author.id, message.guild.id, randomXP);
    if (hasLeveledUP) {
        const user = await Levels.fetch(message.author.id, message.guild.id);
        message.channel.send(`${message.member} is now level ${user.level}.`);
    }
    
    const args = message.content.slice(prefix.length).trim().split(" ");
    const cmd = args.shift().toLowerCase();
    
    if (cmd.length === 0) return;
    
    let command = client.commands.get(cmd) || client.commands.find(c => c.aliases?.includes(cmd));
    
    if (command) {
        command.run(client, message, args, client.queue);
    }
}

第二步:修改play.js中的调用逻辑和video_player函数

  1. 调用video_player时传入queue参数
  2. 修复video_player内部未声明connection的问题
    修改后play.js相关部分代码:
// 原try代码块部分修改
try {
    const connection = joinVoiceChannel({
        channelId: voiceChannel.id,
        guildId: message.guild.id,
        adapterCreator: message.guild.voiceAdapterCreator
    });
    queue_constructor.connection = connection;
    // 新增传入queue参数
    video_player(message.guild, queue_constructor.songs[0], queue);
} catch (err) {
    queue.delete(message.guild.id);
    message.channel.send('Error connecting');
    throw err;
}

// ... 其他代码不变,修改video_player函数
const video_player = async (guild, song, queue) => {
    const song_queue = queue.get(guild.id);
    
    if(!song) {
        // 调用song_queue中存储的connection,避免使用未声明变量
        song_queue.connection.destroy();
        queue.delete(guild.id);
        return;
    }
    
    const audioPlayer = createAudioPlayer();
    song_queue.connection.subscribe(audioPlayer);
    
    const stream = ytdl(song.url, { filter: 'audioonly' });
    audioPlayer.play(createAudioResource(stream, {seek: 0, volume: 1}))
    audioPlayer.on(AudioPlayerStatus.Idle, () => {
        song_queue.songs.shift();
        // 递归调用时也要传入queue参数
        video_player(guild, song_queue.songs[0], queue);
    });
    song_queue.text_channel.send(`Now playing **${song.title}**`)
}

可选优化

因为队列已经全局挂载在client.queue上,你可以直接在play.js的run函数里通过client.queue访问,不需要单独传queue参数,可避免后续传参遗漏的问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 16:45:02