Initial Commit
This commit is contained in:
@ -0,0 +1,32 @@
|
||||
package net.locusworks.discord.eighttrack.handlers;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import com.sedmelluq.discord.lavaplayer.player.AudioPlayer;
|
||||
import com.sedmelluq.discord.lavaplayer.track.playback.AudioFrame;
|
||||
|
||||
import net.dv8tion.jda.api.audio.AudioSendHandler;
|
||||
|
||||
public class EightTrackAudioSendHandler implements AudioSendHandler {
|
||||
|
||||
private final AudioPlayer audioPlayer;
|
||||
private AudioFrame lastFrame;
|
||||
|
||||
public EightTrackAudioSendHandler(AudioPlayer audioPlayer) {
|
||||
this.audioPlayer = audioPlayer;
|
||||
}
|
||||
|
||||
public boolean canProvide() {
|
||||
lastFrame = audioPlayer.provide();
|
||||
return lastFrame != null;
|
||||
}
|
||||
|
||||
public ByteBuffer provide20MsAudio() {
|
||||
return ByteBuffer.wrap(lastFrame.getData());
|
||||
}
|
||||
|
||||
public boolean isOpus() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
154
src/main/java/net/locusworks/discord/eighttrack/main/Entry.java
Normal file
154
src/main/java/net/locusworks/discord/eighttrack/main/Entry.java
Normal file
@ -0,0 +1,154 @@
|
||||
package net.locusworks.discord.eighttrack.main;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.Iterator;
|
||||
|
||||
import javax.security.auth.login.LoginException;
|
||||
|
||||
import com.sedmelluq.discord.lavaplayer.player.AudioPlayer;
|
||||
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.track.AudioTrack;
|
||||
import net.dv8tion.jda.api.AccountType;
|
||||
import net.dv8tion.jda.api.EmbedBuilder;
|
||||
import net.dv8tion.jda.api.JDA;
|
||||
import net.dv8tion.jda.api.JDABuilder;
|
||||
import net.dv8tion.jda.api.Permission;
|
||||
import net.dv8tion.jda.api.entities.MessageEmbed;
|
||||
import net.dv8tion.jda.api.entities.VoiceChannel;
|
||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||
import net.dv8tion.jda.api.managers.AudioManager;
|
||||
import net.locusworks.discord.eighttrack.handlers.EightTrackAudioSendHandler;
|
||||
import net.locusworks.discord.eighttrack.scheduler.TrackScheduler;
|
||||
import net.locusworks.logger.ApplicationLogger;
|
||||
import net.locusworks.logger.ApplicationLoggerFactory;
|
||||
|
||||
public class Entry {
|
||||
|
||||
public static void main(String[] args) throws LoginException, IOException {
|
||||
if (args.length < 1) throw new RuntimeException("no token provided");
|
||||
|
||||
ApplicationLogger logger = ApplicationLoggerFactory.getLogger(Entry.class);
|
||||
logger.info("Starting Eight-Track");
|
||||
|
||||
JDA client = new JDABuilder(AccountType.BOT).setToken(args[0]).build();
|
||||
|
||||
AudioPlayerManager apm = new DefaultAudioPlayerManager();
|
||||
AudioSourceManagers.registerLocalSource(apm);
|
||||
|
||||
final AudioPlayer player = apm.createPlayer();
|
||||
|
||||
TrackScheduler ts = new TrackScheduler();
|
||||
|
||||
player.addListener(ts);
|
||||
|
||||
for (Iterator<Path> iter = Files.list(Paths.get(args[1])).iterator(); iter.hasNext();) {
|
||||
Path song = iter.next();
|
||||
if (!song.getFileName().toString().toLowerCase().endsWith(".mp3")) continue;
|
||||
logger.info("Loading song: %s", song);
|
||||
try {
|
||||
apm.loadItem(song.toAbsolutePath().toString(), ts);
|
||||
} catch (IllegalStateException ex) {
|
||||
logger.warn("Unable to load song :%s -> %s", song.toAbsolutePath().toString(), ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
client.addEventListener(new ListenerAdapter() {
|
||||
|
||||
@Override
|
||||
public void onMessageReceived(final MessageReceivedEvent event) {
|
||||
if (event.getAuthor().isBot()) return;
|
||||
|
||||
String command = event.getMessage().getContentRaw().trim().toLowerCase();
|
||||
|
||||
switch (command) {
|
||||
case "-play":
|
||||
play(event, ts, player);
|
||||
return;
|
||||
case "-stop":
|
||||
stop(event, ts, player);
|
||||
return;
|
||||
case "-next":
|
||||
next(event, ts, player);
|
||||
return;
|
||||
case "-repeat":
|
||||
repeat(event, ts, player);
|
||||
return;
|
||||
case "-whatsnext":
|
||||
whatsNext(event, ts, player);
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected static void whatsNext(MessageReceivedEvent event, TrackScheduler ts, AudioPlayer player) {
|
||||
AudioTrack track = ts.peek();
|
||||
MessageEmbed embed = new EmbedBuilder()
|
||||
.setAuthor(event.getMember().getEffectiveName(), null, event.getAuthor().getAvatarUrl())
|
||||
.setTitle("Next Up:")
|
||||
.setDescription(String.format("**%s** by __%s__", track.getInfo().title, track.getInfo().author))
|
||||
.setTimestamp(OffsetDateTime.now())
|
||||
.build();
|
||||
event.getTextChannel().sendMessage(embed).queue();
|
||||
}
|
||||
|
||||
protected static void repeat(MessageReceivedEvent event, TrackScheduler ts, AudioPlayer player) {
|
||||
next(event, ts, player);
|
||||
ts.setFinishedCallback((ater) -> {
|
||||
next(event, ts, player);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
protected static void next(MessageReceivedEvent event, TrackScheduler ts, AudioPlayer player) {
|
||||
stop(event, ts, player);
|
||||
play(event, ts, player);
|
||||
}
|
||||
|
||||
private static void stop(MessageReceivedEvent event, TrackScheduler ts, AudioPlayer player) {
|
||||
player.stopTrack();
|
||||
}
|
||||
|
||||
private static void play(MessageReceivedEvent event, TrackScheduler ts, AudioPlayer player) {
|
||||
VoiceChannel vc = event.getMember().getVoiceState().getChannel();
|
||||
if (vc == null) {
|
||||
event.getTextChannel().sendMessage(String.format("<@%s you are not in a voice channel to play music", event.getMember().getId())).queue();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!event.getGuild().getSelfMember().hasPermission(vc, Permission.VOICE_CONNECT, Permission.VOICE_SPEAK)) {
|
||||
event.getTextChannel().sendMessage(String.format("<@%s, I cannot play my music in channel %s as I dont have permission to",
|
||||
event.getMember().getId(), vc.getName())).queue();
|
||||
return;
|
||||
}
|
||||
|
||||
AudioManager manager = event.getGuild().getAudioManager();
|
||||
manager.openAudioConnection(vc);
|
||||
|
||||
manager.setSendingHandler(new EightTrackAudioSendHandler(player));
|
||||
|
||||
if (ts.hasTracks()) {
|
||||
AudioTrack track = ts.getNextTrack();
|
||||
|
||||
MessageEmbed embed = new EmbedBuilder()
|
||||
.setAuthor(event.getMember().getEffectiveName(), null, event.getAuthor().getAvatarUrl())
|
||||
.setTitle("Now Playing:")
|
||||
.setDescription(String.format("**%s** by __%s__", track.getInfo().title, track.getInfo().author))
|
||||
.setTimestamp(OffsetDateTime.now())
|
||||
.build();
|
||||
|
||||
event.getTextChannel().sendMessage(embed).queue();
|
||||
player.playTrack(track);
|
||||
ts.trackLoaded(track);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
package net.locusworks.discord.eighttrack.scheduler;
|
||||
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler;
|
||||
import com.sedmelluq.discord.lavaplayer.player.AudioPlayer;
|
||||
import com.sedmelluq.discord.lavaplayer.player.event.AudioEventAdapter;
|
||||
import com.sedmelluq.discord.lavaplayer.player.event.AudioEventListener;
|
||||
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.AudioTrackEndReason;
|
||||
|
||||
public class TrackScheduler extends AudioEventAdapter implements AudioEventListener, AudioLoadResultHandler {
|
||||
|
||||
private Queue<AudioTrack> trackQueue;
|
||||
|
||||
private boolean started;
|
||||
|
||||
private Consumer<AudioTrackEndReason> finished;
|
||||
|
||||
public TrackScheduler() {
|
||||
trackQueue = new LinkedBlockingQueue<AudioTrack>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTrackStart(AudioPlayer player, AudioTrack track) {
|
||||
this.started = true;
|
||||
super.onTrackStart(player, track);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTrackEnd(AudioPlayer player, AudioTrack track, AudioTrackEndReason endReason) {
|
||||
this.started = false;
|
||||
super.onTrackEnd(player, track, endReason);
|
||||
if (finished != null) finished.accept(endReason);
|
||||
}
|
||||
|
||||
public void setFinishedCallback(Consumer<AudioTrackEndReason> callback) {
|
||||
if (this.finished == null) this.finished = callback;
|
||||
}
|
||||
|
||||
public void trackLoaded(AudioTrack track) {
|
||||
trackQueue.add(track);
|
||||
}
|
||||
|
||||
public void playlistLoaded(AudioPlaylist playlist) {
|
||||
for (AudioTrack at : playlist.getTracks()) {
|
||||
trackQueue.add(at);
|
||||
}
|
||||
}
|
||||
|
||||
public void noMatches() {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
public void loadFailed(FriendlyException exception) {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
public AudioTrack peek() {
|
||||
return trackQueue.peek();
|
||||
}
|
||||
|
||||
public boolean hasTracks() {
|
||||
return !trackQueue.isEmpty();
|
||||
}
|
||||
|
||||
public AudioTrack getNextTrack() {
|
||||
return trackQueue.poll();
|
||||
}
|
||||
|
||||
public boolean playing() {
|
||||
return started;
|
||||
}
|
||||
|
||||
|
||||
}
|
29
src/main/resources/log4j2.xml
Normal file
29
src/main/resources/log4j2.xml
Normal file
@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE xml>
|
||||
<Configuration status="WARN" shutdownHook="disable"
|
||||
packages="net.locusworks.discord.eighttrack">
|
||||
<Properties>
|
||||
<property name="logLevel">${sys:LOG_LEVEL:-INFO}</property>
|
||||
<Property name="logFormat">%d{dd-MMM-yyyy HH:mm:ss.SSS} [%-5p] [%c{1}] %m%n</Property>
|
||||
</Properties>
|
||||
<Appenders>
|
||||
<Console name="ConsoleAppender" target="SYSTEM_OUT">
|
||||
<PatternLayout pattern="${logFormat}" />
|
||||
</Console>
|
||||
<RollingFile name="eighttrack"
|
||||
fileName="eighttrack.log"
|
||||
filePattern="eighttrackLO-%d{yyyy-MM-dd}.log.gz">
|
||||
<PatternLayout pattern="${logFormat}" />
|
||||
<Policies>
|
||||
<TimeBasedTriggeringPolicy />
|
||||
<SizeBasedTriggeringPolicy size="10 MB" />
|
||||
</Policies>
|
||||
</RollingFile>
|
||||
</Appenders>
|
||||
<Loggers>
|
||||
<Root level="TRACE">
|
||||
<AppenderRef ref="ConsoleAppender" level="${logLevel}" />
|
||||
<AppenderRef ref="eighttrack" level="${logLevel}" />
|
||||
</Root>
|
||||
</Loggers>
|
||||
</Configuration>
|
Reference in New Issue
Block a user