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.GuildVoiceLeaveEvent;
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.message.MessageReceivedEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
@ -28,6 +29,7 @@ import org.jetbrains.annotations.NotNull;
import org.springframework.context.ApplicationContext;
import java.awt.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@ -122,6 +124,9 @@ public class BotListener extends ListenerAdapter {
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.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
public void onSlashCommand(@NotNull SlashCommandEvent event) {
HashMap<String, SlashCommand> commands = MainBot.slashCommands;
@ -186,4 +205,6 @@ public class BotListener extends ListenerAdapter {
return guildPref;
}
}

View File

@ -13,15 +13,17 @@ import net.Broken.RestApi.Data.UserAudioTrackData;
import net.Broken.Tools.EmbedMessageUtils;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.MessageBuilder;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.entities.VoiceChannel;
import net.dv8tion.jda.api.entities.*;
import net.dv8tion.jda.api.events.interaction.GenericInteractionCreateEvent;
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.Logger;
import java.awt.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@ -55,6 +57,8 @@ public class AudioM {
private Guild guild;
private Logger logger = LogManager.getLogger();
private Message lastMessageWithButton;
private AudioM(Guild guild) {
this.playerManager = new DefaultAudioPlayerManager();
AudioSourceManagers.registerRemoteSources(playerManager);
@ -91,7 +95,8 @@ public class AudioM {
Message message = new MessageBuilder()
.setEmbeds(EmbedMessageUtils.getMusicAdded(track.getInfo(), event.getMember(), -1))
.build();
event.getHook().sendMessage(message).queue();
clearLastButton();
lastMessageWithButton = event.getHook().sendMessage(message).addActionRow(getActionButton()).complete();
play(guild, voiceChannel, musicManager, uat, onHead);
}
@ -103,7 +108,8 @@ public class AudioM {
Message message = new MessageBuilder()
.setEmbeds(EmbedMessageUtils.getMusicAdded(firstTrack.getInfo(), event.getMember(), size))
.build();
event.getHook().sendMessage(message).queue();
clearLastButton();
lastMessageWithButton = event.getHook().sendMessage(message).addActionRow(getActionButton()).complete();
playListLoader(playlist, playlistLimit, event.getUser(), onHead);
}
@ -212,16 +218,17 @@ public class AudioM {
*
* @param event
*/
public void skipTrack(SlashCommandEvent event) {
public void skipTrack(GenericInteractionCreateEvent event) {
GuildMusicManager musicManager = getGuildAudioPlayer();
musicManager.scheduler.nextTrack();
Message message = new MessageBuilder().setEmbeds(
EmbedMessageUtils.buildStandar(
new EmbedBuilder()
.setTitle(":track_next: Next Track")
.setColor(Color.green)
)).build();
event.getHook().sendMessage(message).queue();
.setTitle(":track_next: Next Track")
.setColor(Color.green)
)).build();
clearLastButton();
lastMessageWithButton = event.getHook().sendMessage(message).addActionRow(getActionButton()).complete();
}
/**
@ -229,7 +236,7 @@ public class AudioM {
*
* @param event
*/
public void pause(SlashCommandEvent event) {
public void pause(GenericInteractionCreateEvent event) {
GuildMusicManager musicManager = getGuildAudioPlayer();
musicManager.scheduler.pause();
Message message = new MessageBuilder().setEmbeds(
@ -238,7 +245,8 @@ public class AudioM {
.setTitle(":pause_button: Playback paused")
.setColor(Color.green)
)).build();
event.getHook().sendMessage(message).queue();
clearLastButton();
lastMessageWithButton = event.getHook().sendMessage(message).addActionRow(getActionButton()).complete();
}
@ -248,16 +256,27 @@ public class AudioM {
*
* @param event
*/
public void resume(SlashCommandEvent event) {
public void resume(GenericInteractionCreateEvent event) {
GuildMusicManager musicManager = getGuildAudioPlayer();
musicManager.scheduler.resume();
Message message = new MessageBuilder().setEmbeds(
EmbedMessageUtils.buildStandar(
new EmbedBuilder()
.setTitle(":arrow_forward: Playback resumed")
.setColor(Color.green)
)).build();
event.getHook().sendMessage(message).queue();
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();
message = new MessageBuilder().setEmbeds(
EmbedMessageUtils.buildStandar(
new EmbedBuilder()
.setTitle(":arrow_forward: Playback resumed")
.setColor(Color.green)
)).build();
}
clearLastButton();
lastMessageWithButton = event.getHook().sendMessage(message).addActionRow(getActionButton()).complete();
}
/**
@ -265,15 +284,16 @@ public class AudioM {
*
* @param event
*/
public void info(SlashCommandEvent event) {
public void info(GenericInteractionCreateEvent event) {
GuildMusicManager musicManager = getGuildAudioPlayer();
AudioTrackInfo info = musicManager.scheduler.getInfo();
UserAudioTrack userAudioTrack = musicManager.scheduler.getCurrentPlayingTrack();
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();
musicManager.scheduler.flush();
Message message = new MessageBuilder().setEmbeds(
@ -282,7 +302,8 @@ public class AudioM {
.setTitle(":wastebasket: Playlist flushed")
.setColor(Color.green)
)).build();
event.getHook().sendMessage(message).queue();
clearLastButton();
lastMessageWithButton = event.getHook().sendMessage(message).addActionRow(getActionButton()).complete();
}
/**
@ -290,7 +311,7 @@ public class AudioM {
*
* @param event
*/
public void list(SlashCommandEvent event) {
public void list(GenericInteractionCreateEvent event) {
GuildMusicManager musicManager = getGuildAudioPlayer();
List<UserAudioTrackData> list = musicManager.scheduler.getList();
@ -312,7 +333,7 @@ public class AudioM {
resp.append(" - ");
resp.append(trackInfo.getAudioTrackInfo().author);
resp.append("\n\n");
if (i >= 5){
if (i >= 5) {
resp.append(":arrow_forward: And ");
resp.append(list.size() - 5);
resp.append(" other tracks ...");
@ -354,16 +375,39 @@ public class AudioM {
*
* @param event
*/
public void stop(SlashCommandEvent event) {
public void stop(GenericInteractionCreateEvent event) {
musicManager.scheduler.stop();
musicManager.scheduler.flush();
if (event != null) {
Message message = new MessageBuilder().setEmbeds(EmbedMessageUtils.getMusicOk("Music stopped")).build();
event.getHook().sendMessage(message).queue();
Message message = new MessageBuilder().setEmbeds(
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)
*/
@ -374,6 +418,7 @@ public class AudioM {
musicManager.scheduler.flush();
playedChanel = null;
guild.getAudioManager().closeAudioConnection();
clearLastButton();
}
public GuildMusicManager getGuildMusicManager() {
@ -398,4 +443,38 @@ public class AudioM {
public void setPlayedChanel(VoiceChannel 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.sedmelluq.discord.lavaplayer.player.AudioPlayer;
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.AudioTrackEndReason;
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
// giving null to startTrack, which is a valid argument and will simply stop the player.
UserAudioTrack track = queue.poll();
if (track != null)
if (track != null){
this.currentPlayingTrack = track;
if (track != null)
player.startTrack(track.getAudioTrack(), false);
}
needAutoPlay();
}
@ -174,11 +176,48 @@ public class TrackScheduler extends AudioEventAdapter {
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)
if (endReason.mayStartNext) {
logger.debug("[" + guild + "] End of track, start next.");
nextTrack();
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();
}
}
}
@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() {
if ((queue.size() < 1) && autoFlow && currentPlayingTrack != null) {
logger.debug("[" + guild.getName() + "] Auto add needed!");