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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 10:39:03