Discord.js重写版音乐机器人触发播放提示但无音频输出问题求助
Discord.js 音乐机器人重写后无音频输出故障排查
故障现象
重写后的Discord.js音乐机器人可正常加入语音频道、触发「正在播放歌曲」提示,但无音频输出;原始未整理代码运行完全正常,两套代码仅核心播放逻辑函数存在差异。
可能的问题点
stop函数变量未声明导致作用域污染:重写后的stop函数中未声明guild变量就直接调用queue.delete(guild.id),guild会被隐式定义为全局变量,多次操作后会出现队列关联的服务器ID错误,导致音频资源绑定到错误的上下文。- 跳过逻辑的实例冲突:重写后将切歌逻辑拆分为独立的
skipSong函数,调用videoPlayer时会创建新的AudioPlayer实例,旧实例未被销毁的情况下会出现多个实例抢占连接资源的情况,虽订阅成功但无有效音频输出。 - 依赖资源读取失败:如果重写后代码的运行目录发生变化,ytdl依赖的ffmpeg路径、自定义cookie配置等相对路径资源无法正常读取,会导致生成的音频流为空,创建音频资源时无报错但实际无输出。
代码对比
未整理原版代码
const videoPlayer = async function (message, song, skip, stop) { const guild = message.guild; const songQueue = queue.get(guild.id); if(!song && !skip && !stop) { songQueue.connection.disconnect(); queue.delete(guild.id); return; } if (skip) { if (!songQueue) return message.channel.send("There are currently no songs in the queue"); const prev = songQueue.songs[0].title await songQueue.textChannel.send(`Skipping \`${prev}\`!`) songQueue.songs.shift(); if (!song && songQueue.songs.length == 0) { songQueue.connection.disconnect(); queue.delete(guild.id); return songQueue.textChannel.send("There are currently no songs in the queue"); } var music = songQueue.songs[0] var stream = ytdl(music.url, {filter: 'audioonly', highWaterMark: 1<<25}) } else { var stream = ytdl(song.url, {filter: 'audioonly', highWaterMark: 1<<25}) } const player = Voice.createAudioPlayer(); const resource = Voice.createAudioResource(stream); await player.play(resource); songQueue.connection.subscribe(player); if (!song && music) { song = music } player.on(Voice.AudioPlayerStatus.Playing, async () => { await songQueue.textChannel.send(`Playing \`${song.title}\`!`) }); player.on(Voice.AudioPlayerStatus.Idle, () => { songQueue.songs.shift(); videoPlayer(message, songQueue.songs[0]) }); }
重写后代码
const videoPlayer = async (message, song) => { const guild = message.guild; const songQueue = queue.get(guild.id); if(!song) { songQueue.connection.disconnect(); queue.delete(guild.id); return message.channel.send("There are no more songs in queue."); } const stream = ytdl(song.url, {filter: 'audioonly', highWaterMark: 1<<25}); const player = Voice.createAudioPlayer(); const resource = Voice.createAudioResource(stream); await player.play(resource); songQueue.connection.subscribe(player); player.on(Voice.AudioPlayerStatus.Playing, async () => { await songQueue.textChannel.send(`Playing \`${song.title}\``) }); player.on(Voice.AudioPlayerStatus.Idle, async () => { songQueue.songs.shift(); videoPlayer(message, songQueue.songs[0]); }) } const skipSong = async (message) => { guild = message.guild; songQueue = queue.get(guild.id); if(!songQueue) return message.channel.send("There are currently no songs in queue."); let song = songQueue.songs[0]; await message.channel.send(`Skipping \`${song.title}\`!`); songQueue.songs.shift(); song = songQueue.songs[0]; if(!song) return message.channel.send("There are no more songs in queue."); videoPlayer(message, song); } const stop = async (message) => { songQueue = queue.get(message.guild.id); await songQueue.textChannel.send('Stopping in just a moment...'); songQueue.connection.disconnect(); queue.delete(guild.id); return; }
后续更新
最终排查发现代码本身不存在问题,故障原因和运行目录有关,在原项目目录下运行即可正常工作,暂未明确具体触发原因,目前功能已经恢复正常。
内容的提问来源于stack exchange,提问作者Shirayuki Yumi
相关产品推荐
相关产品推荐

