Музыкальный дискорд бот на lavaplayer загружает музыку, но никогда не воспроизводит ее

Работаю над discord ботом, одной из функций которого должен стать заказ музыки. Когда дописывал, приходил к тому, что при использовании команды бот подключается к каналу, загружает трек из указанной ссылки, но не воспроизводит его, при этом никаких ошибок в консоли не возникает. Пересмотрел 3 руководства, даже полностью копировал код, который работает у авторов, но проблема осталась. Использую Java, IntelliJ IDEA, maven, JDA 5.0.0-alpha.11, lavaplayer 1.3.77. Подозреваю, что проблема заключается в нехватке каких-либо прав. Код ниже:

  • 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;
               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) {
            player.startTrack(track.makeClone(), false);
        } else {
            player.startTrack(queue.poll(), false);
        }
    }

    public void queue(AudioTrack track) {
        if(!player.startTrack(track, true)) {
            queue.offer(track);
        }
    }

    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 Map<Long, GuildMusicManager> guildMusicManagers = new HashMap<>();
    private 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) {
                guildMusicManager.getTrackScheduler().queue(track);
            }

            @Override
            public void playlistLoaded(AudioPlaylist playlist) {
                guildMusicManager.getTrackScheduler().queue(playlist.getTracks().get(0));
            }

            @Override
            public void noMatches() {

            }

            @Override
            public void loadFailed(FriendlyException exception) {

            }
        });
    }
}
  • Обработка /play
public void onSlashCommandInteraction(@NotNull SlashCommandInteractionEvent event) {
     if (event.getName().equals("play")) {
            if (!event.getMember().getVoiceState().inAudioChannel()) {
                event.reply("Сначала нужно подключиться к голосовому каналу!").setEphemeral(true).submit();
            } else if (!event.getChannel().getId().equals(App.rules.get("music_channel_id"))) {
                event.reply("Данное действие можно использовать только в соответствующем канале!")
                        .setEphemeral(true).submit();
            } else if (event.getOption("name").getAsString().equals("null")) {
                event.reply("Необходимо указать ссылку на трек!")
                        .setEphemeral(true).submit();
            } else {
                event.getGuild().getAudioManager().openAudioConnection(event.getMember().getVoiceState().getChannel());

                PlayerManager playerManager = PlayerManager.get();
                event.reply("Playing").setEphemeral(true).submit();
                playerManager.play(event.getGuild(), event.getOption("name").getAsString());
            }
        }
}

P.S. На портале разработчиков discord все права включены, на тестовом сервере бот имеет права администратора, роль бота в приоритетах стоит выше всех остальных.


Ответы (0 шт):