基于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,提问作者Николай
相关产品推荐
相关产品推荐

