=Fixing Youtube Player
This commit is contained in:
@@ -15,6 +15,9 @@ public class CommandMusicMain extends Command
|
|||||||
framework.addCommand("join", new SubCommandJoin(KittyRole.General, KittyRating.Safe));
|
framework.addCommand("join", new SubCommandJoin(KittyRole.General, KittyRating.Safe));
|
||||||
framework.addCommand("leave", new SubCommandLeave(KittyRole.General, KittyRating.Safe));
|
framework.addCommand("leave", new SubCommandLeave(KittyRole.General, KittyRating.Safe));
|
||||||
framework.addCommand("add", new SubCommandAddTrack(KittyRole.General, KittyRating.Safe));
|
framework.addCommand("add", new SubCommandAddTrack(KittyRole.General, KittyRating.Safe));
|
||||||
|
framework.addCommand("skip", new SubCommandSkip(KittyRole.General, KittyRating.Safe));
|
||||||
|
framework.addCommand("stop", new SubCommandStop(KittyRole.General, KittyRating.Safe));
|
||||||
|
framework.addCommand("playlist", new SubCommandPlaylist(KittyRole.General, KittyRating.Safe));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import dataStructures.KittyRole;
|
|||||||
import dataStructures.KittyUser;
|
import dataStructures.KittyUser;
|
||||||
import dataStructures.UserInput;
|
import dataStructures.UserInput;
|
||||||
import network.NetworkYoutube;
|
import network.NetworkYoutube;
|
||||||
import utils.audio.AudioController;
|
|
||||||
|
|
||||||
public class SubCommandAddTrack extends SubCommand
|
public class SubCommandAddTrack extends SubCommand
|
||||||
{
|
{
|
||||||
@@ -17,16 +16,17 @@ public class SubCommandAddTrack extends SubCommand
|
|||||||
public SubCommandAddTrack(KittyRole level, KittyRating rating) { super(level, rating); }
|
public SubCommandAddTrack(KittyRole level, KittyRating rating) { super(level, rating); }
|
||||||
|
|
||||||
NetworkYoutube YT = new NetworkYoutube();
|
NetworkYoutube YT = new NetworkYoutube();
|
||||||
AudioController ac = new AudioController();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SubCommandFormattable OnRun(KittyGuild guild, KittyChannel channel, KittyUser user, UserInput input)
|
public SubCommandFormattable OnRun(KittyGuild guild, KittyChannel channel, KittyUser user, UserInput input)
|
||||||
{
|
{
|
||||||
//Get track from Youtube
|
//Get track from Youtube
|
||||||
String video = YT.getYT(input.args);
|
String video = input.args;
|
||||||
ac.loadAndPlay(video, guild);
|
if(!(video.startsWith("https://www.youtube") || video.startsWith("https://www.youtu.be")))
|
||||||
System.out.println("Internal: " + ac.response);
|
{
|
||||||
|
video = YT.getYT(video);
|
||||||
|
}
|
||||||
|
guild.audio.playVideo(video);
|
||||||
return new SubCommandFormattable(video);
|
return new SubCommandFormattable(video);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package commands.music;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
|
||||||
|
|
||||||
|
import core.SubCommand;
|
||||||
|
import core.SubCommandFormattable;
|
||||||
|
import dataStructures.*;
|
||||||
|
|
||||||
|
public class SubCommandPlaylist extends SubCommand
|
||||||
|
{
|
||||||
|
|
||||||
|
public SubCommandPlaylist(KittyRole roleLevel, KittyRating contentRating) {super(roleLevel, contentRating); }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SubCommandFormattable OnRun(KittyGuild guild, KittyChannel channel, KittyUser user, UserInput input)
|
||||||
|
{
|
||||||
|
// ArrayList<AudioTrack> playlist = guild.audio.getPlaylist();
|
||||||
|
String stringPlaylist = guild.audio.getPlaylist(guild.audio.player);
|
||||||
|
return new SubCommandFormattable(stringPlaylist);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package commands.music;
|
||||||
|
|
||||||
|
import core.SubCommand;
|
||||||
|
import core.SubCommandFormattable;
|
||||||
|
import dataStructures.KittyChannel;
|
||||||
|
import dataStructures.KittyGuild;
|
||||||
|
import dataStructures.KittyRating;
|
||||||
|
import dataStructures.KittyRole;
|
||||||
|
import dataStructures.KittyUser;
|
||||||
|
import dataStructures.UserInput;
|
||||||
|
|
||||||
|
public class SubCommandSkip extends SubCommand
|
||||||
|
{
|
||||||
|
public SubCommandSkip(KittyRole level, KittyRating rating) { super(level, rating); }
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public SubCommandFormattable OnRun(KittyGuild guild, KittyChannel channel, KittyUser user, UserInput input)
|
||||||
|
{
|
||||||
|
return new SubCommandFormattable(guild.audio.skipVideo(guild.audio.player));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package commands.music;
|
||||||
|
|
||||||
|
import core.SubCommand;
|
||||||
|
import core.SubCommandFormattable;
|
||||||
|
import dataStructures.KittyChannel;
|
||||||
|
import dataStructures.KittyGuild;
|
||||||
|
import dataStructures.KittyRating;
|
||||||
|
import dataStructures.KittyRole;
|
||||||
|
import dataStructures.KittyUser;
|
||||||
|
import dataStructures.UserInput;
|
||||||
|
|
||||||
|
public class SubCommandStop extends SubCommand
|
||||||
|
{
|
||||||
|
|
||||||
|
public SubCommandStop(KittyRole roleLevel, KittyRating contentRating) {super(roleLevel, contentRating);}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SubCommandFormattable OnRun(KittyGuild guild, KittyChannel channel, KittyUser user, UserInput input)
|
||||||
|
{
|
||||||
|
|
||||||
|
return new SubCommandFormattable(guild.audio.stopPlayer(guild.audio.player));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -7,16 +7,29 @@ import java.util.concurrent.Semaphore;
|
|||||||
|
|
||||||
import javax.security.auth.login.LoginException;
|
import javax.security.auth.login.LoginException;
|
||||||
|
|
||||||
|
import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager;
|
||||||
|
import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager;
|
||||||
|
import com.sedmelluq.discord.lavaplayer.source.AudioSourceManagers;
|
||||||
|
|
||||||
//import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager;
|
//import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager;
|
||||||
//import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager;
|
//import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager;
|
||||||
|
|
||||||
import core.lua.PluginManager;
|
import core.lua.PluginManager;
|
||||||
import dataStructures.*;
|
import dataStructures.KittyChannel;
|
||||||
|
import dataStructures.KittyCore;
|
||||||
|
import dataStructures.KittyGuild;
|
||||||
|
import dataStructures.KittyRating;
|
||||||
|
import dataStructures.KittyRole;
|
||||||
|
import dataStructures.KittyUser;
|
||||||
import main.Main;
|
import main.Main;
|
||||||
import net.dv8tion.jda.core.AccountType;
|
import net.dv8tion.jda.core.AccountType;
|
||||||
import net.dv8tion.jda.core.JDA;
|
import net.dv8tion.jda.core.JDA;
|
||||||
import net.dv8tion.jda.core.JDABuilder;
|
import net.dv8tion.jda.core.JDABuilder;
|
||||||
import net.dv8tion.jda.core.entities.*;
|
import net.dv8tion.jda.core.entities.Emote;
|
||||||
|
import net.dv8tion.jda.core.entities.Game;
|
||||||
|
import net.dv8tion.jda.core.entities.Guild;
|
||||||
|
import net.dv8tion.jda.core.entities.Member;
|
||||||
|
import net.dv8tion.jda.core.entities.User;
|
||||||
import net.dv8tion.jda.core.events.message.guild.GuildMessageReceivedEvent;
|
import net.dv8tion.jda.core.events.message.guild.GuildMessageReceivedEvent;
|
||||||
import offline.Ref;
|
import offline.Ref;
|
||||||
import utils.AdminControl;
|
import utils.AdminControl;
|
||||||
@@ -56,7 +69,7 @@ public class ObjectBuilderFactory
|
|||||||
private static CommandManager commandManager;
|
private static CommandManager commandManager;
|
||||||
|
|
||||||
//Audio track manager
|
//Audio track manager
|
||||||
// private static AudioPlayerManager audioPlayer = new DefaultAudioPlayerManager();
|
private static AudioPlayerManager playerManager = new DefaultAudioPlayerManager();
|
||||||
|
|
||||||
// Localization classes - these are singletons, but should be initialized before almost all other
|
// Localization classes - these are singletons, but should be initialized before almost all other
|
||||||
// things so their inclusion in the factory is to ensure they're started at the correct time.
|
// things so their inclusion in the factory is to ensure they're started at the correct time.
|
||||||
@@ -91,6 +104,9 @@ public class ObjectBuilderFactory
|
|||||||
database = null;
|
database = null;
|
||||||
stats = null;
|
stats = null;
|
||||||
|
|
||||||
|
AudioSourceManagers.registerRemoteSources(playerManager);
|
||||||
|
AudioSourceManagers.registerLocalSource(playerManager);
|
||||||
|
|
||||||
// Start by reading from things that are external. Because
|
// Start by reading from things that are external. Because
|
||||||
// we require these things to be resolved before the rest of the application,
|
// we require these things to be resolved before the rest of the application,
|
||||||
// we place them here.
|
// we place them here.
|
||||||
@@ -148,7 +164,7 @@ public class ObjectBuilderFactory
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Construct a new guild with defaults
|
// Construct a new guild with defaults
|
||||||
guild = new KittyGuild(uid, new AdminControl(event.getGuild()), emotesString, new AudioUtils(event.getGuild()));
|
guild = new KittyGuild(uid, new AdminControl(event.getGuild()), emotesString, new AudioUtils(event.getGuild(), playerManager));
|
||||||
DatabaseManager.instance.globalRegister(guild);
|
DatabaseManager.instance.globalRegister(guild);
|
||||||
guildCache.put(uid, guild);
|
guildCache.put(uid, guild);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,15 +2,10 @@ package dataStructures;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager;
|
|
||||||
import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager;
|
|
||||||
import com.sedmelluq.discord.lavaplayer.source.AudioSourceManagers;
|
|
||||||
|
|
||||||
import core.DatabaseManager;
|
import core.DatabaseManager;
|
||||||
import core.DatabaseTrackedObject;
|
import core.DatabaseTrackedObject;
|
||||||
import utils.AdminControl;
|
import utils.AdminControl;
|
||||||
import utils.audio.AudioUtils;
|
import utils.audio.AudioUtils;
|
||||||
import utils.audio.GuildMusicManager;
|
|
||||||
|
|
||||||
// Context for a given guild for kittybot. Primarily designed to hold guild-specific settings.
|
// Context for a given guild for kittybot. Primarily designed to hold guild-specific settings.
|
||||||
public class KittyGuild extends DatabaseTrackedObject
|
public class KittyGuild extends DatabaseTrackedObject
|
||||||
@@ -28,8 +23,6 @@ public class KittyGuild extends DatabaseTrackedObject
|
|||||||
public ArrayList <KittyPoll> choices = new ArrayList<KittyPoll>();
|
public ArrayList <KittyPoll> choices = new ArrayList<KittyPoll>();
|
||||||
public AdminControl control;
|
public AdminControl control;
|
||||||
public AudioUtils audio;
|
public AudioUtils audio;
|
||||||
public GuildMusicManager musicManager;
|
|
||||||
public AudioPlayerManager playerManager = new DefaultAudioPlayerManager();
|
|
||||||
public ArrayList <KittyUser> raffleUsersUnchosen = new ArrayList<KittyUser>();
|
public ArrayList <KittyUser> raffleUsersUnchosen = new ArrayList<KittyUser>();
|
||||||
public ArrayList <KittyUser> raffleUsersChosen = new ArrayList<KittyUser>();
|
public ArrayList <KittyUser> raffleUsersChosen = new ArrayList<KittyUser>();
|
||||||
|
|
||||||
@@ -51,14 +44,12 @@ public class KittyGuild extends DatabaseTrackedObject
|
|||||||
// Default content for a guild
|
// Default content for a guild
|
||||||
public KittyGuild(String uniqueID, AdminControl adminControl, ArrayList <String> emoji, AudioUtils audio)
|
public KittyGuild(String uniqueID, AdminControl adminControl, ArrayList <String> emoji, AudioUtils audio)
|
||||||
{
|
{
|
||||||
|
|
||||||
super(uniqueID);
|
super(uniqueID);
|
||||||
AudioSourceManagers.registerRemoteSources(playerManager);
|
|
||||||
AudioSourceManagers.registerLocalSource(playerManager);
|
|
||||||
this.uniqueID = uniqueID;
|
this.uniqueID = uniqueID;
|
||||||
roleList = new KittyTrackedVector(roleListName, uniqueID);
|
roleList = new KittyTrackedVector(roleListName, uniqueID);
|
||||||
beans = new KittyTrackedLong(beansName, uniqueID);
|
beans = new KittyTrackedLong(beansName, uniqueID);
|
||||||
registerTrackedObjects();
|
registerTrackedObjects();
|
||||||
musicManager = new GuildMusicManager(playerManager);
|
|
||||||
|
|
||||||
control = adminControl;
|
control = adminControl;
|
||||||
this.contentRating = KittyRating.Safe;
|
this.contentRating = KittyRating.Safe;
|
||||||
|
|||||||
@@ -49,110 +49,6 @@ import utils.GlobalLog;
|
|||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public class Main extends ListenerAdapter
|
public class Main extends ListenerAdapter
|
||||||
{
|
{
|
||||||
public class AudioPlayerSendHandler implements AudioSendHandler
|
|
||||||
{
|
|
||||||
private final AudioPlayer audioPlayer;
|
|
||||||
private AudioFrame lastFrame;
|
|
||||||
|
|
||||||
public AudioPlayerSendHandler(AudioPlayer audioPlayer)
|
|
||||||
{
|
|
||||||
this.audioPlayer = audioPlayer;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canProvide()
|
|
||||||
{
|
|
||||||
lastFrame = audioPlayer.provide();
|
|
||||||
return lastFrame != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public byte[] provide20MsAudio()
|
|
||||||
{
|
|
||||||
return lastFrame.getData();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public boolean isOpus()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class SmallAudio implements AudioLoadResultHandler
|
|
||||||
{
|
|
||||||
private TextChannel channel;
|
|
||||||
private Guild guild;
|
|
||||||
private AudioPlayer player;
|
|
||||||
|
|
||||||
private SmallAudio(TextChannel channel, Guild guild, AudioPlayer player)
|
|
||||||
{
|
|
||||||
this.channel = channel;
|
|
||||||
this.player = player;
|
|
||||||
this.guild = guild;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public void loadFailed(FriendlyException arg0) { }
|
|
||||||
@Override public void noMatches() { }
|
|
||||||
@Override public void playlistLoaded(AudioPlaylist arg0) { }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void trackLoaded(AudioTrack track)
|
|
||||||
{
|
|
||||||
connectToFirstVoiceChannel(guild.getAudioManager());
|
|
||||||
player.startTrack(track, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void connectToFirstVoiceChannel(AudioManager audioManager)
|
|
||||||
{
|
|
||||||
if (!audioManager.isConnected() && !audioManager.isAttemptingToConnect())
|
|
||||||
{
|
|
||||||
for (VoiceChannel voiceChannel : audioManager.getGuild().getVoiceChannels())
|
|
||||||
{
|
|
||||||
audioManager.openAudioConnection(voiceChannel);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public final AudioPlayerManager playerManager;
|
|
||||||
public final AudioPlayer player;
|
|
||||||
|
|
||||||
// Initialization and setup
|
|
||||||
public static void main(String[] args) throws InterruptedException, LoginException, Exception
|
|
||||||
{
|
|
||||||
JDA bot = new JDABuilder(AccountType.BOT).setToken(Ref.TestToken).buildBlocking();
|
|
||||||
bot.addEventListener(new Main());
|
|
||||||
}
|
|
||||||
|
|
||||||
public Main()
|
|
||||||
{
|
|
||||||
this.playerManager = new DefaultAudioPlayerManager();
|
|
||||||
this.player = playerManager.createPlayer();
|
|
||||||
|
|
||||||
AudioSourceManagers.registerRemoteSources(playerManager);
|
|
||||||
AudioSourceManagers.registerLocalSource(playerManager);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onGuildMessageReceived(GuildMessageReceivedEvent event)
|
|
||||||
{
|
|
||||||
if(event.getMessage().getContentRaw().contains("!hasan"))
|
|
||||||
{
|
|
||||||
final TextChannel channel = event.getChannel();
|
|
||||||
final Guild guild = channel.getGuild();
|
|
||||||
|
|
||||||
guild.getAudioManager().setSendingHandler(new AudioPlayerSendHandler(player));
|
|
||||||
|
|
||||||
playerManager.loadItemOrdered(player, "https://www.youtube.com/watch?v=qL-JCVA22Lo", new SmallAudio(channel, guild, player));
|
|
||||||
}
|
|
||||||
|
|
||||||
super.onGuildMessageReceived(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
// Variables and bot specific objects
|
// Variables and bot specific objects
|
||||||
private static KittyCore kittyCore;
|
private static KittyCore kittyCore;
|
||||||
private static DatabaseManager databaseManager;
|
private static DatabaseManager databaseManager;
|
||||||
@@ -237,4 +133,3 @@ public class Main extends ListenerAdapter
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
package utils.audio;
|
|
||||||
|
|
||||||
import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler;
|
|
||||||
import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager;
|
|
||||||
import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager;
|
|
||||||
import com.sedmelluq.discord.lavaplayer.source.AudioSourceManagers;
|
|
||||||
import com.sedmelluq.discord.lavaplayer.tools.FriendlyException;
|
|
||||||
import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist;
|
|
||||||
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
|
|
||||||
|
|
||||||
import dataStructures.KittyGuild;
|
|
||||||
|
|
||||||
public class AudioController
|
|
||||||
{
|
|
||||||
private final AudioPlayerManager playerManager;
|
|
||||||
public String response;
|
|
||||||
|
|
||||||
public AudioController()
|
|
||||||
{
|
|
||||||
playerManager = new DefaultAudioPlayerManager();
|
|
||||||
AudioSourceManagers.registerRemoteSources(playerManager);
|
|
||||||
AudioSourceManagers.registerLocalSource(playerManager);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void loadAndPlay(final String trackUrl, KittyGuild guild)
|
|
||||||
{
|
|
||||||
GuildMusicManager musicManager = guild.musicManager;
|
|
||||||
response = "HERE";
|
|
||||||
|
|
||||||
playerManager.loadItemOrdered(musicManager, trackUrl, new AudioLoadResultHandler()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void trackLoaded(AudioTrack track)
|
|
||||||
{
|
|
||||||
response = "Adding to queue " + track.getInfo().title;
|
|
||||||
System.out.println("QUEUED");
|
|
||||||
play(musicManager, track);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void playlistLoaded(AudioPlaylist playlist)
|
|
||||||
{
|
|
||||||
AudioTrack firstTrack = playlist.getSelectedTrack();
|
|
||||||
|
|
||||||
if (firstTrack == null)
|
|
||||||
{
|
|
||||||
firstTrack = playlist.getTracks().get(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
response = "Adding to queue " + firstTrack.getInfo().title + " (first track of playlist " + playlist.getName() + ")";
|
|
||||||
|
|
||||||
play(musicManager, firstTrack);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void noMatches()
|
|
||||||
{
|
|
||||||
System.out.println("NOT QUEUED");
|
|
||||||
response = "Nothing found by " + trackUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void loadFailed(FriendlyException exception)
|
|
||||||
{
|
|
||||||
System.out.println("EXCEPTION");
|
|
||||||
System.out.println(exception.getCause());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void play(GuildMusicManager musicManager, AudioTrack track)
|
|
||||||
{
|
|
||||||
|
|
||||||
musicManager.scheduler.queue(track);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void skipTrack(KittyGuild guild)
|
|
||||||
{
|
|
||||||
GuildMusicManager musicManager = guild.musicManager;
|
|
||||||
musicManager.scheduler.nextTrack();
|
|
||||||
|
|
||||||
response = "Skipped to next track.";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
package utils.audio;
|
|
||||||
|
|
||||||
import com.sedmelluq.discord.lavaplayer.player.AudioPlayer;
|
|
||||||
import com.sedmelluq.discord.lavaplayer.track.playback.AudioFrame;
|
|
||||||
|
|
||||||
import net.dv8tion.jda.core.audio.AudioSendHandler;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is a wrapper around AudioPlayer which makes it behave as an AudioSendHandler for JDA. As JDA calls canProvide
|
|
||||||
* before every call to provide20MsAudio(), we pull the frame in canProvide() and use the frame we already pulled in
|
|
||||||
* provide20MsAudio().
|
|
||||||
*/
|
|
||||||
public class AudioPlayerSendHandler implements AudioSendHandler
|
|
||||||
{
|
|
||||||
private final AudioPlayer audioPlayer;
|
|
||||||
private AudioFrame lastFrame;
|
|
||||||
|
|
||||||
public AudioPlayerSendHandler(AudioPlayer audioPlayer)
|
|
||||||
{
|
|
||||||
this.audioPlayer = audioPlayer;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canProvide()
|
|
||||||
{
|
|
||||||
lastFrame = audioPlayer.provide();
|
|
||||||
return lastFrame != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] provide20MsAudio()
|
|
||||||
{
|
|
||||||
return lastFrame.getData();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isOpus()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,17 @@
|
|||||||
package utils.audio;
|
package utils.audio;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.Queue;
|
||||||
|
|
||||||
|
import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler;
|
||||||
|
import com.sedmelluq.discord.lavaplayer.player.AudioPlayer;
|
||||||
|
import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager;
|
||||||
|
import com.sedmelluq.discord.lavaplayer.tools.FriendlyException;
|
||||||
|
import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist;
|
||||||
|
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
|
||||||
|
import com.sedmelluq.discord.lavaplayer.track.playback.AudioFrame;
|
||||||
|
|
||||||
|
import net.dv8tion.jda.core.audio.AudioSendHandler;
|
||||||
import net.dv8tion.jda.core.entities.Guild;
|
import net.dv8tion.jda.core.entities.Guild;
|
||||||
import net.dv8tion.jda.core.entities.VoiceChannel;
|
import net.dv8tion.jda.core.entities.VoiceChannel;
|
||||||
import net.dv8tion.jda.core.managers.AudioManager;
|
import net.dv8tion.jda.core.managers.AudioManager;
|
||||||
@@ -6,13 +19,19 @@ import net.dv8tion.jda.core.managers.AudioManager;
|
|||||||
public class AudioUtils
|
public class AudioUtils
|
||||||
{
|
{
|
||||||
private Guild guild;
|
private Guild guild;
|
||||||
public AudioManager audio;
|
public AudioManager am;
|
||||||
|
public final AudioPlayer player;
|
||||||
|
public final AudioPlayerManager playerManager;
|
||||||
|
private Queue <AudioTrack> playlist = new LinkedList<>();
|
||||||
|
|
||||||
|
|
||||||
public AudioUtils(Guild guild)
|
public AudioUtils(Guild guild, AudioPlayerManager playerManager)
|
||||||
{
|
{
|
||||||
|
player = playerManager.createPlayer();
|
||||||
|
this.playerManager = playerManager;
|
||||||
this.guild = guild;
|
this.guild = guild;
|
||||||
audio = guild.getAudioManager();
|
am = guild.getAudioManager();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean joinChannel(String channelName)
|
public boolean joinChannel(String channelName)
|
||||||
@@ -21,7 +40,7 @@ public class AudioUtils
|
|||||||
channel = guild.getVoiceChannelsByName(channelName, true).get(0);
|
channel = guild.getVoiceChannelsByName(channelName, true).get(0);
|
||||||
if(channel != null)
|
if(channel != null)
|
||||||
{
|
{
|
||||||
audio.openAudioConnection(channel);
|
am.openAudioConnection(channel);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -29,11 +48,100 @@ public class AudioUtils
|
|||||||
|
|
||||||
public boolean leaveChannel()
|
public boolean leaveChannel()
|
||||||
{
|
{
|
||||||
if(audio.isConnected())
|
if(am.isConnected())
|
||||||
{
|
{
|
||||||
audio.closeAudioConnection();
|
am.closeAudioConnection();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class AudioPlayerSendHandler implements AudioSendHandler
|
||||||
|
{
|
||||||
|
private final AudioPlayer audioPlayer;
|
||||||
|
private AudioFrame lastFrame;
|
||||||
|
|
||||||
|
public AudioPlayerSendHandler(AudioPlayer audioPlayer)
|
||||||
|
{
|
||||||
|
this.audioPlayer = audioPlayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canProvide()
|
||||||
|
{
|
||||||
|
lastFrame = audioPlayer.provide();
|
||||||
|
return lastFrame != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public byte[] provide20MsAudio()
|
||||||
|
{
|
||||||
|
return lastFrame.getData();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean isOpus()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SmallAudio implements AudioLoadResultHandler
|
||||||
|
{
|
||||||
|
private AudioPlayer player;
|
||||||
|
|
||||||
|
private SmallAudio(AudioPlayer player)
|
||||||
|
{
|
||||||
|
this.player = player;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void loadFailed(FriendlyException arg0) { }
|
||||||
|
@Override public void noMatches() { }
|
||||||
|
@Override public void playlistLoaded(AudioPlaylist arg0) { }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void trackLoaded(AudioTrack track)
|
||||||
|
{
|
||||||
|
synchronized(playlist)
|
||||||
|
{
|
||||||
|
playlist.add(track);
|
||||||
|
}
|
||||||
|
//if(player.getPlayingTrack() == null)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if(player.getPlayingTrack() == null)
|
||||||
|
{
|
||||||
|
player.startTrack(playlist.poll(), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while(!playlist.isEmpty());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String playVideo(String videoURL)
|
||||||
|
{
|
||||||
|
guild.getAudioManager().setSendingHandler(new AudioPlayerSendHandler(player));
|
||||||
|
playerManager.loadItemOrdered(player, videoURL, new SmallAudio(player));
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String skipVideo(AudioPlayer player)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String stopPlayer(AudioPlayer player)
|
||||||
|
{
|
||||||
|
playlist.clear();
|
||||||
|
player.stopTrack();
|
||||||
|
return "Stopped";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPlaylist(AudioPlayer player)
|
||||||
|
{
|
||||||
|
return player.getPlayingTrack().getInfo().title;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,36 +0,0 @@
|
|||||||
package utils.audio;
|
|
||||||
|
|
||||||
import com.sedmelluq.discord.lavaplayer.player.AudioPlayer;
|
|
||||||
import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holder for both the player and a track scheduler for one guild.
|
|
||||||
*/
|
|
||||||
public class GuildMusicManager {
|
|
||||||
/**
|
|
||||||
* Audio player for the guild.
|
|
||||||
*/
|
|
||||||
public final AudioPlayer player;
|
|
||||||
/**
|
|
||||||
* Track scheduler for the player.
|
|
||||||
*/
|
|
||||||
public final TrackScheduler scheduler;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a player and a track scheduler.
|
|
||||||
* @param manager Audio player manager to use for creating the player.
|
|
||||||
*/
|
|
||||||
public GuildMusicManager(AudioPlayerManager manager)
|
|
||||||
{
|
|
||||||
player = manager.createPlayer();
|
|
||||||
scheduler = new TrackScheduler(player);
|
|
||||||
player.addListener(scheduler);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Wrapper around AudioPlayer to use it as an AudioSendHandler.
|
|
||||||
*/
|
|
||||||
public AudioPlayerSendHandler getSendHandler() {
|
|
||||||
return new AudioPlayerSendHandler(player);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
package utils.audio;
|
|
||||||
|
|
||||||
import com.sedmelluq.discord.lavaplayer.player.AudioPlayer;
|
|
||||||
import com.sedmelluq.discord.lavaplayer.player.event.AudioEventAdapter;
|
|
||||||
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
|
|
||||||
import com.sedmelluq.discord.lavaplayer.track.AudioTrackEndReason;
|
|
||||||
|
|
||||||
import java.util.concurrent.BlockingQueue;
|
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class schedules tracks for the audio player. It contains the queue of tracks.
|
|
||||||
*/
|
|
||||||
public class TrackScheduler extends AudioEventAdapter {
|
|
||||||
private final AudioPlayer player;
|
|
||||||
private final BlockingQueue<AudioTrack> queue;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param player The audio player this scheduler uses
|
|
||||||
*/
|
|
||||||
public TrackScheduler(AudioPlayer player)
|
|
||||||
{
|
|
||||||
this.player = player;
|
|
||||||
this.queue = new LinkedBlockingQueue<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add the next track to queue or play right away if nothing is in the queue.
|
|
||||||
*
|
|
||||||
* @param track The track to play or add to queue.
|
|
||||||
*/
|
|
||||||
public void queue(AudioTrack track)
|
|
||||||
{
|
|
||||||
// Calling startTrack with the noInterrupt set to true will start the track only if nothing is currently playing. If
|
|
||||||
// something is playing, it returns false and does nothing. In that case the player was already playing so this
|
|
||||||
// track goes to the queue instead.
|
|
||||||
if (!player.startTrack(track, true))
|
|
||||||
{
|
|
||||||
queue.offer(track);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start the next track, stopping the current one if it is playing.
|
|
||||||
*/
|
|
||||||
public void nextTrack()
|
|
||||||
{
|
|
||||||
// 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.
|
|
||||||
player.startTrack(queue.poll(), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
nextTrack();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user