Discord.js音乐机器人AudioPlayer.play报Cannot read 'once'错误求助
错误修复方案
核心问题定位
@discordjs/voice的AudioPlayer.play()方法仅接受AudioResource类型的参数,你直接传入ytdl返回的裸流不符合接口要求,这是触发Cannot read properties of undefined (reading 'once')报错的直接原因play.js中未定义connection变量就直接调用connection.subscribe(),同时播放逻辑和加入语音频道的逻辑割裂,没有在执行play命令时自动初始化语音连接index.js中命令注册逻辑写错,你的普通命令导出的是name字段,用command.data.name取值会返回undefined,会导致命令注册失败
修正后的play.js代码
const ytdl = require('ytdl-core'); const ytSearch = require('yt-search'); const { createAudioPlayer, createAudioResource, joinVoiceChannel, getVoiceConnection } = require('@discordjs/voice'); const player = createAudioPlayer(); module.exports = { name: 'play', description: 'Plays video', async execute(message, args) { const voiceChannel = message.member.voice.channel; if (!voiceChannel) return message.channel.send('I cannot enter the tavern!'); const permissions = voiceChannel.permissionsFor(message.client.user); if (!permissions.has('CONNECT')) return message.channel.send('I cannot reach you!'); if (!permissions.has('SPEAK')) return message.channel.send('I cannot hear you!'); if (!args.length) return message.channel.send('You need to tell me the song!'); const videoFinder = async (query) => { const videoResult = await ytSearch(query); return videoResult.videos.length >= 1 ? videoResult.videos[0] : null; } const video = await videoFinder(args.join(' ')); if(video){ // 先获取已有的语音连接,没有就新建连接 let connection = getVoiceConnection(message.guild.id); if (!connection) { connection = joinVoiceChannel({ channelId: voiceChannel.id, guildId: message.guild.id, adapterCreator: message.guild.voiceAdapterCreator }); } // 将ytdl流包装为AudioResource const stream = ytdl(video.url, {filter: 'audioonly', highWaterMark: 1<<25}); const resource = createAudioResource(stream, { inlineVolume: true }); resource.volume.setVolume(0.5); // 播放资源、订阅播放器 player.play(resource); connection.subscribe(player); await message.reply(`:thumbsup: Now Playing *${video.title}*`); } else { message.channel.send(`No video results found`); } } }
修正index.js的两处问题
- 替换命令注册逻辑:
把原来的循环
for (const file of commandFiles) { const command = require(`./commands/${file}`); client.commands.set(command.data.name, command); }
替换为
for (const file of commandFiles) { const command = require(`./commands/${file}`); client.commands.set(command.name, command); }
- 替换废弃事件:discord.js v14已经弃用
message事件,把client.on('message', message => {改成client.on('messageCreate', message => {即可适配版本规范。
内容的提问来源于stack exchange,提问作者Aegis
相关产品推荐
相关产品推荐

