Add music control via button

This commit is contained in:
SebClem 2022-05-16 14:13:10 +02:00
parent 32ba05bf99
commit fc3b89af9c
Signed by: sebclem
GPG Key ID: 5A4308F6A359EA50
3 changed files with 174 additions and 35 deletions

View File

@ -19,6 +19,7 @@ import net.dv8tion.jda.api.events.guild.member.GuildMemberRoleRemoveEvent;
import net.dv8tion.jda.api.events.guild.voice.GuildVoiceJoinEvent; import net.dv8tion.jda.api.events.guild.voice.GuildVoiceJoinEvent;
import net.dv8tion.jda.api.events.guild.voice.GuildVoiceLeaveEvent; import net.dv8tion.jda.api.events.guild.voice.GuildVoiceLeaveEvent;
import net.dv8tion.jda.api.events.guild.voice.GuildVoiceMoveEvent; import net.dv8tion.jda.api.events.guild.voice.GuildVoiceMoveEvent;
import net.dv8tion.jda.api.events.interaction.ButtonClickEvent;
import net.dv8tion.jda.api.events.interaction.SlashCommandEvent; import net.dv8tion.jda.api.events.interaction.SlashCommandEvent;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent; import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter; import net.dv8tion.jda.api.hooks.ListenerAdapter;
@ -28,6 +29,7 @@ import org.jetbrains.annotations.NotNull;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import java.awt.*; import java.awt.*;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -122,6 +124,9 @@ public class BotListener extends ListenerAdapter {
AudioM.getInstance(event.getGuild()).stop(); AudioM.getInstance(event.getGuild()).stop();
} }
} }
else if (event.getMember().getUser() == MainBot.jda.getSelfUser()){
AudioM.getInstance(event.getGuild()).clearLastButton();
}
AutoVoiceChannel autoVoiceChannel = AutoVoiceChannel.getInstance(event.getGuild()); AutoVoiceChannel autoVoiceChannel = AutoVoiceChannel.getInstance(event.getGuild());
autoVoiceChannel.leave(event.getChannelLeft()); autoVoiceChannel.leave(event.getChannelLeft());
} }
@ -141,6 +146,20 @@ public class BotListener extends ListenerAdapter {
} }
} }
@Override
public void onButtonClick(@NotNull ButtonClickEvent event) {
super.onButtonClick(event);
event.deferReply().queue();
AudioM audioM = AudioM.getInstance(event.getGuild());
switch (event.getComponentId()) {
case "pause" -> audioM.pause(event);
case "play" -> audioM.resume(event);
case "next" -> audioM.skipTrack(event);
case "stop" -> audioM.stop(event);
case "disconnect" -> audioM.disconect(event);
}
}
@Override @Override
public void onSlashCommand(@NotNull SlashCommandEvent event) { public void onSlashCommand(@NotNull SlashCommandEvent event) {
HashMap<String, SlashCommand> commands = MainBot.slashCommands; HashMap<String, SlashCommand> commands = MainBot.slashCommands;
@ -186,4 +205,6 @@ public class BotListener extends ListenerAdapter {
return guildPref; return guildPref;
} }
} }

View File

@ -13,15 +13,17 @@ import net.Broken.RestApi.Data.UserAudioTrackData;
import net.Broken.Tools.EmbedMessageUtils; import net.Broken.Tools.EmbedMessageUtils;
import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.MessageBuilder; import net.dv8tion.jda.api.MessageBuilder;
import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.*;
import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.events.interaction.GenericInteractionCreateEvent;
import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.entities.VoiceChannel;
import net.dv8tion.jda.api.events.interaction.SlashCommandEvent; import net.dv8tion.jda.api.events.interaction.SlashCommandEvent;
import net.dv8tion.jda.api.interactions.components.ActionRow;
import net.dv8tion.jda.api.interactions.components.Button;
import net.dv8tion.jda.api.interactions.components.ComponentLayout;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import java.awt.*; import java.awt.*;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -55,6 +57,8 @@ public class AudioM {
private Guild guild; private Guild guild;
private Logger logger = LogManager.getLogger(); private Logger logger = LogManager.getLogger();
private Message lastMessageWithButton;
private AudioM(Guild guild) { private AudioM(Guild guild) {
this.playerManager = new DefaultAudioPlayerManager(); this.playerManager = new DefaultAudioPlayerManager();
AudioSourceManagers.registerRemoteSources(playerManager); AudioSourceManagers.registerRemoteSources(playerManager);
@ -91,7 +95,8 @@ public class AudioM {
Message message = new MessageBuilder() Message message = new MessageBuilder()
.setEmbeds(EmbedMessageUtils.getMusicAdded(track.getInfo(), event.getMember(), -1)) .setEmbeds(EmbedMessageUtils.getMusicAdded(track.getInfo(), event.getMember(), -1))
.build(); .build();
event.getHook().sendMessage(message).queue(); clearLastButton();
lastMessageWithButton = event.getHook().sendMessage(message).addActionRow(getActionButton()).complete();
play(guild, voiceChannel, musicManager, uat, onHead); play(guild, voiceChannel, musicManager, uat, onHead);
} }
@ -103,7 +108,8 @@ public class AudioM {
Message message = new MessageBuilder() Message message = new MessageBuilder()
.setEmbeds(EmbedMessageUtils.getMusicAdded(firstTrack.getInfo(), event.getMember(), size)) .setEmbeds(EmbedMessageUtils.getMusicAdded(firstTrack.getInfo(), event.getMember(), size))
.build(); .build();
event.getHook().sendMessage(message).queue(); clearLastButton();
lastMessageWithButton = event.getHook().sendMessage(message).addActionRow(getActionButton()).complete();
playListLoader(playlist, playlistLimit, event.getUser(), onHead); playListLoader(playlist, playlistLimit, event.getUser(), onHead);
} }
@ -212,7 +218,7 @@ public class AudioM {
* *
* @param event * @param event
*/ */
public void skipTrack(SlashCommandEvent event) { public void skipTrack(GenericInteractionCreateEvent event) {
GuildMusicManager musicManager = getGuildAudioPlayer(); GuildMusicManager musicManager = getGuildAudioPlayer();
musicManager.scheduler.nextTrack(); musicManager.scheduler.nextTrack();
Message message = new MessageBuilder().setEmbeds( Message message = new MessageBuilder().setEmbeds(
@ -221,7 +227,8 @@ public class AudioM {
.setTitle(":track_next: Next Track") .setTitle(":track_next: Next Track")
.setColor(Color.green) .setColor(Color.green)
)).build(); )).build();
event.getHook().sendMessage(message).queue(); clearLastButton();
lastMessageWithButton = event.getHook().sendMessage(message).addActionRow(getActionButton()).complete();
} }
/** /**
@ -229,7 +236,7 @@ public class AudioM {
* *
* @param event * @param event
*/ */
public void pause(SlashCommandEvent event) { public void pause(GenericInteractionCreateEvent event) {
GuildMusicManager musicManager = getGuildAudioPlayer(); GuildMusicManager musicManager = getGuildAudioPlayer();
musicManager.scheduler.pause(); musicManager.scheduler.pause();
Message message = new MessageBuilder().setEmbeds( Message message = new MessageBuilder().setEmbeds(
@ -238,7 +245,8 @@ public class AudioM {
.setTitle(":pause_button: Playback paused") .setTitle(":pause_button: Playback paused")
.setColor(Color.green) .setColor(Color.green)
)).build(); )).build();
event.getHook().sendMessage(message).queue(); clearLastButton();
lastMessageWithButton = event.getHook().sendMessage(message).addActionRow(getActionButton()).complete();
} }
@ -248,16 +256,27 @@ public class AudioM {
* *
* @param event * @param event
*/ */
public void resume(SlashCommandEvent event) { public void resume(GenericInteractionCreateEvent event) {
GuildMusicManager musicManager = getGuildAudioPlayer(); GuildMusicManager musicManager = getGuildAudioPlayer();
Message message;
if(musicManager.player.getPlayingTrack() == null){
message = new MessageBuilder().setEmbeds(
EmbedMessageUtils.buildStandar(
new EmbedBuilder()
.setTitle(":warning: Nothing to play, playlist is empty !")
.setColor(Color.green)
)).build();
}else{
musicManager.scheduler.resume(); musicManager.scheduler.resume();
Message message = new MessageBuilder().setEmbeds( message = new MessageBuilder().setEmbeds(
EmbedMessageUtils.buildStandar( EmbedMessageUtils.buildStandar(
new EmbedBuilder() new EmbedBuilder()
.setTitle(":arrow_forward: Playback resumed") .setTitle(":arrow_forward: Playback resumed")
.setColor(Color.green) .setColor(Color.green)
)).build(); )).build();
event.getHook().sendMessage(message).queue(); }
clearLastButton();
lastMessageWithButton = event.getHook().sendMessage(message).addActionRow(getActionButton()).complete();
} }
/** /**
@ -265,15 +284,16 @@ public class AudioM {
* *
* @param event * @param event
*/ */
public void info(SlashCommandEvent event) { public void info(GenericInteractionCreateEvent event) {
GuildMusicManager musicManager = getGuildAudioPlayer(); GuildMusicManager musicManager = getGuildAudioPlayer();
AudioTrackInfo info = musicManager.scheduler.getInfo(); AudioTrackInfo info = musicManager.scheduler.getInfo();
UserAudioTrack userAudioTrack = musicManager.scheduler.getCurrentPlayingTrack(); UserAudioTrack userAudioTrack = musicManager.scheduler.getCurrentPlayingTrack();
Message message = new MessageBuilder().setEmbeds(EmbedMessageUtils.getMusicInfo(info, userAudioTrack)).build(); Message message = new MessageBuilder().setEmbeds(EmbedMessageUtils.getMusicInfo(info, userAudioTrack)).build();
event.getHook().sendMessage(message).queue(); clearLastButton();
lastMessageWithButton = event.getHook().sendMessage(message).addActionRow(getActionButton()).complete();
} }
public void flush(SlashCommandEvent event) { public void flush(GenericInteractionCreateEvent event) {
GuildMusicManager musicManager = getGuildAudioPlayer(); GuildMusicManager musicManager = getGuildAudioPlayer();
musicManager.scheduler.flush(); musicManager.scheduler.flush();
Message message = new MessageBuilder().setEmbeds( Message message = new MessageBuilder().setEmbeds(
@ -282,7 +302,8 @@ public class AudioM {
.setTitle(":wastebasket: Playlist flushed") .setTitle(":wastebasket: Playlist flushed")
.setColor(Color.green) .setColor(Color.green)
)).build(); )).build();
event.getHook().sendMessage(message).queue(); clearLastButton();
lastMessageWithButton = event.getHook().sendMessage(message).addActionRow(getActionButton()).complete();
} }
/** /**
@ -290,7 +311,7 @@ public class AudioM {
* *
* @param event * @param event
*/ */
public void list(SlashCommandEvent event) { public void list(GenericInteractionCreateEvent event) {
GuildMusicManager musicManager = getGuildAudioPlayer(); GuildMusicManager musicManager = getGuildAudioPlayer();
List<UserAudioTrackData> list = musicManager.scheduler.getList(); List<UserAudioTrackData> list = musicManager.scheduler.getList();
@ -354,16 +375,39 @@ public class AudioM {
* *
* @param event * @param event
*/ */
public void stop(SlashCommandEvent event) { public void stop(GenericInteractionCreateEvent event) {
musicManager.scheduler.stop(); musicManager.scheduler.stop();
musicManager.scheduler.flush(); musicManager.scheduler.flush();
if (event != null) { if (event != null) {
Message message = new MessageBuilder().setEmbeds(EmbedMessageUtils.getMusicOk("Music stopped")).build(); Message message = new MessageBuilder().setEmbeds(
event.getHook().sendMessage(message).queue(); EmbedMessageUtils.buildStandar(
new EmbedBuilder()
.setTitle(":stop_button: Playback stopped")
.setColor(Color.green)
)).build();
clearLastButton();
lastMessageWithButton = event.getHook().sendMessage(message).addActionRow(getActionButton()).complete();
} }
} }
public void disconect(GenericInteractionCreateEvent event){
GuildMusicManager musicManager = getGuildAudioPlayer();
musicManager.scheduler.stop();
musicManager.scheduler.flush();
playedChanel = null;
guild.getAudioManager().closeAudioConnection();
clearLastButton();
Message message = new MessageBuilder().setEmbeds(
EmbedMessageUtils.buildStandar(
new EmbedBuilder()
.setTitle(":eject: Disconnected")
.setColor(Color.green)
)).build();
clearLastButton();
event.getHook().sendMessage(message).queue();
}
/** /**
* Stop current playing track and flush playlist (no confirmation message) * Stop current playing track and flush playlist (no confirmation message)
*/ */
@ -374,6 +418,7 @@ public class AudioM {
musicManager.scheduler.flush(); musicManager.scheduler.flush();
playedChanel = null; playedChanel = null;
guild.getAudioManager().closeAudioConnection(); guild.getAudioManager().closeAudioConnection();
clearLastButton();
} }
public GuildMusicManager getGuildMusicManager() { public GuildMusicManager getGuildMusicManager() {
@ -398,4 +443,38 @@ public class AudioM {
public void setPlayedChanel(VoiceChannel playedChanel) { public void setPlayedChanel(VoiceChannel playedChanel) {
this.playedChanel = playedChanel; this.playedChanel = playedChanel;
} }
public void clearLastButton() {
if (lastMessageWithButton != null){
this.lastMessageWithButton.editMessageComponents(new ArrayList<>()).queue();
this.lastMessageWithButton = null;
}
}
public void updateLastButton(){
if (lastMessageWithButton != null)
lastMessageWithButton = lastMessageWithButton.editMessageComponents(ActionRow.of(getActionButton())).complete();
}
private List<Button> getActionButton(){
ArrayList<Button> buttonArrayList = new ArrayList<>();
if(musicManager.player.getPlayingTrack() == null){
buttonArrayList.add(Button.success("play", Emoji.fromUnicode("▶️")).withDisabled(true));
buttonArrayList.add(Button.primary("next", Emoji.fromUnicode("⏭️")).withDisabled(true));
buttonArrayList.add(Button.primary("stop", Emoji.fromUnicode("⏹️")).withDisabled(true));
buttonArrayList.add(Button.danger("disconnect", Emoji.fromUnicode("⏏️")));
return buttonArrayList;
}
if(musicManager.player.isPaused()){
buttonArrayList.add(Button.success("play", Emoji.fromUnicode("▶️")));
}
else{
buttonArrayList.add(Button.success("pause", Emoji.fromUnicode("⏸️")));
}
buttonArrayList.add(Button.primary("next", Emoji.fromUnicode("⏭️")));
buttonArrayList.add(Button.primary("stop", Emoji.fromUnicode("⏹️")));
buttonArrayList.add(Button.danger("disconnect", Emoji.fromUnicode("⏏️")));
return buttonArrayList;
}
} }

View File

@ -3,6 +3,7 @@ package net.Broken.audio;
import com.google.api.client.googleapis.json.GoogleJsonResponseException; import com.google.api.client.googleapis.json.GoogleJsonResponseException;
import com.sedmelluq.discord.lavaplayer.player.AudioPlayer; import com.sedmelluq.discord.lavaplayer.player.AudioPlayer;
import com.sedmelluq.discord.lavaplayer.player.event.AudioEventAdapter; import com.sedmelluq.discord.lavaplayer.player.event.AudioEventAdapter;
import com.sedmelluq.discord.lavaplayer.tools.FriendlyException;
import com.sedmelluq.discord.lavaplayer.track.AudioTrack; import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
import com.sedmelluq.discord.lavaplayer.track.AudioTrackEndReason; import com.sedmelluq.discord.lavaplayer.track.AudioTrackEndReason;
import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo;
@ -163,10 +164,11 @@ public class TrackScheduler extends AudioEventAdapter {
// Start the next track, regardless of if something is already playing or not. In case queue was empty, we are // Start the next track, regardless of if something is already playing or not. In case queue was empty, we are
// giving null to startTrack, which is a valid argument and will simply stop the player. // giving null to startTrack, which is a valid argument and will simply stop the player.
UserAudioTrack track = queue.poll(); UserAudioTrack track = queue.poll();
if (track != null) if (track != null){
this.currentPlayingTrack = track; this.currentPlayingTrack = track;
if (track != null)
player.startTrack(track.getAudioTrack(), false); player.startTrack(track.getAudioTrack(), false);
}
needAutoPlay(); needAutoPlay();
} }
@ -174,9 +176,46 @@ public class TrackScheduler extends AudioEventAdapter {
public void onTrackEnd(AudioPlayer player, AudioTrack track, AudioTrackEndReason endReason) { public void onTrackEnd(AudioPlayer player, AudioTrack track, AudioTrackEndReason endReason) {
// Only start the next track if the end reason is suitable for it (FINISHED or LOAD_FAILED) // Only start the next track if the end reason is suitable for it (FINISHED or LOAD_FAILED)
if (endReason.mayStartNext) { if (endReason.mayStartNext) {
logger.debug("[" + guild + "] End of track, start next."); if(queue.isEmpty()){
logger.debug("[" + guild.getName() + "] End of track, Playlist empty.");
AudioM.getInstance(guild).updateLastButton();
}else{
logger.debug("[" + guild.getName() + "] End of track, start next.");
nextTrack(); nextTrack();
} }
}
}
@Override
public void onTrackStart(AudioPlayer player, AudioTrack track) {
super.onTrackStart(player, track);
AudioM.getInstance(guild).updateLastButton();
}
@Override
public void onPlayerPause(AudioPlayer player) {
super.onPlayerPause(player);
AudioM.getInstance(guild).updateLastButton();
}
@Override
public void onPlayerResume(AudioPlayer player) {
super.onPlayerResume(player);
AudioM.getInstance(guild).updateLastButton();
}
@Override
public void onTrackException(AudioPlayer player, AudioTrack track, FriendlyException exception) {
super.onTrackException(player, track, exception);
AudioM.getInstance(guild).updateLastButton();
}
@Override
public void onTrackStuck(AudioPlayer player, AudioTrack track, long thresholdMs) {
super.onTrackStuck(player, track, thresholdMs);
AudioM.getInstance(guild).updateLastButton();
} }
private void needAutoPlay() { private void needAutoPlay() {