Mega-refactor: change song to track everywhere.
This commit is contained in:
parent
abfab9a18d
commit
2a25e1368d
|
@ -0,0 +1,72 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>moe.nekojimi</groupId>
|
||||
<artifactId>Chords</artifactId>
|
||||
<version>1.0</version>
|
||||
<packaging>jar</packaging>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>dv8tion</id>
|
||||
<name>m2-dv8tion</name>
|
||||
<url>https://m2.dv8tion.net/releases</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>
|
||||
moe.nekojimi.chords.Chords
|
||||
</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
<descriptorRefs>
|
||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||
</descriptorRefs>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>net.dv8tion</groupId>
|
||||
<artifactId>JDA</artifactId>
|
||||
<<<<<<< HEAD
|
||||
<version>5.0.0-beta.5</version>
|
||||
=======
|
||||
<version>5.0.0-beta.6</version>
|
||||
>>>>>>> b24453d (Update JDA to v5.0.)
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>2.11.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>moe.nekojimi</groupId>
|
||||
<artifactId>MusicSearcher</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<type>jar</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.json</groupId>
|
||||
<artifactId>javax.json-api</artifactId>
|
||||
<version>1.1.4</version>
|
||||
<type>jar</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.beust</groupId>
|
||||
<artifactId>jcommander</artifactId>
|
||||
<version>1.78</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.compiler.source>11</maven.compiler.source>
|
||||
<maven.compiler.target>11</maven.compiler.target>
|
||||
</properties>
|
||||
</project>
|
|
@ -128,9 +128,9 @@ public final class Chords extends ListenerAdapter
|
|||
JDA jda = builder.build();
|
||||
listener.setJda(jda);
|
||||
}
|
||||
private final Consumer<Song> nowPlayingConsumer = new NowPlayingConsumer();
|
||||
private final Consumer<Track> nowPlayingConsumer = new NowPlayingConsumer();
|
||||
|
||||
private final BiConsumer<SongRequest, Exception> downloaderMessageHandler = new DownloaderMessageHandler();
|
||||
private final BiConsumer<TrackRequest, Exception> downloaderMessageHandler = new DownloaderMessageHandler();
|
||||
|
||||
public Chords() throws IOException
|
||||
{
|
||||
|
@ -253,12 +253,12 @@ public final class Chords extends ListenerAdapter
|
|||
}
|
||||
}
|
||||
|
||||
public void queueDownload(SongRequest request)
|
||||
public void queueDownload(TrackRequest request)
|
||||
{
|
||||
// Song song;
|
||||
// Track track;
|
||||
// if (request.getUrl() != null)
|
||||
// {
|
||||
// song = new Song(request.getUrl());
|
||||
// track = new Track(request.getUrl());
|
||||
// } else
|
||||
// {
|
||||
// // interpret search result
|
||||
|
@ -268,15 +268,15 @@ public final class Chords extends ListenerAdapter
|
|||
// {
|
||||
//
|
||||
// }
|
||||
// song.setNumber(trackNumber);
|
||||
// track.setNumber(trackNumber);
|
||||
// trackNumber++;
|
||||
// request.addSong(song);
|
||||
// request.addTrack(track);
|
||||
request.getInvocation().respond("Request pending...");
|
||||
downloader.accept(new Downloader.DownloadTask(request, queueManager));
|
||||
// return song;
|
||||
// return track;
|
||||
}
|
||||
|
||||
public void setStatus(Song nowPlaying)
|
||||
public void setStatus(Track nowPlaying)
|
||||
{
|
||||
jda.getPresence().setActivity(Activity.listening(nowPlaying.toString()));
|
||||
}
|
||||
|
@ -396,7 +396,7 @@ public final class Chords extends ListenerAdapter
|
|||
return settings;
|
||||
}
|
||||
|
||||
private class DownloaderMessageHandler implements BiConsumer<SongRequest, Exception>
|
||||
private class DownloaderMessageHandler implements BiConsumer<TrackRequest, Exception>
|
||||
{
|
||||
|
||||
private static final String PROGRESS_SYMBOLS = " ▏▎▍▌▋▊▉█";
|
||||
|
@ -407,23 +407,23 @@ public final class Chords extends ListenerAdapter
|
|||
}
|
||||
|
||||
@Override
|
||||
public void accept(SongRequest request, Exception ex)
|
||||
public void accept(TrackRequest request, Exception ex)
|
||||
{
|
||||
String response = "";
|
||||
if (request.getSongs().size() > 1)
|
||||
response += "Downloading " + request.getSongs().size() + " tracks:\n";
|
||||
for (Song song : request.getSongs())
|
||||
if (request.getTracks().size() > 1)
|
||||
response += "Downloading " + request.getTracks().size() + " tracks:\n";
|
||||
for (Track track : request.getTracks())
|
||||
{
|
||||
// TextChannel channel = jda.getTextChannelById(song.getRequestedIn());
|
||||
// String bracketNo = "[" + song.getNumber() + "] ";
|
||||
// TextChannel channel = jda.getTextChannelById(track.getRequestedIn());
|
||||
// String bracketNo = "[" + track.getNumber() + "] ";
|
||||
if (ex == null)
|
||||
if (song.getLocation() != null && song.getProgress() >= 100)
|
||||
if (track.getLocation() != null && track.getProgress() >= 100)
|
||||
{
|
||||
response += ("Finished downloading " + song + ", added to queue!");
|
||||
log("DOWN", "Downloaded " + song);
|
||||
response += ("Finished downloading " + track + "!");
|
||||
log("DOWN", "Downloaded " + track);
|
||||
} else
|
||||
{
|
||||
Format format = song.getBestFormat();
|
||||
Format format = track.getBestFormat();
|
||||
String formatDetails = "";
|
||||
if (format != null)
|
||||
{
|
||||
|
@ -435,16 +435,16 @@ public final class Chords extends ListenerAdapter
|
|||
}
|
||||
|
||||
String progressDetails = "";
|
||||
if (song.getProgress() >= 0)
|
||||
progressDetails = " [" + String.format("%.1f", song.getProgress()) + "%]";
|
||||
if (track.getProgress() >= 0)
|
||||
progressDetails = " [" + String.format("%.1f", track.getProgress()) + "%]";
|
||||
|
||||
response += ("Now downloading " + song + formatDetails + progressDetails + " ...");
|
||||
log("DOWN", "Downloading " + song + "...");
|
||||
response += ("Now downloading " + track + formatDetails + progressDetails + " ...");
|
||||
log("DOWN", "Downloading " + track + "...");
|
||||
}
|
||||
else
|
||||
{
|
||||
response += ("Failed to download " + song + "! Reason: " + ex.getMessage());
|
||||
log("DOWN", "Failed to download " + song + "! Reason: " + ex.getMessage());
|
||||
response += ("Failed to download " + track + "! Reason: " + ex.getMessage());
|
||||
log("DOWN", "Failed to download " + track + "! Reason: " + ex.getMessage());
|
||||
}
|
||||
response += "\n";
|
||||
}
|
||||
|
@ -453,7 +453,7 @@ public final class Chords extends ListenerAdapter
|
|||
}
|
||||
}
|
||||
|
||||
private class NowPlayingConsumer implements Consumer<Song>
|
||||
private class NowPlayingConsumer implements Consumer<Track>
|
||||
{
|
||||
|
||||
public NowPlayingConsumer()
|
||||
|
@ -461,10 +461,10 @@ public final class Chords extends ListenerAdapter
|
|||
}
|
||||
|
||||
@Override
|
||||
public void accept(Song song)
|
||||
public void accept(Track track)
|
||||
{
|
||||
if (song != null)
|
||||
jda.getPresence().setActivity(Activity.of(Activity.ActivityType.LISTENING, song.toString()));
|
||||
if (track != null)
|
||||
jda.getPresence().setActivity(Activity.of(Activity.ActivityType.LISTENING, track.toString()));
|
||||
else
|
||||
jda.getPresence().setActivity(null);
|
||||
}
|
||||
|
|
|
@ -49,8 +49,8 @@ public class Downloader implements Consumer<DownloadTask>
|
|||
private final LinkedBlockingDeque<Runnable> workQueue = new LinkedBlockingDeque<>();
|
||||
private final ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 4, 30, TimeUnit.SECONDS, workQueue);
|
||||
private final ScheduledExecutorService scheduler = new ScheduledThreadPoolExecutor(1);
|
||||
// private Consumer<Song> next;
|
||||
private BiConsumer<SongRequest, Exception> messageHandler;
|
||||
// private Consumer<Track> next;
|
||||
private BiConsumer<TrackRequest, Exception> messageHandler;
|
||||
|
||||
private File downloadDir = null;
|
||||
|
||||
|
@ -64,11 +64,11 @@ public class Downloader implements Consumer<DownloadTask>
|
|||
@Override
|
||||
public void accept(DownloadTask task)
|
||||
{
|
||||
// if all songs of the request are already downloaded, just skip
|
||||
if (!task.request.getSongs().isEmpty() && task.request.getSongs().stream().allMatch((t) -> t.isDownloaded()))
|
||||
// if all tracks of the request are already downloaded, just skip
|
||||
if (!task.request.getTracks().isEmpty() && task.request.getTracks().stream().allMatch((t) -> t.isDownloaded()))
|
||||
{
|
||||
for (Song song : task.request.getSongs())
|
||||
task.getDestination().accept(song);
|
||||
for (Track track : task.request.getTracks())
|
||||
task.getDestination().accept(track);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -79,7 +79,7 @@ public class Downloader implements Consumer<DownloadTask>
|
|||
{
|
||||
try
|
||||
{
|
||||
// getFormats(song);
|
||||
// getFormats(track);
|
||||
download(task);
|
||||
} catch (Exception ex)
|
||||
{
|
||||
|
@ -129,13 +129,13 @@ public class Downloader implements Consumer<DownloadTask>
|
|||
return formats;
|
||||
}
|
||||
|
||||
private void getFormats(Song song)
|
||||
private void getFormats(Track track)
|
||||
{
|
||||
if (!song.getFormats().isEmpty())
|
||||
if (!track.getFormats().isEmpty())
|
||||
return;
|
||||
try
|
||||
{
|
||||
String cmd = Chords.getSettings().getYtdlCommand() + " --skip-download -F " + song.getUrl().toString();
|
||||
String cmd = Chords.getSettings().getYtdlCommand() + " --skip-download -F " + track.getUrl().toString();
|
||||
Process exec = runCommand(cmd, FORMAT_TIMEOUT);
|
||||
InputStream input = exec.getInputStream();
|
||||
String output = new String(input.readAllBytes(), Charset.defaultCharset());
|
||||
|
@ -195,7 +195,7 @@ public class Downloader implements Consumer<DownloadTask>
|
|||
format.setSampleRate(Util.parseSampleRate(split[bitrateCol]));
|
||||
formats.add(format);
|
||||
}
|
||||
song.setFormats(formats);
|
||||
track.setFormats(formats);
|
||||
|
||||
} catch (Exception ex)
|
||||
{
|
||||
|
@ -204,31 +204,31 @@ public class Downloader implements Consumer<DownloadTask>
|
|||
}
|
||||
}
|
||||
|
||||
private List<Song> getInfo(SongRequest request)
|
||||
private List<Track> getInfo(TrackRequest request)
|
||||
{
|
||||
List<Song> ret = new ArrayList<>();
|
||||
List<Track> ret = new ArrayList<>();
|
||||
try
|
||||
{
|
||||
String cmd = Chords.getSettings().getYtdlCommand() + " --skip-download --print-json " + request.getUrl().toString();
|
||||
Process exec = runCommand(cmd, INFO_TIMEOUT);
|
||||
InputStream input = exec.getInputStream();
|
||||
|
||||
// read each line as JSON, turn each into a song object
|
||||
// read each line as JSON, turn each into a track object
|
||||
Scanner sc = new Scanner(input);
|
||||
while (sc.hasNextLine())
|
||||
{
|
||||
Song song = new Song(request.getUrl());
|
||||
song.setNumber(trackNumber);
|
||||
Track track = new Track(request.getUrl());
|
||||
track.setNumber(trackNumber);
|
||||
trackNumber++;
|
||||
request.addSong(song);
|
||||
request.addTrack(track);
|
||||
|
||||
String line = sc.nextLine();
|
||||
JsonReader reader = Json.createReader(new StringReader(line));
|
||||
JsonObject object = reader.readObject();
|
||||
if (song.getTitle() == null)
|
||||
song.setTitle(object.getString("title", null));
|
||||
if (song.getArtist() == null)
|
||||
song.setArtist(object.getString("uploader", null));
|
||||
if (track.getTitle() == null)
|
||||
track.setTitle(object.getString("title", null));
|
||||
if (track.getArtist() == null)
|
||||
track.setArtist(object.getString("uploader", null));
|
||||
|
||||
JsonArray formatsJSON = object.getJsonArray("formats");
|
||||
if (formatsJSON != null)
|
||||
|
@ -240,10 +240,10 @@ public class Downloader implements Consumer<DownloadTask>
|
|||
if (format != null)
|
||||
formats.add(format);
|
||||
}
|
||||
song.setFormats(formats);
|
||||
track.setFormats(formats);
|
||||
}
|
||||
|
||||
ret.add(song);
|
||||
ret.add(track);
|
||||
}
|
||||
} catch (Exception ex)
|
||||
{
|
||||
|
@ -259,25 +259,25 @@ public class Downloader implements Consumer<DownloadTask>
|
|||
return downloadDir;
|
||||
}
|
||||
|
||||
private Song getSongFromRequest(SongRequest request, int idx)
|
||||
private Track getTrackFromRequest(TrackRequest request, int idx)
|
||||
{
|
||||
// if there's less songs in the request than expected, fill the array
|
||||
while (idx >= request.getSongs().size())
|
||||
// if there's less tracks in the request than expected, fill the array
|
||||
while (idx >= request.getTracks().size())
|
||||
{
|
||||
Song song = new Song(request.getUrl());
|
||||
song.setNumber(trackNumber);
|
||||
Track track = new Track(request.getUrl());
|
||||
track.setNumber(trackNumber);
|
||||
trackNumber++;
|
||||
request.addSong(song);
|
||||
request.addTrack(track);
|
||||
}
|
||||
return request.getSongs().get(idx);
|
||||
return request.getTracks().get(idx);
|
||||
}
|
||||
|
||||
private void download(DownloadTask task)
|
||||
{
|
||||
Set<Format> uniqueFormats = new HashSet<>();
|
||||
for (Song song : task.request.getSongs())
|
||||
for (Track track : task.request.getTracks())
|
||||
{
|
||||
uniqueFormats.addAll(song.getFormats());
|
||||
uniqueFormats.addAll(track.getFormats());
|
||||
}
|
||||
|
||||
List<Format> sortedFormats = sortFormats(uniqueFormats);
|
||||
|
@ -313,7 +313,7 @@ public class Downloader implements Consumer<DownloadTask>
|
|||
if (itemMatcher.find())
|
||||
{
|
||||
int idx = Integer.parseInt(itemMatcher.group(1)) - 1;
|
||||
int total = Integer.parseInt(cmd);
|
||||
// int total = Integer.parseInt(itemMatcher.group(2));
|
||||
|
||||
downloadIdx = idx;
|
||||
}
|
||||
|
@ -321,20 +321,24 @@ public class Downloader implements Consumer<DownloadTask>
|
|||
Matcher progMatcher = PROGRESS_PATTERN.matcher(line);
|
||||
if (progMatcher.find())
|
||||
{
|
||||
getSongFromRequest(task.request, downloadIdx).setProgress(Double.parseDouble(progMatcher.group(1)));
|
||||
getTrackFromRequest(task.request, downloadIdx).setProgress(Double.parseDouble(progMatcher.group(1)));
|
||||
messageHandler.accept(task.request, null);
|
||||
}
|
||||
|
||||
Matcher destMatcher = DESTINATION_PATTERN.matcher(line);
|
||||
if (destMatcher.find())
|
||||
{
|
||||
Song song = getSongFromRequest(task.request, downloadIdx);
|
||||
Track track = getTrackFromRequest(task.request, downloadIdx);
|
||||
|
||||
song.setLocation(new File(destMatcher.group(1)));
|
||||
track.setLocation(new File(destMatcher.group(1)));
|
||||
|
||||
// this is currently our criteria for completion; submit the song and move on
|
||||
// this is currently our criteria for completion; submit the track and move on
|
||||
if (task.getDestination() != null)
|
||||
task.getDestination().accept(song);
|
||||
task.getDestination().accept(track);
|
||||
|
||||
track.setProgress(100.0);
|
||||
|
||||
messageHandler.accept(task.request, null);
|
||||
|
||||
downloadIdx++;
|
||||
}
|
||||
|
@ -383,12 +387,12 @@ public class Downloader implements Consumer<DownloadTask>
|
|||
return exec;
|
||||
}
|
||||
|
||||
public BiConsumer<SongRequest, Exception> getMessageHandler()
|
||||
public BiConsumer<TrackRequest, Exception> getMessageHandler()
|
||||
{
|
||||
return messageHandler;
|
||||
}
|
||||
|
||||
public void setMessageHandler(BiConsumer<SongRequest, Exception> messageHandler)
|
||||
public void setMessageHandler(BiConsumer<TrackRequest, Exception> messageHandler)
|
||||
{
|
||||
this.messageHandler = messageHandler;
|
||||
}
|
||||
|
@ -401,21 +405,21 @@ public class Downloader implements Consumer<DownloadTask>
|
|||
public static class DownloadTask
|
||||
{
|
||||
|
||||
private final SongRequest request;
|
||||
private final Consumer<Song> destination;
|
||||
private final TrackRequest request;
|
||||
private final Consumer<Track> destination;
|
||||
|
||||
public DownloadTask(SongRequest request, Consumer<Song> destination)
|
||||
public DownloadTask(TrackRequest request, Consumer<Track> destination)
|
||||
{
|
||||
this.request = request;
|
||||
this.destination = destination;
|
||||
}
|
||||
|
||||
public SongRequest getSong()
|
||||
public TrackRequest getTrack()
|
||||
{
|
||||
return request;
|
||||
}
|
||||
|
||||
public Consumer<Song> getDestination()
|
||||
public Consumer<Track> getDestination()
|
||||
{
|
||||
return destination;
|
||||
}
|
||||
|
|
|
@ -23,21 +23,21 @@ public class MusicHandler implements AudioSendHandler, Closeable
|
|||
{
|
||||
|
||||
private QueueManager queueManager;
|
||||
// private final LinkedList<Song> songQueue = new LinkedList<>();
|
||||
// private final LinkedList<Track> trackQueue = new LinkedList<>();
|
||||
// private final Queue<byte[]> queue = new ConcurrentLinkedQueue<>();
|
||||
// private final CircularByteBuffer audioBuffer = new CircularByteBuffer(3840 * 1024);
|
||||
private boolean shouldPlay = true;
|
||||
private int byteCount;
|
||||
|
||||
private boolean arrayErr = false;
|
||||
private Consumer<Song> nowPlayingConsumer;
|
||||
private Consumer<Track> nowPlayingConsumer;
|
||||
|
||||
public void setNowPlayingConsumer(Consumer<Song> nowPlayingConsumer)
|
||||
public void setNowPlayingConsumer(Consumer<Track> nowPlayingConsumer)
|
||||
{
|
||||
this.nowPlayingConsumer = nowPlayingConsumer;
|
||||
}
|
||||
|
||||
private Song currentSong;
|
||||
private Track currentTrack;
|
||||
// private TrackPlayer player;
|
||||
private final List<TrackPlayer> playingTracks = new ArrayList<>();
|
||||
|
||||
|
@ -66,21 +66,21 @@ public class MusicHandler implements AudioSendHandler, Closeable
|
|||
|
||||
public void playNext()
|
||||
{
|
||||
nextSong(true);
|
||||
nextTrack(true);
|
||||
}
|
||||
|
||||
public void playOver(Song song)
|
||||
public void playOver(Track track)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
private boolean nextSong()
|
||||
private boolean nextTrack()
|
||||
{
|
||||
return nextSong(false);
|
||||
return nextTrack(false);
|
||||
}
|
||||
|
||||
public boolean nextSong(boolean immediate)
|
||||
public boolean nextTrack(boolean immediate)
|
||||
{
|
||||
if (immediate)
|
||||
{
|
||||
|
@ -90,25 +90,25 @@ public class MusicHandler implements AudioSendHandler, Closeable
|
|||
|
||||
try
|
||||
{
|
||||
if (currentSong != null)
|
||||
if (currentTrack != null)
|
||||
{
|
||||
if (!currentSong.isKept())
|
||||
currentSong.delete();
|
||||
currentSong = null;
|
||||
if (!currentTrack.isKept())
|
||||
currentTrack.delete();
|
||||
currentTrack = null;
|
||||
}
|
||||
currentSong = queueManager.nextSongNeeded();
|
||||
currentTrack = queueManager.nextTrackNeeded();
|
||||
if (nowPlayingConsumer != null)
|
||||
nowPlayingConsumer.accept(currentSong);
|
||||
if (currentSong == null)
|
||||
nowPlayingConsumer.accept(currentTrack);
|
||||
if (currentTrack == null)
|
||||
{
|
||||
System.out.println("End of queue.");
|
||||
debugOut.flush();
|
||||
return false;
|
||||
}
|
||||
System.out.println("Playing song " + currentSong.getLocation().getAbsolutePath());
|
||||
System.out.println("Playing track " + currentTrack.getLocation().getAbsolutePath());
|
||||
arrayErr = false;
|
||||
byteCount = 3840;
|
||||
TrackPlayer player = new TrackPlayer(currentSong);
|
||||
TrackPlayer player = new TrackPlayer(currentTrack);
|
||||
playingTracks.add(player);
|
||||
// System.out.println("Queue filled to " + audioBuffer.getCurrentNumberOfBytes());
|
||||
return true;
|
||||
|
@ -134,7 +134,7 @@ public class MusicHandler implements AudioSendHandler, Closeable
|
|||
public void setShouldPlay(boolean shouldPlay)
|
||||
{
|
||||
if (!this.shouldPlay && shouldPlay)
|
||||
nextSong();
|
||||
nextTrack();
|
||||
this.shouldPlay = shouldPlay;
|
||||
}
|
||||
|
||||
|
@ -181,7 +181,7 @@ public class MusicHandler implements AudioSendHandler, Closeable
|
|||
ret.put(mixBuffers(mixes));
|
||||
if (outOfInput)
|
||||
{
|
||||
boolean foundNext = nextSong();
|
||||
boolean foundNext = nextTrack();
|
||||
if (!foundNext)
|
||||
break;
|
||||
}
|
||||
|
@ -194,9 +194,9 @@ public class MusicHandler implements AudioSendHandler, Closeable
|
|||
|
||||
}
|
||||
|
||||
public Song getCurrentSong()
|
||||
public Track getCurrentTrack()
|
||||
{
|
||||
return currentSong;
|
||||
return currentTrack;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -30,14 +30,14 @@ import java.util.logging.Logger;
|
|||
*
|
||||
* @author jimj316
|
||||
*/
|
||||
public class Playlist implements Consumer<Song>
|
||||
public class Playlist implements Consumer<Track>
|
||||
{
|
||||
|
||||
private static final int SHUFFLE_DONT_REPEAT_LAST = 3;
|
||||
|
||||
private final String name;
|
||||
private final List<Song> songs = new ArrayList<>();
|
||||
private final LinkedList<Song> playHistory = new LinkedList<>();
|
||||
private final List<Track> tracks = new ArrayList<>();
|
||||
private final LinkedList<Track> playHistory = new LinkedList<>();
|
||||
|
||||
public Playlist(String name)
|
||||
{
|
||||
|
@ -46,25 +46,25 @@ public class Playlist implements Consumer<Song>
|
|||
|
||||
public YamlMapping toYaml()
|
||||
{
|
||||
YamlSequenceBuilder songList = Yaml.createYamlSequenceBuilder();
|
||||
for (Song song : songs)
|
||||
songList = songList.add(song.toYaml());
|
||||
YamlSequenceBuilder trackList = Yaml.createYamlSequenceBuilder();
|
||||
for (Track track : tracks)
|
||||
trackList = trackList.add(track.toYaml());
|
||||
|
||||
return Yaml.createYamlMappingBuilder()
|
||||
.add("name", name)
|
||||
.add("songs", songList.build())
|
||||
.add("tracks", trackList.build())
|
||||
.build();
|
||||
}
|
||||
|
||||
public static Playlist fromYaml(YamlMapping yaml)
|
||||
{
|
||||
Playlist ret = new Playlist(yaml.string("name"));
|
||||
YamlSequence songList = yaml.value("songs").asSequence();
|
||||
for (int i = 0; i < songList.size(); i++)
|
||||
YamlSequence trackList = yaml.value("tracks").asSequence();
|
||||
for (int i = 0; i < trackList.size(); i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
ret.addSong(Song.fromYaml(songList.yamlMapping(i)));
|
||||
ret.addTrack(Track.fromYaml(trackList.yamlMapping(i)));
|
||||
} catch (MalformedURLException ex)
|
||||
{
|
||||
Logger.getLogger(Playlist.class.getName()).log(Level.SEVERE, null, ex);
|
||||
|
@ -73,10 +73,10 @@ public class Playlist implements Consumer<Song>
|
|||
return ret;
|
||||
}
|
||||
|
||||
public void addSong(Song song)
|
||||
public void addTrack(Track track)
|
||||
{
|
||||
song.setKept(true);
|
||||
songs.add(song);
|
||||
track.setKept(true);
|
||||
tracks.add(track);
|
||||
}
|
||||
|
||||
public String getName()
|
||||
|
@ -84,17 +84,17 @@ public class Playlist implements Consumer<Song>
|
|||
return name;
|
||||
}
|
||||
|
||||
public List<Song> getSongs()
|
||||
public List<Track> getTracks()
|
||||
{
|
||||
return songs;
|
||||
return tracks;
|
||||
}
|
||||
|
||||
public Song getNextSong()
|
||||
public Track getNextTrack()
|
||||
{
|
||||
Song ret;
|
||||
Track ret;
|
||||
|
||||
// copy the song list
|
||||
List<Song> toShuffle = new LinkedList<>(songs);
|
||||
// copy the track list
|
||||
List<Track> toShuffle = new LinkedList<>(tracks);
|
||||
|
||||
// remove play history from candidates, latest first, unless we'd have less than 2 options
|
||||
for (int i = playHistory.size() - 1; i >= 0; i--)
|
||||
|
@ -114,9 +114,9 @@ public class Playlist implements Consumer<Song>
|
|||
}
|
||||
|
||||
@Override
|
||||
public void accept(Song t)
|
||||
public void accept(Track t)
|
||||
{
|
||||
addSong(t);
|
||||
addTrack(t);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,11 +26,11 @@ import java.util.function.Consumer;
|
|||
*
|
||||
* @author jimj316
|
||||
*/
|
||||
public class QueueManager implements Consumer<Song>
|
||||
public class QueueManager implements Consumer<Track>
|
||||
{
|
||||
|
||||
private Song restartingSong = null;
|
||||
private final PriorityQueue<Song> jukeboxQueue = new PriorityQueue<>();
|
||||
private Track restartingTrack = null;
|
||||
private final PriorityQueue<Track> jukeboxQueue = new PriorityQueue<>();
|
||||
private Playlist playlist;
|
||||
private MusicHandler handler;
|
||||
|
||||
|
@ -40,30 +40,30 @@ public class QueueManager implements Consumer<Song>
|
|||
}
|
||||
|
||||
@Override
|
||||
public void accept(Song t)
|
||||
public void accept(Track t)
|
||||
{
|
||||
jukeboxQueue.add(t);
|
||||
|
||||
if (!handler.isPlaying() || handler.getCurrentSong() == null)
|
||||
if (!handler.isPlaying() || handler.getCurrentTrack() == null)
|
||||
handler.playNext();
|
||||
|
||||
if (handler.isPlaying() != (handler.getCurrentSong() == null))
|
||||
if (handler.isPlaying() != (handler.getCurrentTrack() == null))
|
||||
System.err.println("WARNING: handler isPlaying violates contract! Something dumb going on!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the music handler when the current song has ended, or if
|
||||
* Called by the music handler when the current track has ended, or if
|
||||
* playNext is called with nothing playing.
|
||||
*
|
||||
* @return the next track to play, or null to stop playing.
|
||||
*/
|
||||
public Song nextSongNeeded()
|
||||
public Track nextTrackNeeded()
|
||||
{
|
||||
// if we're restarting the current song: store, clear, and return it
|
||||
if (restartingSong != null)
|
||||
// if we're restarting the current track: store, clear, and return it
|
||||
if (restartingTrack != null)
|
||||
{
|
||||
Song ret = restartingSong;
|
||||
restartingSong = null;
|
||||
Track ret = restartingTrack;
|
||||
restartingTrack = null;
|
||||
return ret;
|
||||
}
|
||||
// if there's anything in the queue, play that first
|
||||
|
@ -74,7 +74,7 @@ public class QueueManager implements Consumer<Song>
|
|||
// otherwise if there's a playlist, shuffle from that
|
||||
else if (playlist != null)
|
||||
{
|
||||
return playlist.getNextSong();
|
||||
return playlist.getNextTrack();
|
||||
}
|
||||
// otherwise stop playing
|
||||
else
|
||||
|
@ -86,27 +86,27 @@ public class QueueManager implements Consumer<Song>
|
|||
return handler;
|
||||
}
|
||||
|
||||
public void addSong(Song song)
|
||||
public void addTrack(Track track)
|
||||
{
|
||||
System.out.println("Song added to queue: " + song.getLocation().getAbsolutePath());
|
||||
jukeboxQueue.add(song);
|
||||
System.out.println("Track added to queue: " + track.getLocation().getAbsolutePath());
|
||||
jukeboxQueue.add(track);
|
||||
|
||||
}
|
||||
|
||||
public boolean removeSong(int i)
|
||||
public boolean removeTrack(int i)
|
||||
{
|
||||
try
|
||||
{
|
||||
return jukeboxQueue.remove((Song) jukeboxQueue.toArray()[i]);
|
||||
return jukeboxQueue.remove((Track) jukeboxQueue.toArray()[i]);
|
||||
} catch (ArrayIndexOutOfBoundsException ex)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean removeSong(Song song)
|
||||
public boolean removeTrack(Track track)
|
||||
{
|
||||
return jukeboxQueue.remove(song);
|
||||
return jukeboxQueue.remove(track);
|
||||
}
|
||||
|
||||
public void setHandler(MusicHandler handler)
|
||||
|
@ -115,7 +115,7 @@ public class QueueManager implements Consumer<Song>
|
|||
handler.setQueueManager(this);
|
||||
}
|
||||
|
||||
public Queue<Song> getJukeboxQueue()
|
||||
public Queue<Track> getJukeboxQueue()
|
||||
{
|
||||
return jukeboxQueue;
|
||||
}
|
||||
|
@ -130,10 +130,10 @@ public class QueueManager implements Consumer<Song>
|
|||
this.playlist = playlist;
|
||||
}
|
||||
|
||||
public boolean restartSong()
|
||||
public boolean restartTrack()
|
||||
{
|
||||
restartingSong = handler.getCurrentSong();
|
||||
if (restartingSong != null)
|
||||
restartingTrack = handler.getCurrentTrack();
|
||||
if (restartingTrack != null)
|
||||
{
|
||||
handler.playNext();
|
||||
return true;
|
||||
|
|
|
@ -19,7 +19,7 @@ import java.util.List;
|
|||
*
|
||||
* @author jimj316
|
||||
*/
|
||||
public class Song implements Comparable<Song>
|
||||
public class Track implements Comparable<Track>
|
||||
{
|
||||
private String title;
|
||||
private String artist;
|
||||
|
@ -33,7 +33,7 @@ public class Song implements Comparable<Song>
|
|||
private double progress = -1;
|
||||
private double eta = -1;
|
||||
|
||||
public Song(URL url)
|
||||
public Track(URL url)
|
||||
{
|
||||
this.url = url;
|
||||
}
|
||||
|
@ -57,24 +57,24 @@ public class Song implements Comparable<Song>
|
|||
.build();
|
||||
}
|
||||
|
||||
public static Song fromYaml(YamlMapping map) throws MalformedURLException
|
||||
public static Track fromYaml(YamlMapping map) throws MalformedURLException
|
||||
{
|
||||
Song song = new Song(new URL(map.string("url")));
|
||||
song.setArtist(map.string("artist"));
|
||||
song.setTitle(map.string("title"));
|
||||
song.setLocation(new File(map.string("location")));
|
||||
song.setNumber(map.integer("num"));
|
||||
song.setKept(Boolean.parseBoolean(map.string("kept")));
|
||||
// song.setRequestedBy(map.string("requestedBy"));
|
||||
// song.setRequestedIn(map.string("requestedIn"));
|
||||
Track track = new Track(new URL(map.string("url")));
|
||||
track.setArtist(map.string("artist"));
|
||||
track.setTitle(map.string("title"));
|
||||
track.setLocation(new File(map.string("location")));
|
||||
track.setNumber(map.integer("num"));
|
||||
track.setKept(Boolean.parseBoolean(map.string("kept")));
|
||||
// track.setRequestedBy(map.string("requestedBy"));
|
||||
// track.setRequestedIn(map.string("requestedIn"));
|
||||
|
||||
List<Format> formats = new ArrayList<>();
|
||||
YamlSequence formatSeq = map.yamlSequence("formats");
|
||||
for (int i = 0; i < formats.size(); i++)
|
||||
formats.add(Format.fromYaml(formatSeq.yamlMapping(i)));
|
||||
song.setFormats(formats);
|
||||
track.setFormats(formats);
|
||||
|
||||
return song;
|
||||
return track;
|
||||
}
|
||||
|
||||
public boolean isDownloaded()
|
||||
|
@ -199,7 +199,7 @@ public class Song implements Comparable<Song>
|
|||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Song o)
|
||||
public int compareTo(Track o)
|
||||
{
|
||||
return Integer.compare(number, o.number);
|
||||
}
|
|
@ -31,9 +31,9 @@ public class TrackPlayer implements Closeable
|
|||
|
||||
private boolean arrayErr = false; // supresses ArrayIndexOutOfBoundsException after the first time, to prevent spam
|
||||
|
||||
public TrackPlayer(Song song) throws UnsupportedAudioFileException, IOException
|
||||
public TrackPlayer(Track track) throws UnsupportedAudioFileException, IOException
|
||||
{
|
||||
AudioInputStream in = AudioSystem.getAudioInputStream(song.getLocation());
|
||||
AudioInputStream in = AudioSystem.getAudioInputStream(track.getLocation());
|
||||
AudioFormat decodedFormat = AudioSendHandler.INPUT_FORMAT;
|
||||
input = AudioSystem.getAudioInputStream(decodedFormat, in);
|
||||
fillBuffer(false);
|
||||
|
|
|
@ -26,7 +26,7 @@ import moe.nekojimi.musicsearcher.Result;
|
|||
*
|
||||
* @author jimj316
|
||||
*/
|
||||
public class SongRequest
|
||||
public class TrackRequest
|
||||
{
|
||||
private Invocation invocation;
|
||||
|
||||
|
@ -37,7 +37,7 @@ public class SongRequest
|
|||
|
||||
private Result result;
|
||||
|
||||
private final List<Song> songs = new ArrayList<>();
|
||||
private final List<Track> tracks = new ArrayList<>();
|
||||
|
||||
private String requestedBy;
|
||||
private String requestedIn;
|
||||
|
@ -115,19 +115,19 @@ public class SongRequest
|
|||
this.url = url;
|
||||
}
|
||||
|
||||
public List<Song> getSongs()
|
||||
public List<Track> getTracks()
|
||||
{
|
||||
return songs;
|
||||
return tracks;
|
||||
}
|
||||
|
||||
public void addSong(Song song)
|
||||
public void addTrack(Track track)
|
||||
{
|
||||
songs.add(song);
|
||||
tracks.add(track);
|
||||
}
|
||||
|
||||
public void clearSongs()
|
||||
public void clearTracks()
|
||||
{
|
||||
songs.clear();
|
||||
tracks.clear();
|
||||
}
|
||||
|
||||
public String getRequestedBy()
|
||||
|
@ -140,4 +140,23 @@ public class SongRequest
|
|||
return requestedIn;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
String trackName;
|
||||
if (tracks.isEmpty())
|
||||
trackName = "Request";
|
||||
else
|
||||
{
|
||||
trackName = tracks.get(1).toString();
|
||||
if (tracks.size() > 1)
|
||||
trackName += " & " + (tracks.size() - 1) + " more tracks";
|
||||
}
|
||||
|
||||
String requestName = "";
|
||||
if (!requestedBy.isEmpty())
|
||||
requestName = "for " + requestedBy;
|
||||
|
||||
return (trackName + " " + requestName).trim();
|
||||
}
|
||||
|
||||
}
|
|
@ -34,10 +34,10 @@ public class HelpCommand extends Command
|
|||
+ "!leave - Leaves the current voice channel\n"
|
||||
+ "!play <URL> - Downloads the track at that URL and adds it to the queue.\n"
|
||||
+ "!play <Search> - Searches for a track and displays a selection menu.\n"
|
||||
+ "!queue - Show the songs currently playing and the current queue.\n"
|
||||
+ "!remove <Index> - Remove the song at position <Index> from the queue.\n"
|
||||
+ "!skip - Skip the current song and play the next one.\n"
|
||||
+ "!restart - Try playing the current song again in case it goes wrong.\n";
|
||||
+ "!queue - Show the tracks currently playing and the current queue.\n"
|
||||
+ "!remove <Index> - Remove the track at position <Index> from the queue.\n"
|
||||
+ "!skip - Skip the current track and play the next one.\n"
|
||||
+ "!restart - Try playing the current track again in case it goes wrong.\n";
|
||||
// for (String key: commands.keySet())
|
||||
// {
|
||||
// help += "!" + key + ":"
|
||||
|
|
|
@ -22,7 +22,7 @@ import java.util.List;
|
|||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import moe.nekojimi.chords.Chords;
|
||||
import moe.nekojimi.chords.SongRequest;
|
||||
import moe.nekojimi.chords.TrackRequest;
|
||||
import moe.nekojimi.musicsearcher.Query;
|
||||
import moe.nekojimi.musicsearcher.Result;
|
||||
|
||||
|
@ -45,7 +45,7 @@ public class PlayCommand extends Command
|
|||
@Override
|
||||
public void call(Invocation invocation)
|
||||
{
|
||||
SongRequest request = new SongRequest();
|
||||
TrackRequest request = new TrackRequest();
|
||||
request.setInvocation(invocation);
|
||||
try
|
||||
{
|
||||
|
@ -67,11 +67,11 @@ public class PlayCommand extends Command
|
|||
Result result = request.getSearchResults().get(index - 1);
|
||||
request.setResult(result);
|
||||
bot.queueDownload(request);
|
||||
// event.getChannel().sendMessage("Song removed.").queue();
|
||||
// event.getChannel().sendMessage("Track removed.").queue();
|
||||
} else if (size > 1)
|
||||
invocation.respond("That's not a number between 1 and " + size + "!");
|
||||
else if (size == 1)
|
||||
invocation.respond("There's only one song and that's not one of them!");
|
||||
invocation.respond("There's only one track and that's not one of them!");
|
||||
|
||||
return;
|
||||
} catch (NumberFormatException nfx)
|
||||
|
|
|
@ -20,7 +20,7 @@ import java.util.List;
|
|||
import java.util.Queue;
|
||||
import moe.nekojimi.chords.Downloader;
|
||||
import moe.nekojimi.chords.Chords;
|
||||
import moe.nekojimi.chords.Song;
|
||||
import moe.nekojimi.chords.Track;
|
||||
|
||||
public class QueueCommand extends Command
|
||||
{
|
||||
|
@ -36,19 +36,19 @@ public class QueueCommand extends Command
|
|||
String message = ">>> ";
|
||||
int i = 1;
|
||||
|
||||
final Song currentSong = bot.getMusicHandler().getCurrentSong();
|
||||
if (currentSong != null)
|
||||
message += ":notes: **Now playing: " + currentSong + "**\n";
|
||||
final Track currentTrack = bot.getMusicHandler().getCurrentTrack();
|
||||
if (currentTrack != null)
|
||||
message += ":notes: **Now playing: " + currentTrack + "**\n";
|
||||
else
|
||||
message += ":mute: **Not playing anything right now.**\n";
|
||||
|
||||
final Queue<Song> songQueue = bot.getQueueManager().getJukeboxQueue();
|
||||
if (!songQueue.isEmpty())
|
||||
final Queue<Track> trackQueue = bot.getQueueManager().getJukeboxQueue();
|
||||
if (!trackQueue.isEmpty())
|
||||
{
|
||||
message += "__Ready to play:__\n";
|
||||
for (Song song : songQueue)
|
||||
for (Track track : trackQueue)
|
||||
{
|
||||
message += ":bread: **" + (i) + ":** " + song + "\n";
|
||||
message += ":bread: **" + (i) + ":** " + track + "\n";
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
@ -59,12 +59,12 @@ public class QueueCommand extends Command
|
|||
message += "__Downloading:__\n";
|
||||
for (Downloader.DownloadTask task : downloadQueue)
|
||||
{
|
||||
message += ":inbox_tray: **" + (i) + ":** " + task.getSong() + "\n";
|
||||
message += ":inbox_tray: **" + (i) + ":** " + task.getTrack() + "\n";
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
if (downloadQueue.isEmpty() && songQueue.isEmpty())
|
||||
if (downloadQueue.isEmpty() && trackQueue.isEmpty())
|
||||
message += ":mailbox_with_no_mail: The track queue is empty.";
|
||||
// :inbox_tray:
|
||||
invocation.respond(message);
|
||||
|
|
|
@ -32,14 +32,14 @@ public class RemoveCommand extends Command
|
|||
try
|
||||
{
|
||||
int i = Integer.parseInt(invocation.getArgs().get(0));
|
||||
boolean removed = bot.getQueueManager().removeSong(i - 1);
|
||||
boolean removed = bot.getQueueManager().removeTrack(i - 1);
|
||||
final int size = bot.getQueueManager().getJukeboxQueue().size();
|
||||
if (removed)
|
||||
invocation.respond("Song removed.");
|
||||
invocation.respond("Track removed.");
|
||||
else if (size > 1)
|
||||
invocation.respond("That's not a number between 1 and " + size + "!");
|
||||
else if (size == 1)
|
||||
invocation.respond("There's only one song to remove and that's not one of them!");
|
||||
invocation.respond("There's only one track to remove and that's not one of them!");
|
||||
|
||||
} catch (NumberFormatException ex)
|
||||
{
|
||||
|
|
|
@ -30,9 +30,9 @@ public class RestartCommand extends Command
|
|||
public void call(Invocation invocation)
|
||||
{
|
||||
// TODO: this needs to clear the current data queue
|
||||
boolean ok = bot.getQueueManager().restartSong();
|
||||
boolean ok = bot.getQueueManager().restartTrack();
|
||||
if (ok)
|
||||
invocation.respond("Restarted current song!");
|
||||
invocation.respond("Restarted current track!");
|
||||
else
|
||||
invocation.respond("Cannot restart!");
|
||||
}
|
||||
|
|
|
@ -29,11 +29,11 @@ public class SkipCommand extends Command
|
|||
@Override
|
||||
public void call(Invocation invocation)
|
||||
{
|
||||
boolean ok = bot.getMusicHandler().nextSong(true);
|
||||
boolean ok = bot.getMusicHandler().nextTrack(true);
|
||||
if (ok)
|
||||
invocation.respond("Skipped to next song!");
|
||||
invocation.respond("Skipped to next track!");
|
||||
else
|
||||
invocation.respond("There's no more songs!");
|
||||
invocation.respond("There's no more tracks!");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue