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

基于Lavaplayer与Maven的Java Discord音乐机器人无法播放问题排查

Discord音乐机器人无法播放音频问题

我正在开发一款Discord音乐机器人,程序可成功查找并下载音频,但无法播放。即使复制同版本教程的可用代码也无效,原代码会在player.startTrack(track, false);或player.playTrack(track);处挂起。

尝试过不同平台的音频链接均无效,怀疑是自身代码问题。已在Discord开发者门户开启所有网关意图,测试服务器中机器人拥有管理员权限且角色优先级最高。

初始版本:JDA 5.0.0-alpha.11、lavaplayer 1.3.77;更新至JDA 5.0.0-beta.9后,代码不再挂起,但仍无声音,机器人连接语音频道后会频繁重连。相关代码如下:

Main

public static void main(String[] args) throws Exception {
        JDA jda = JDABuilder.createDefault(TOKEN).setChunkingFilter(ChunkingFilter.ALL)
                .setMemberCachePolicy(MemberCachePolicy.ALL).enableIntents(GatewayIntent.GUILD_MEMBERS,
                        GatewayIntent.GUILD_MESSAGES,
                        GatewayIntent.GUILD_VOICE_STATES).build();
        jda.addEventListener(new checker()); 
    }  

AudioSendHandler

public class AudioForwarder implements AudioSendHandler {

   private final AudioPlayer player;
   private final Guild guild;
   private final ByteBuffer buffer = ByteBuffer.allocate(1024);
   private final MutableAudioFrame frame = new MutableAudioFrame();
   private int time;

   public AudioForwarder(AudioPlayer player, Guild guild) {
       this.player = player;
       this.guild = guild;
       frame.setBuffer(buffer);
   }

   @Override
   public boolean canProvide() {
       boolean canProvide = player.provide(frame);
       if(!canProvide) {
           time += 20;
           if (time >= 300000) {
               time = 0;
               System.out.println("timeout");
               guild.getAudioManager().closeAudioConnection();
           }
       } else {
           time = 0;
       }
       return canProvide;
   }

   @Nullable
   @Override
   public ByteBuffer provide20MsAudio() {
       final Buffer tmp = ((Buffer) buffer).flip();

       return (ByteBuffer) tmp;
   }

   @Override
   public boolean isOpus() {
       return true;
   }
}

TrackScheduler

public class TrackScheduler extends AudioEventAdapter {

    private final AudioPlayer player;
    private final BlockingQueue<AudioTrack> queue = new LinkedBlockingQueue<>();
    private boolean isRepeat = false;

    public TrackScheduler(AudioPlayer player) {
        this.player = player;
    }

    @Override
    public void onTrackEnd(AudioPlayer player, AudioTrack track, AudioTrackEndReason endReason) {
        if(isRepeat) {
            System.out.println("6");
            player.startTrack(track.makeClone(), false);
            System.out.println("7");
        } else {
            System.out.println("8");
            player.startTrack(queue.poll(), false);
            System.out.println("9");
        }
    }

    public void queue(AudioTrack track) {
        if(!player.startTrack(track, true)) {
            System.out.println("1");
            queue.offer(track);
            System.out.println("2");
        } else {
            System.out.println("3");
            StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
            for (StackTraceElement element:stackTraceElements) {
                System.out.println(element.getMethodName());
            }
            player.startTrack(track, false);
            System.out.println("4");
        }
    }

    public AudioPlayer getPlayer() {
        return player;
    }

    public BlockingQueue<AudioTrack> getQueue() {
        return queue;
    }

    public boolean isRepeat() {
        return isRepeat;
    }

    public void setRepeat(boolean repeat) {
        isRepeat = repeat;
    }
}

GuildMusicManager

public class GuildMusicManager {

    private TrackScheduler trackScheduler;
    private AudioForwarder audioForwarder;

    public GuildMusicManager(AudioPlayerManager manager, Guild guild) {
        AudioPlayer player = manager.createPlayer();
        trackScheduler = new TrackScheduler(player);
        player.addListener(trackScheduler);
        audioForwarder = new AudioForwarder(player, guild);
    }

    public TrackScheduler getTrackScheduler() {
        return trackScheduler;
    }

    public AudioForwarder getAudioForwarder() {
        return audioForwarder;
    }
}

PlayerManager

public class PlayerManager {

    private static PlayerManager INSTANCE;
    private final Map<Long, GuildMusicManager> guildMusicManagers = new HashMap<>();
    private final AudioPlayerManager audioPlayerManager = new DefaultAudioPlayerManager();

    private PlayerManager() {
        AudioSourceManagers.registerRemoteSources(audioPlayerManager);
        AudioSourceManagers.registerLocalSource(audioPlayerManager);
    }

    public static PlayerManager get() {
        if(INSTANCE == null) {
            INSTANCE = new PlayerManager();
        }
        return INSTANCE;
    }

    public GuildMusicManager getGuildMusicManager(Guild guild) {
        return guildMusicManagers.computeIfAbsent(guild.getIdLong(), (guildId) -> {
            GuildMusicManager musicManager = new GuildMusicManager(audioPlayerManager, guild);

            guild.getAudioManager().setSendingHandler(musicManager.getAudioForwarder());

            return musicManager;
        });
    }

    public void play(Guild guild, String trackURL) {
        GuildMusicManager guildMusicManager = getGuildMusicManager(guild);
        audioPlayerManager.loadItemOrdered(guildMusicManager, trackURL, new AudioLoadResultHandler() {
            @Override
            public void trackLoaded(AudioTrack track) {
                System.out.println("0");
                guildMusicManager.getTrackScheduler().queue(track);
                System.out.println("5");
            }

            @Override
            public void playlistLoaded(AudioPlaylist playlist) {
                System.out.println("0.1");
                guildMusicManager.getTrackScheduler().queue(playlist.getTracks().get(0));
                System.out.println("5.1");
            }

            @Override
            public void noMatches() {
                System.out.println("no_matches");
            }

            @Override
            public void loadFailed(FriendlyException exception) {
                System.out.println("failed");
            }
        });
    }
}

/play命令

public void onSlashCommandInteraction(@NotNull SlashCommandInteractionEvent event) {
     if (event.getName().equals("play")) {
                event.getGuild().getAudioManager().openAudioConnection(event.getMember().getVoiceState().getChannel());

                String name = event.getOption("name").getAsString();
                try {
                    new URI(name);
                } catch (URISyntaxException e) {
                    name = name + "ytsearch:";
                }
                PlayerManager playerManager = PlayerManager.get();
                event.reply("Playing").setEphemeral(true).submit();
                playerManager.play(event.getGuild(), name);
        }
}

内容的提问来源于stack exchange,提问作者Николай

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 08:29:56