discord.js v13音乐机器人报错song_queue.connection.play is not a function如何解决
解决方案
报错原因
discord.js v13对语音模块做了全量重构,@discordjs/voice返回的语音连接对象已不再内置play方法,必须配合官方规范的AudioPlayer+AudioResource流程实现播放,你使用的v12版本代码逻辑完全不兼容v13接口。
需要修改的核心点
- 修复代码笔误:获取Youtube视频信息时变量名写错,
song_title应为song_info - 新增
AudioPlayer实例存储字段,将播放器绑定到语音连接 - 重写播放逻辑,替换原有废弃的
connection.play调用 - 替换原有语音频道退出方法,改用
connection.destroy()
修改后完整代码
const ytdl = require('ytdl-core'); const ytSearch = require('yt-search'); // 新增引入StreamType const { joinVoiceChannel, createAudioPlayer, createAudioResource, StreamType } = require('@discordjs/voice'); const queue = new Map(); // queue (message.guild.id, queue_constructor object { voice channel, text channel, connection, audioPlayer, song[]}); module.exports = { name: 'play', aliases: ['skip', 'stop'], description: 'Advanced music bot', async execute(message, args, cmd, client, discord){ const voice_channel = message.member.voice.channel; if (!voice_channel) return message.channel.send('You need to be in a channel to execute this command'); const permissions = voice_channel.permissionsFor(message.client.user); if (!permissions.has('CONNECT')) return message.channel.send('You dont have permission to do that'); if (!permissions.has('SPEAK')) return message.channel.send('You dont have permission to do that'); const server_queue = queue.get(message.guild.id); if (cmd === 'play') { if (!args.length) return message.channel.send('You need to send the second argument'); let song = {}; if (ytdl.validateURL(args[0])){ const song_info = await ytdl.getInfo(args[0]); // 修复变量名错误 song = { title: song_info.videoDetails.title, url: song_info.videoDetails.video_url } } else { //If the video is not a URL then use keywords to find that video. const video_finder = async (query) =>{ const videoResult = await ytSearch(query); return (videoResult.videos.length > 1) ? videoResult.videos[0] : null; } const video = await video_finder(args.join(' ')); if (video){ song = { title: video.title, url: video.url } } else { return message.channel.send('Error finding your video'); } } if (!server_queue){ const queue_constructor = { voice_channel: voice_channel, text_channel: message.channel, connection: null, audioPlayer: null, // 新增播放器存储字段 songs: [] } queue.set(message.guild.id, queue_constructor); queue_constructor.songs.push(song); try { const connection = await joinVoiceChannel({ channelId: message.member.voice.channel.id, guildId: message.guild.id, adapterCreator: message.guild.voiceAdapterCreator }) // 创建播放器并绑定到连接 const audioPlayer = createAudioPlayer(); connection.subscribe(audioPlayer); queue_constructor.connection = connection; queue_constructor.audioPlayer = audioPlayer; video_player(message.guild, queue_constructor.songs[0]); } catch (err) { queue.delete(message.guild.id); message.channel.send('There was an error connecting'); throw err; } } else{ server_queue.songs.push(song); return message.channel.send(`<:seelio:811951350660595772> **${song.title}** added to queue`); } } } } const video_player = async (guild, song) => { const song_queue = queue.get(guild.id); if(!song) { // 替换原有leave方法 song_queue.connection.destroy(); queue.delete(guild.id); return; } const stream = ytdl(song.url, { filter: 'audioonly', highWaterMark: 1 << 25 }); // 创建音频资源 const audioResource = createAudioResource(stream, { inputType: StreamType.Arbitrary, inlineVolume: true }); // 设置音量 audioResource.volume.setVolume(0.5); // 调用播放器播放 song_queue.audioPlayer.play(audioResource); // 监听播放结束事件 song_queue.audioPlayer.once('idle', () => { song_queue.songs.shift(); video_player(guild, song_queue.songs[0]); }); // 监听播放错误 song_queue.audioPlayer.once('error', (err) => { console.error('播放出错:', err); song_queue.songs.shift(); video_player(guild, song_queue.songs[0]); }); // 修复模板字符串语法错误,替换单引号为反引号 await song_queue.text_channel.send(`<:seelio:811951350660595772> Now Playing **${song.title}**`) }
额外注意
如果运行后仍出现无法拉取音频流的问题,可将ytdl-core依赖更新到最新版本。
内容的提问来源于stack exchange,提问作者uPink
相关产品推荐
相关产品推荐

