From 048376d2a8811ce581c029699154b25d6ec6a71c Mon Sep 17 00:00:00 2001 From: Julian Date: Tue, 3 Jun 2025 21:53:49 +0200 Subject: [PATCH] Replace Lavaplayer with Lavalink skeleton --- maven-build.properties | 2 +- pom.xml | 10 +-- .../eventslistener/AudioEventListener.java | 9 +-- .../merly/events/AudioSystemEvent.java | 9 +-- .../merly/subsystem/audio/AudioHandler.java | 16 +++-- .../merly/subsystem/audio/AudioManager.java | 72 ++++--------------- .../merly/subsystem/audio/AudioQueue.java | 12 ++-- .../merly/subsystem/audio/AudioQueueImpl.java | 51 ++++++------- .../subsystem/audio/EnhancedAudioQueue.java | 5 +- .../audio/EnhancedAudioQueueImpl.java | 39 +++++----- .../subsystem/audio/TrackLoadResult.java | 14 ++-- .../java/de/yjulian/merly/util/AudioUtil.java | 39 +++------- 12 files changed, 110 insertions(+), 168 deletions(-) diff --git a/maven-build.properties b/maven-build.properties index 08435a7..d855348 100644 --- a/maven-build.properties +++ b/maven-build.properties @@ -12,7 +12,7 @@ maven.settings.offline=false maven.settings.interactiveMode=true maven.build.srcDir.0=src/main/java maven.compiler.target=11 -lavaplayer.version=1.3.67 +lavalink.version=4.0.0 maven.build.outputDir=${maven.build.dir}/classes project.build.outputDirectory=${maven.build.outputDir} maven.build.testResourceDir.0=src/test/resources diff --git a/pom.xml b/pom.xml index 13a1a8f..387435f 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ 11 11 4.2.0_249 - 1.3.67 + 4.0.0 @@ -113,11 +113,11 @@ trove4j 3.0.3 - + - com.sedmelluq - lavaplayer - ${lavaplayer.version} + dev.arbjerg + lavalink-client + ${lavalink.version} diff --git a/src/main/java/de/yjulian/merly/bot/eventslistener/AudioEventListener.java b/src/main/java/de/yjulian/merly/bot/eventslistener/AudioEventListener.java index 6b528a1..8a1a8ce 100644 --- a/src/main/java/de/yjulian/merly/bot/eventslistener/AudioEventListener.java +++ b/src/main/java/de/yjulian/merly/bot/eventslistener/AudioEventListener.java @@ -1,11 +1,12 @@ package de.yjulian.merly.bot.eventslistener; -import com.sedmelluq.discord.lavaplayer.player.event.AudioEvent; -import com.sedmelluq.discord.lavaplayer.player.event.AudioEventAdapter; +// TODO: update listener to Lavalink API +import lavalink.client.player.event.PlayerEvent; +import lavalink.client.player.event.PlayerEventAdapter; import de.yjulian.merly.events.AudioSystemEvent; import de.yjulian.merly.events.EventManager; -public class AudioEventListener extends AudioEventAdapter { +public class AudioEventListener extends PlayerEventAdapter { private final EventManager eventManager; @@ -14,7 +15,7 @@ public AudioEventListener(EventManager eventManager) { } @Override - public void onEvent(AudioEvent event) { + public void onEvent(PlayerEvent event) { this.eventManager.fireEvent(new AudioSystemEvent(event)); } } diff --git a/src/main/java/de/yjulian/merly/events/AudioSystemEvent.java b/src/main/java/de/yjulian/merly/events/AudioSystemEvent.java index a6e0897..6769d96 100644 --- a/src/main/java/de/yjulian/merly/events/AudioSystemEvent.java +++ b/src/main/java/de/yjulian/merly/events/AudioSystemEvent.java @@ -1,16 +1,17 @@ package de.yjulian.merly.events; -import com.sedmelluq.discord.lavaplayer.player.event.AudioEvent; +// TODO: replace with Lavalink player event +import lavalink.client.player.event.PlayerEvent; public class AudioSystemEvent implements Event { - private final AudioEvent event; + private final PlayerEvent event; - public AudioSystemEvent(AudioEvent event) { + public AudioSystemEvent(PlayerEvent event) { this.event = event; } - public AudioEvent getEvent() { + public PlayerEvent getEvent() { return event; } } diff --git a/src/main/java/de/yjulian/merly/subsystem/audio/AudioHandler.java b/src/main/java/de/yjulian/merly/subsystem/audio/AudioHandler.java index b4e464b..0132dff 100644 --- a/src/main/java/de/yjulian/merly/subsystem/audio/AudioHandler.java +++ b/src/main/java/de/yjulian/merly/subsystem/audio/AudioHandler.java @@ -1,7 +1,8 @@ package de.yjulian.merly.subsystem.audio; -import com.sedmelluq.discord.lavaplayer.player.AudioPlayer; -import com.sedmelluq.discord.lavaplayer.track.playback.AudioFrame; +// TODO: use Lavalink player classes +import lavalink.client.player.LavalinkPlayer; +import lavalink.client.player.event.Frame; import net.dv8tion.jda.api.audio.AudioSendHandler; import org.jetbrains.annotations.Nullable; @@ -10,15 +11,15 @@ public class AudioHandler implements AudioSendHandler { private static final boolean OPUS_FRAME = true; - private final AudioPlayer player; - private AudioFrame lastFrame; + private final LavalinkPlayer player; + private Frame lastFrame; /** * Create a new AudioPlayer handler with a provided {@link AudioPlayer}. * * @param player the player. */ - public AudioHandler(AudioPlayer player) { + public AudioHandler(LavalinkPlayer player) { this.player = player; } @@ -32,7 +33,8 @@ public AudioHandler(AudioPlayer player) { */ @Override public boolean canProvide() { - lastFrame = player.provide(); + // TODO: get frame from Lavalink player + lastFrame = null; return lastFrame != null; } @@ -58,7 +60,7 @@ public boolean canProvide() { @Nullable @Override public ByteBuffer provide20MsAudio() { - return ByteBuffer.wrap(lastFrame.getData()); + return lastFrame != null ? ByteBuffer.wrap(lastFrame.getData()) : null; } /** diff --git a/src/main/java/de/yjulian/merly/subsystem/audio/AudioManager.java b/src/main/java/de/yjulian/merly/subsystem/audio/AudioManager.java index 7c8030f..301d71a 100644 --- a/src/main/java/de/yjulian/merly/subsystem/audio/AudioManager.java +++ b/src/main/java/de/yjulian/merly/subsystem/audio/AudioManager.java @@ -1,10 +1,8 @@ package de.yjulian.merly.subsystem.audio; -import com.sedmelluq.discord.lavaplayer.player.*; -import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; -import com.sedmelluq.discord.lavaplayer.track.AudioItem; -import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; +// TODO: Replace lavaplayer imports with lavalink client equivalents +import lavalink.client.player.LavalinkPlayer; +import lavalink.client.player.event.PlayerEvent; import de.yjulian.merly.bot.MerlyBot; import de.yjulian.merly.exceptions.BotUnavailableException; import de.yjulian.merly.util.EnumUtils; @@ -17,43 +15,23 @@ public class AudioManager { - private final AudioPlayerManager manager; + // TODO: use appropriate Lavalink client class + private final LavalinkPlayer manager; private final HashMap audioQueues = new HashMap<>(); public AudioManager() { - this.manager = new DefaultAudioPlayerManager(); + // TODO: initialize Lavalink player + this.manager = null; init(); } private void init() { MerlyBot.getLogger().info("Initializing Merly Bot - Audio Manager"); - AudioConfiguration.ResamplingQuality resamplingQuality = EnumUtils - .getOrDefault(AudioConfiguration.ResamplingQuality.class, - System.getenv("MERLY_RESAMPLING_QUALITY"), - AudioConfiguration.ResamplingQuality.MEDIUM - ); - MerlyBot.getLogger().info(String.format("Audio Resampling Quality: %s", resamplingQuality.name())); - + // TODO: configure Lavalink connection MerlyBot.getLogger().info("Initializing Merly Bot - Finished"); - setCurrentQuality(resamplingQuality); - } - - public AudioConfiguration.ResamplingQuality getCurrentQuality() { - return getConfiguration().getResamplingQuality(); - } - - public void setCurrentQuality(AudioConfiguration.ResamplingQuality quality) { - getConfiguration().setResamplingQuality(quality); - MerlyBot.getLogger().debug(String.format("Audio Resampling Quality updated to %s", quality.name())); } - /** - * Get the current audio configuration. - * @return the current configuration. - */ - public AudioConfiguration getConfiguration() { - return this.manager.getConfiguration(); - } + // TODO: implement Lavalink audio configuration methods if needed /** * Get a audio queue for the voice channel provided. If no player is available the method with throw @@ -81,39 +59,17 @@ public AudioQueue getAudioQueue(VoiceChannel voiceChannel) { } } - AudioPlayer player = manager.createPlayer(); + // TODO: create Lavalink player instance + LavalinkPlayer player = manager; AudioQueueImpl audioQueue = new AudioQueueImpl(player, voiceChannel); audioQueues.put(guild, audioQueue); return audioQueue; } - void getTrack(String identifier, Consumer itemConsumer, Consumer result) { - manager.loadItem(identifier, new AudioLoadResultHandler() { - @Override - public void trackLoaded(AudioTrack track) { - itemConsumer.accept(track); - result.accept(new TrackLoadResult(null, TrackLoadResult.State.TRACK, track)); - } - - @Override - public void playlistLoaded(AudioPlaylist playlist) { - itemConsumer.accept(playlist); - result.accept(new TrackLoadResult(null, TrackLoadResult.State.PLAYLIST, playlist)); - } - - @Override - public void noMatches() { - itemConsumer.accept(null); - result.accept(new TrackLoadResult(null, TrackLoadResult.State.NOTHING_FOUND, null)); - } - - @Override - public void loadFailed(FriendlyException exception) { - itemConsumer.accept(null); - result.accept(new TrackLoadResult(exception, TrackLoadResult.State.EXCEPTION, null)); - } - }); + // TODO: implement track loading via Lavalink client + void getTrack(String identifier, Consumer itemConsumer, Consumer result) { + // Implementation pending } } diff --git a/src/main/java/de/yjulian/merly/subsystem/audio/AudioQueue.java b/src/main/java/de/yjulian/merly/subsystem/audio/AudioQueue.java index a266ce8..9af6d2f 100644 --- a/src/main/java/de/yjulian/merly/subsystem/audio/AudioQueue.java +++ b/src/main/java/de/yjulian/merly/subsystem/audio/AudioQueue.java @@ -1,7 +1,7 @@ package de.yjulian.merly.subsystem.audio; -import com.sedmelluq.discord.lavaplayer.track.AudioItem; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; +// TODO: replace with Lavalink track types +import lavalink.client.player.LavalinkTrack; import net.dv8tion.jda.api.entities.VoiceChannel; import java.util.function.Consumer; @@ -55,13 +55,13 @@ public interface AudioQueue { * Add tracks to the queue. * @param item a audio item */ - void addTrack(AudioItem item); + void addTrack(LavalinkTrack item); /** * Play a track instantly. * @param track a audio track. */ - void playTrack(AudioTrack track); + void playTrack(LavalinkTrack track); /** * Get the voice channel the bot is currently. @@ -72,9 +72,9 @@ public interface AudioQueue { /** * Get and remove the head of the playlist. - * @return a AudioTrack or null. + * @return a LavalinkTrack or null. */ - AudioTrack pollNextTrack(); + LavalinkTrack pollNextTrack(); /** * Load a track from a specific identifier. E.g. a youtube link. diff --git a/src/main/java/de/yjulian/merly/subsystem/audio/AudioQueueImpl.java b/src/main/java/de/yjulian/merly/subsystem/audio/AudioQueueImpl.java index 7db3a1e..e5030f5 100644 --- a/src/main/java/de/yjulian/merly/subsystem/audio/AudioQueueImpl.java +++ b/src/main/java/de/yjulian/merly/subsystem/audio/AudioQueueImpl.java @@ -1,11 +1,11 @@ package de.yjulian.merly.subsystem.audio; -import com.sedmelluq.discord.lavaplayer.player.AudioPlayer; -import com.sedmelluq.discord.lavaplayer.player.event.AudioEventAdapter; -import com.sedmelluq.discord.lavaplayer.track.AudioItem; -import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackEndReason; +// TODO: use Lavalink client classes +import lavalink.client.player.LavalinkPlayer; +import lavalink.client.player.event.PlayerEventAdapter; +import lavalink.client.player.LavalinkTrack; +import lavalink.client.player.LavalinkPlaylist; +import lavalink.client.player.event.TrackEndEvent; import de.yjulian.merly.bot.MerlyBot; import net.dv8tion.jda.api.entities.VoiceChannel; import net.dv8tion.jda.api.managers.AudioManager; @@ -18,13 +18,13 @@ public class AudioQueueImpl extends AudioEventAdapter implements AudioQueue { private static final long MIN_INACTIVITY_MS = 60000; private static final int DEFAULT_FRAME_BUFFER = 500; - private final AudioPlayer player; - private final Playlist playlist; + private final LavalinkPlayer player; + private final Playlist playlist; private final VoiceChannel voiceChannel; private long pausedSince = System.currentTimeMillis(); - AudioQueueImpl(AudioPlayer player, VoiceChannel voiceChannel) { + AudioQueueImpl(LavalinkPlayer player, VoiceChannel voiceChannel) { this.player = player; this.playlist = new PlaylistImpl<>(); this.voiceChannel = voiceChannel; @@ -42,8 +42,8 @@ public class AudioQueueImpl extends AudioEventAdapter implements AudioQueue { } @Override - public void onTrackEnd(AudioPlayer player, AudioTrack track, AudioTrackEndReason endReason) { - if (endReason.equals(AudioTrackEndReason.FINISHED)) { + public void onTrackEnd(LavalinkPlayer player, LavalinkTrack track, TrackEndEvent endReason) { + if (true) { // TODO check end reason nextTrack(); } } @@ -72,7 +72,7 @@ private void loadDefaults() { */ @Override public boolean nextTrack() { - AudioTrack nextTrack = pollNextTrack(); + LavalinkTrack nextTrack = pollNextTrack(); if (nextTrack != null) { playTrack(nextTrack); return true; @@ -88,7 +88,8 @@ public boolean nextTrack() { */ @Override public boolean isPlaying() { - return player.getPlayingTrack() != null; + // TODO: adjust according to Lavalink API + return false; } /** @@ -107,7 +108,7 @@ public boolean isAvailable() { */ @Override public void stopTrack() { - player.stopTrack(); + // TODO: stop playback in Lavalink pausedSince = System.currentTimeMillis(); } @@ -120,11 +121,11 @@ public void clearQueue() { } @Override - public void addTrack(AudioItem item) { - if (item instanceof AudioTrack) { - this.playlist.addTrack(Priority.MEDIUM, (AudioTrack) item); - } else if (item instanceof AudioPlaylist) { - for (AudioTrack track : ((AudioPlaylist) item).getTracks()) { + public void addTrack(LavalinkTrack item) { + if (item instanceof LavalinkTrack) { + this.playlist.addTrack(Priority.MEDIUM, item); + } else if (item instanceof LavalinkPlaylist) { + for (LavalinkTrack track : ((LavalinkPlaylist) item).getTracks()) { this.playlist.addTrack(Priority.MEDIUM, track); } } else { @@ -138,16 +139,16 @@ public void addTrack(AudioItem item) { * @param track the new track to play. */ @Override - public void playTrack(AudioTrack track) { - this.player.playTrack(track); + public void playTrack(LavalinkTrack track) { + // TODO: play track via Lavalink this.pausedSince = -1; } - public AudioPlayer getPlayer() { + public LavalinkPlayer getPlayer() { return player; } - public Playlist getPlaylist() { + public Playlist getPlaylist() { return this.playlist; } @@ -159,10 +160,10 @@ public VoiceChannel getVoiceChannel() { /** * Get and remove the head of the playlist. * - * @return a AudioTrack or null. + * @return a LavalinkTrack or null. */ @Override - public AudioTrack pollNextTrack() { + public LavalinkTrack pollNextTrack() { return this.playlist.poll(); } diff --git a/src/main/java/de/yjulian/merly/subsystem/audio/EnhancedAudioQueue.java b/src/main/java/de/yjulian/merly/subsystem/audio/EnhancedAudioQueue.java index c740b4e..4c9bee0 100644 --- a/src/main/java/de/yjulian/merly/subsystem/audio/EnhancedAudioQueue.java +++ b/src/main/java/de/yjulian/merly/subsystem/audio/EnhancedAudioQueue.java @@ -1,6 +1,7 @@ package de.yjulian.merly.subsystem.audio; -import com.sedmelluq.discord.lavaplayer.track.AudioItem; +// TODO: replace with Lavalink track type +import lavalink.client.player.LavalinkTrack; public interface EnhancedAudioQueue extends AudioQueue { @@ -9,6 +10,6 @@ public interface EnhancedAudioQueue extends AudioQueue { * @param prio a priority * @param item the item. */ - void addTrack(int prio, AudioItem item); + void addTrack(int prio, LavalinkTrack item); } diff --git a/src/main/java/de/yjulian/merly/subsystem/audio/EnhancedAudioQueueImpl.java b/src/main/java/de/yjulian/merly/subsystem/audio/EnhancedAudioQueueImpl.java index 94da6ae..2b0ebac 100644 --- a/src/main/java/de/yjulian/merly/subsystem/audio/EnhancedAudioQueueImpl.java +++ b/src/main/java/de/yjulian/merly/subsystem/audio/EnhancedAudioQueueImpl.java @@ -1,17 +1,17 @@ package de.yjulian.merly.subsystem.audio; -import com.sedmelluq.discord.lavaplayer.player.AudioPlayer; -import com.sedmelluq.discord.lavaplayer.track.AudioItem; -import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; +// TODO: use Lavalink player classes +import lavalink.client.player.LavalinkPlayer; +import lavalink.client.player.LavalinkTrack; +import lavalink.client.player.LavalinkPlaylist; import de.yjulian.merly.subsystem.audio.enhanced.PriorityQueue; import net.dv8tion.jda.api.entities.VoiceChannel; public class EnhancedAudioQueueImpl extends AudioQueueImpl implements EnhancedAudioQueue { - private final PriorityQueue playlist = new PriorityQueue<>(); + private final PriorityQueue playlist = new PriorityQueue<>(); - public EnhancedAudioQueueImpl(AudioPlayer player, VoiceChannel voiceChannel) { + public EnhancedAudioQueueImpl(LavalinkPlayer player, VoiceChannel voiceChannel) { super(player, voiceChannel); } @@ -30,11 +30,12 @@ public void clearQueue() { * @param item a audio item */ @Override - public void addTrack(AudioItem item) { - if (item instanceof AudioTrack) { - this.playlist.addItem(100, (AudioTrack) item); - } else if (item instanceof AudioPlaylist) { - for (AudioTrack track : ((AudioPlaylist) item).getTracks()) { + public void addTrack(LavalinkTrack item) { + // TODO: adapt to Lavalink track/playlist API + if (item instanceof LavalinkTrack) { + this.playlist.addItem(100, item); + } else if (item instanceof LavalinkPlaylist) { + for (LavalinkTrack track : ((LavalinkPlaylist) item).getTracks()) { this.playlist.addItem(100, track); } } else { @@ -44,10 +45,10 @@ public void addTrack(AudioItem item) { /** * Get the next track. - * @return a AudioTrack + * @return a LavalinkTrack */ @Override - public AudioTrack pollNextTrack() { + public LavalinkTrack pollNextTrack() { return this.playlist.poll(); } @@ -57,7 +58,7 @@ public AudioTrack pollNextTrack() { * @param track a audio track. */ @Override - public void playTrack(AudioTrack track) { + public void playTrack(LavalinkTrack track) { this.playlist.addItem(0, track); } @@ -68,11 +69,11 @@ public void playTrack(AudioTrack track) { * @param item the item. */ @Override - public void addTrack(int prio, AudioItem item) { - if (item instanceof AudioTrack) { - this.playlist.addItem(prio, (AudioTrack) item); - } else if (item instanceof AudioPlaylist) { - for (AudioTrack track : ((AudioPlaylist) item).getTracks()) { + public void addTrack(int prio, LavalinkTrack item) { + if (item instanceof LavalinkTrack) { + this.playlist.addItem(prio, item); + } else if (item instanceof LavalinkPlaylist) { + for (LavalinkTrack track : ((LavalinkPlaylist) item).getTracks()) { this.playlist.addItem(prio, track); } } else { diff --git a/src/main/java/de/yjulian/merly/subsystem/audio/TrackLoadResult.java b/src/main/java/de/yjulian/merly/subsystem/audio/TrackLoadResult.java index ba05f24..a0ba123 100644 --- a/src/main/java/de/yjulian/merly/subsystem/audio/TrackLoadResult.java +++ b/src/main/java/de/yjulian/merly/subsystem/audio/TrackLoadResult.java @@ -1,24 +1,24 @@ package de.yjulian.merly.subsystem.audio; -import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; -import com.sedmelluq.discord.lavaplayer.track.AudioItem; +// TODO: replace with Lavalink classes +import lavalink.client.player.event.PlayerEvent; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class TrackLoadResult { - private final FriendlyException exception; + private final Exception exception; private final State state; - private final AudioItem item; + private final Object item; - TrackLoadResult(FriendlyException exception, State state, AudioItem item) { + TrackLoadResult(Exception exception, State state, Object item) { this.exception = exception; this.state = state; this.item = item; } @Nullable - public FriendlyException getException() { + public Exception getException() { return exception; } @@ -28,7 +28,7 @@ public State getState() { } @Nullable - public AudioItem getItem() { + public Object getItem() { return item; } diff --git a/src/main/java/de/yjulian/merly/util/AudioUtil.java b/src/main/java/de/yjulian/merly/util/AudioUtil.java index 1dcd328..6be8a93 100644 --- a/src/main/java/de/yjulian/merly/util/AudioUtil.java +++ b/src/main/java/de/yjulian/merly/util/AudioUtil.java @@ -1,11 +1,7 @@ package de.yjulian.merly.util; -import com.sedmelluq.discord.lavaplayer.source.youtube.YoutubeAudioSourceManager; -import com.sedmelluq.discord.lavaplayer.source.youtube.YoutubeAudioTrack; -import com.sedmelluq.discord.lavaplayer.source.youtube.YoutubeSearchMusicProvider; -import com.sedmelluq.discord.lavaplayer.source.youtube.YoutubeSearchProvider; -import com.sedmelluq.discord.lavaplayer.track.AudioItem; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; +// TODO: migrate to lavalink search utilities +import lavalink.client.player.LavalinkPlayer; public final class AudioUtil { @@ -17,34 +13,17 @@ private AudioUtil() { } - public static AudioItem youtubeSearch(String query) { - if (youtubeSearchProvider == null) { - youtubeSearchProvider = new YoutubeSearchProvider(); - } - - return youtubeSearchProvider.loadSearchResult(query, info -> { - if (youtubeAudioSourceManager == null) { - youtubeAudioSourceManager = new YoutubeAudioSourceManager(); - } - return new YoutubeAudioTrack(info, youtubeAudioSourceManager); - }); + // TODO: implement search using Lavalink + public static Object youtubeSearch(String query) { + return null; } - public static AudioItem youtubeMusicSearch(String query) { - if (youtubeSearchMusicProvider == null) { - youtubeSearchMusicProvider = new YoutubeSearchMusicProvider(); - } - - return youtubeSearchMusicProvider.loadSearchMusicResult(query, info -> { - if (youtubeAudioSourceManager == null) { - youtubeAudioSourceManager = new YoutubeAudioSourceManager(); - } - return new YoutubeAudioTrack(info, youtubeAudioSourceManager); - }); + public static Object youtubeMusicSearch(String query) { + return null; } - public static AudioTrack cloneAudioTrack(AudioTrack track) { - return track.makeClone(); + public static Object cloneAudioTrack(Object track) { + return null; } }