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

DiscordJS音量命令故障排查:player与resource变量为空

Discord.js音量命令无法获取player/resource的问题解决

问题描述

我编写了一个Discord.js音乐命令类,执行play命令时机器人能正常播放歌曲,但执行volume命令时,player和resource变量始终为空,无法调整音量。相关代码如下:

class music_cmd{
    constructor(client, message, prefix, cmd, args, generateDependencyReport, joinVoiceChannel, createAudioPlayer, createAudioResource, ytdl){

        this.client = client;
        this.message = message;
        this.prefix = prefix;
        this.cmd = cmd;
        this.args = args;
        this.joinVoiceChannel = joinVoiceChannel;
        this.createAudioPlayer = createAudioPlayer;
        this.createAudioResource = createAudioResource;
        this.ytdl = ytdl;
        this.connection = null;
        this.players = new Map();

        if(cmd === 'play'){
            this.play();
        }

        if(cmd === 'volume'){
            this.volume();
        }

    }

    async play(){
        
        try{
            this.connection = await this.joinVoiceChannel({
                channelId: this.message.member.voice.channel.id,
                guildId: this.message.guild.id,
                adapterCreator: this.message.guild.voiceAdapterCreator
            });

            const stream = this.ytdl(this.args[1], { filter: 'audioonly' });
            
            const player = this.createAudioPlayer();
            const resource = this.createAudioResource(stream);

            this.players.set(this.message.guild.id, { player, resource });

            player.play(resource);
            this.connection.subscribe(player);
            this.message.channel.send('Rozpoczynam odtwarzanie utworu..');
        } catch(error){
            console.error(error);
        }
    }

    volume(){
        const volume = parseInt(this.args[1]);
        if (isNaN(volume) || volume < 0 || volume > 100) {
        this.message.channel.send('Podaj poprawną wartość głośności (liczba od 0 do 100).');
        return;
        }

        const guildId = this.message.guild.id;
        const { player, resource } = this.players.get(guildId) || {};

        console.log(player);
        console.log(resource);

        if (!player || !resource) {
        this.message.channel.send('Nie odtwarzam żadnej muzyki.');
        return;
        }

        resource.volume.setVolume(volume / 100);
        this.message.channel.send(`Głośność ustawiona na ${volume}%.`);
    }

}

export default music_cmd;

问题根源

每次触发Discord命令时,都会创建一个全新的music_cmd实例。你在constructor里初始化的this.players = new Map()是每个实例独有的,play命令将播放器状态存在当前实例的Map中,而volume命令的实例根本访问不到这个Map,自然拿不到player和resource。

解决方案

1. 共享播放器状态(核心修复)

将players改为类的静态属性,让所有music_cmd实例共享同一个Map:

class music_cmd{
    // 改为静态属性,所有实例共享
    static players = new Map();

    constructor(client, message, prefix, cmd, args, generateDependencyReport, joinVoiceChannel, createAudioPlayer, createAudioResource, ytdl){
        this.client = client;
        this.message = message;
        this.prefix = prefix;
        this.cmd = cmd;
        this.args = args;
        this.joinVoiceChannel = joinVoiceChannel;
        this.createAudioPlayer = createAudioPlayer;
        this.createAudioResource = createAudioResource;
        this.ytdl = ytdl;
        this.connection = null;
        // 移除this.players = new Map();

        if(cmd === 'play'){
            this.play();
        }

        if(cmd === 'volume'){
            this.volume();
        }
    }

    async play(){
        try{
            this.connection = await this.joinVoiceChannel({
                channelId: this.message.member.voice.channel.id,
                guildId: this.message.guild.id,
                adapterCreator: this.message.guild.voiceAdapterCreator
            });

            const stream = this.ytdl(this.args[1], { filter: 'audioonly' });
            
            const player = this.createAudioPlayer();
            // 开启音量控制选项
            const resource = this.createAudioResource(stream, { inlineVolume: true });

            // 使用静态属性存储
            music_cmd.players.set(this.message.guild.id, { player, resource });

            player.play(resource);
            this.connection.subscribe(player);
            this.message.channel.send('Rozpoczynam odtwarzanie utworu..');
        } catch(error){
            console.error(error);
        }
    }

    volume(){
        const volume = parseInt(this.args[1]);
        if (isNaN(volume) || volume < 0 || volume > 100) {
            this.message.channel.send('Podaj poprawną wartość głośności (liczba od 0 do 100).');
            return;
        }

        const guildId = this.message.guild.id;
        // 从静态属性获取
        const { player, resource } = music_cmd.players.get(guildId) || {};

        if (!player || !resource) {
            this.message.channel.send('Nie odtwarzam żadnej muzyki.');
            return;
        }

        resource.volume.setVolume(volume / 100);
        this.message.channel.send(`Głośność ustawiona na ${volume}%.`);
    }
}

export default music_cmd;

2. 额外注意:开启音量控制

创建AudioResource时必须添加inlineVolume: true选项,否则resource.volume会是undefined,即使拿到资源也无法调整音量。

其他可选方案

如果不想用静态属性,也可以将播放器状态存储在Discord客户端实例上,比如:

// 在客户端初始化时添加
client.musicPlayers = new Map();

// 在类中使用
this.client.musicPlayers.set(guildId, { player, resource });
const { player, resource } = this.client.musicPlayers.get(guildId) || {};

这种方式更适合多命令类共享状态的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 19:27:43