Discord音乐机器人播放中断,调用skip命令触发dispatcher.end空指针报错如何解决
问题根因
- 报错直接原因:
dispatcher对象为null时直接调用了end()方法,通常出现在语音连接已经自动断开、音频流加载失败、歌曲已经播放完毕三种场景下 - 运行一段时间自动停止的常见原因:
- ytdl-core版本过旧,无法兼容YouTube最新的接口签名规则
- Discord语音连接超时自动断开,没有做错误捕获和重连逻辑
- 缺少
@discordjs/opus、ffmpeg-static必要依赖,音频流解码不稳定
修复步骤
1. 安装缺失依赖
首先安装你缺少的必要依赖:
npm install @discordjs/opus ffmpeg-static ytdl-core@latest
@discordjs/opus是Discord语音传输必须的编码库ffmpeg-static会自动绑定适配你系统的ffmpeg,不用再依赖本地环境配置的ffmpeg- 升级
ytdl-core到最新版解决YouTube接口适配问题,大幅降低播放中断概率
2. 修复skip、clear方法的空值判断
修改skip_song和clear_song函数,增加dispatcher存在性校验,避免空值调用崩溃:
const skip_song = (message, server_queue) => { if(!message.member.voice.channel) return message.channel.send('เข้าดิสก่อนดิ :angry: '); if(!server_queue) return message.channel.send('ไม่มีเพลงในคิวแล้ว :relieved: '); // 增加dispatcher非空判断 if(server_queue.connection?.dispatcher){ server_queue.connection.dispatcher.end(); }else{ // 如果dispatcher不存在,直接调用下一首播放逻辑 server_queue.songs.shift(); video_player(message.guild, server_queue.songs[0]); } } const clear_song = (message, server_queue) => { if(!message.member.voice.channel) return message.channel.send('เข้าดิสก่อนดิ :angry: '); if(!server_queue) return message.channel.send('ไม่มีเพลงในคิวแล้ว :relieved: '); server_queue.songs = []; // 同样增加非空判断 if(server_queue.connection?.dispatcher){ server_queue.connection.dispatcher.end(); }else{ server_queue.voice_channel.leave(); queue.delete(message.guild.id); } }
3. 修复音频流配置和错误监听
你原来的ytdl参数写了两个独立对象属于无效配置,同时给播放逻辑增加错误监听,避免流加载失败导致整个机器人崩溃:
const video_player = async (guild, song) => { const song_queue = queue.get(guild.id); if(!song){ song_queue.voice_channel.leave(); queue.delete(guild.id); return; } // 合并ytdl参数,让高水位缓冲配置生效 const stream = ytdl(song.url,{filter: 'audioonly', highWaterMark: 1<<25 }); song_queue.connection.play(stream, { seek: 0, volume: 0.5 }) .on('finish', () => { song_queue.songs.shift(); video_player(guild, song_queue.songs[0]); }) // 增加播放错误监听,出错自动切下一首 .on('error', err => { console.log('播放错误:', err); song_queue.songs.shift(); video_player(guild, song_queue.songs[0]); }); await song_queue.text_channel.send(`:regional_indicator_k: :regional_indicator_o: :regional_indicator_n: :regional_indicator_g: :sunglasses: กำลังเล่นเด็ก ***${song.title}***`); }
内容的提问来源于stack exchange,提问作者Konglnwza
相关产品推荐
相关产品推荐

