Java 音乐机器人不播放音乐

问题描述 投票:0回答:1

我正在创建一个 Java 音乐机器人。我遇到了一个问题,机器人加入了我的频道,但它没有开始播放音乐。我正在使用 JDA 和 lavaplayer 来运行机器人。它可以找到曲目,甚至调用 AudioLoadResultHandler 类中的 .trackLoaded 函数。我在我的 Windows 电脑上运行 java 19。

我的 Maven 依赖项:

<repositories>
    <repository>
        <id>dv8tion</id>
        <name>m2-dv8tion</name>
        <url>https://m2.dv8tion.net/releases</url>
    </repository>
</repositories>

<dependencies>
    <!-- Discord Bot - JDA-->
    <dependency>
        <groupId>net.dv8tion</groupId>
        <artifactId>JDA</artifactId>
        <version>5.0.0-beta.21</version>
    </dependency>

    <!-- Music library - Lavaplayer -->
    <dependency>
        <groupId>com.sedmelluq</groupId>
        <artifactId>lavaplayer</artifactId>
        <version>1.3.78</version>
    </dependency>

    <!-- Lombok -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.30</version>
        <scope>provided</scope>
    </dependency>

    <!-- Injection - Guice -->
    <dependency>
        <groupId>com.google.inject</groupId>
        <artifactId>guice</artifactId>
        <version>5.1.0</version>
    </dependency>
</dependencies>

我的 PlayerManager 类:

public class PlayerManager {

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

public PlayerManager() {
    registerRemoteSources(audioPlayerManager);
    registerLocalSource(audioPlayerManager);
}

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 audioTrack) {
            guildMusicManager.getTrackScheduler().queue(audioTrack);
        }

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

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

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

我的 GuildMusicManager 类:

@Getter
public class GuildMusicManager {

private TrackScheduler trackScheduler;
private AudioForwarder audioForwarder;

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

我的 TrackScheduler 课程:

@Getter
public class TrackScheduler extends AudioEventAdapter {

private AudioPlayer audioPlayer;
private BlockingQueue<AudioTrack> queue = new LinkedBlockingQueue<>();
private Guild guild;

TrackScheduler(AudioPlayer audioPlayer, Guild guild) {
    this.audioPlayer = audioPlayer;
    this.guild = guild;
}

@Override
public void onTrackStart(AudioPlayer player, AudioTrack track) {
    EmbedBuilder builder = new EmbedBuilder();
    builder.setColor(MAGENTA);
    AudioTrackInfo info = track.getInfo();
    builder.setTitle("Jetzt läuft: " + info.title);

    long sekunden = info.length/1000;
    long minuten = sekunden/60;
    long stunden = minuten/60;
    minuten %= 60;
    sekunden %= 60;

    String url = info.uri;
    builder.addField(info.author, "[" + info.title +"](" + url + ")", false);
    builder.addField("Länge", info.isStream ? ":red_circle: Stream" : (stunden > 0 ? stunden + "h " : "") + minuten + "min " + sekunden + "s", true);

    map.get(guild.getIdLong()).sendMessageEmbeds(builder.build()).queue();
}

@Override
public void onTrackEnd(AudioPlayer player, AudioTrack track, AudioTrackEndReason endReason) {
    audioPlayer.startTrack(queue.poll(), false);

    newSingleThreadExecutor().execute(() -> {
        try {
            sleep(60000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        if(isNull(player.getPlayingTrack())) {
            if(nonNull(guild.getAudioManager().getConnectedChannel())) {
                guild.getAudioManager().closeAudioConnection();
            }
        }
    });
}

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

我的音频转发器类:

public class AudioForwarder implements AudioSendHandler {

private final AudioPlayer audioPlayer;
private final ByteBuffer byteBuffer = allocate(1024);
private final MutableAudioFrame audioFrame = new MutableAudioFrame();

public AudioForwarder(AudioPlayer audioPlayer) {
    this.audioPlayer = audioPlayer;
    this.audioFrame.setBuffer(byteBuffer);
}

@Override
public boolean canProvide() {
    return audioPlayer.provide(audioFrame);
}

@Nullable
@Override
public ByteBuffer provide20MsAudio() {
    return byteBuffer.flip();
}

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

我的播放命令:

@CommandBase.Command(name = "play", description = "Wähle ein Lied, das abgespielt werden soll.", hasOptions = true)
public class PlayCommand extends CommandBase {

@Inject
private JavaBot javaBot;

public static HashMap<Long, TextChannel> map = new HashMap<>();

public PlayCommand(@NotNull Command command) {
    super(command);
}

@Override
public void execute(Member member, TextChannel textChannel, List<OptionMapping> options, SlashCommandInteractionEvent event) {
    GuildVoiceState guildVoiceState = member.getVoiceState();

    if (isNull(guildVoiceState) || isNull(guildVoiceState.getChannel()) || isNull(guildVoiceState.getChannel().asVoiceChannel())) {
        event.reply("Du musst in einem Sprachkanal sein.").queue(); //TODO Replace with embed (EmbedBuilder builder = new EmbedBuilder())
        return;
    }

    VoiceChannel voiceChannel = guildVoiceState.getChannel().asVoiceChannel();
    PlayerManager playerManager = javaBot.getPlayerManager();
    AudioManager manager = voiceChannel.getGuild().getAudioManager();
    manager.openAudioConnection(voiceChannel);

    String url = options.get(0).getAsString();
    if (!url.startsWith("http")) {
        url = "ytsearch:" + url + " audio";
    }
    event.reply("Suche nach dem Titel...").queue(); //TODO Replace with embed (EmbedBuilder builder = new EmbedBuilder())

    playerManager.play(event.getGuild(), url);
    map.put(voiceChannel.getGuild().getIdLong(), textChannel);
}

@Override
public void autoComplete(String optionName, CommandAutoCompleteInteractionEvent event) {
    List<String> options = of("Achterbahn wise guys", "Ich trink uso was trinkst denn du so", "for the night pop smoke"); //TODO add logic to get famous songs

    if (optionName.equalsIgnoreCase("song")) {
        List<net.dv8tion.jda.api.interactions.commands.Command.Choice> returnChoices = options.stream()
                .filter(option -> option.toLowerCase().startsWith(event.getFocusedOption().getValue().toLowerCase()))
                .map(option -> new net.dv8tion.jda.api.interactions.commands.Command.Choice(option, option))
                .collect(toList());
        event.replyChoices(returnChoices).queue();
    }
}

@Override
public List<OptionData> getOptions() {
    return of(new OptionData(STRING, "song", "Titel oder URL vom Lied", true, true));
}
}

正如您从我的 pom.xml 文件中看到的,我正在运行最新版本的 JDA 和 Lavaplayer。我的机器人在我的不和谐服务器上也拥有尽可能高的权限。该机器人几周前也能工作,但如果没有做任何大的改变,它就不再工作了。正如我所说,我正在运行 Java 19。如果您需要更多信息,请随时询问。 谢谢您的帮助!

java discord bots
1个回答
0
投票

我终于找到了解决问题的方法。 Lavaplayer 似乎已经过时了,这就是为什么你应该使用 fork。我使用以下 Lavaplayer 分支:https://github.com/lavalink-devs/lavaplayer 目前最新的官方版本也有一个bug,这就是为什么你应该使用以下maven导入:

<repository>
        <id>arbjergDev-snapshots</id>
        <name>Lavalink Repository</name>
        <url>https://maven.lavalink.dev/snapshots</url>
</repository>
<dependency>
        <groupId>dev.arbjerg</groupId>
        <artifactId>lavaplayer</artifactId>
        <version>0eaeee195f0315b2617587aa3537fa202df07ddc-SNAPSHOT</version>
</dependency>

您可以在本期中了解为什么要使用此导入:https://github.com/lavalink-devs/lavaplayer/issues/90

它对我有用,我希望它也对你有用。

© www.soinside.com 2019 - 2024. All rights reserved.