Fix various problems.
This commit is contained in:
parent
367f2b93de
commit
2f7bb13dc6
|
@ -24,9 +24,20 @@ target/
|
|||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
|
||||
# Downloaded audio
|
||||
# Downloaded audio/info
|
||||
*.wav
|
||||
*.wav.tmp
|
||||
*.info.json
|
||||
|
||||
# Syncthing being weird
|
||||
.syncthing.*
|
||||
|
||||
# Netbeans
|
||||
**/nbproject/private/
|
||||
**/nbproject/Makefile-*.mk
|
||||
**/nbproject/Package-*.bash
|
||||
build/
|
||||
nbbuild/
|
||||
dist/
|
||||
nbdist/
|
||||
.nb-gradle/
|
||||
|
|
|
@ -5,26 +5,21 @@
|
|||
*/
|
||||
package moe.nekojimi.chords;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.security.auth.login.LoginException;
|
||||
import javax.sound.sampled.*;
|
||||
import net.dv8tion.jda.api.JDA;
|
||||
import net.dv8tion.jda.api.JDABuilder;
|
||||
import net.dv8tion.jda.api.audio.AudioSendHandler;
|
||||
import net.dv8tion.jda.api.entities.*;
|
||||
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
|
||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||
|
@ -81,16 +76,32 @@ public class Main extends ListenerAdapter
|
|||
if (author.isBot())
|
||||
return;
|
||||
|
||||
if (content.startsWith("!join "))
|
||||
try
|
||||
{
|
||||
String arg = content.substring("!join ".length());
|
||||
onJoinCommand(event, guild, arg);
|
||||
} else if (content.equals("!join"))
|
||||
onJoinCommand(event);
|
||||
else if (content.startsWith("!play "))
|
||||
|
||||
String arg = "";
|
||||
if (content.contains(" "))
|
||||
arg = content.split(" ", 2)[1];
|
||||
|
||||
if (content.startsWith("!join "))
|
||||
onJoinCommand(event, guild, arg);
|
||||
else if (content.equals("!join"))
|
||||
onJoinCommand(event);
|
||||
else if (content.startsWith("!play "))
|
||||
onPlayCommand(event, guild, arg);
|
||||
else if (content.startsWith("!queue"))
|
||||
onQueueCommand(event, guild);
|
||||
else if (content.startsWith("!remove "))
|
||||
onRemoveCommand(event, guild, arg);
|
||||
else if (content.startsWith("!restart"))
|
||||
onRestartCommand(event);
|
||||
else if (content.startsWith("!skip"))
|
||||
onSkipCommand(event);
|
||||
else if (content.startsWith("!"))
|
||||
onHelpCommand(event);
|
||||
} catch (Exception ex)
|
||||
{
|
||||
String arg = content.substring("!join ".length());
|
||||
onPlayCommand(event, guild, arg);
|
||||
event.getChannel().sendMessage("Error in command! " + ex.getMessage()).queue();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -129,7 +140,6 @@ public class Main extends ListenerAdapter
|
|||
boolean isNumber = arg.matches("\\d+"); // This is a regular expression that ensures the input consists of digits
|
||||
VoiceChannel channel = null;
|
||||
if (isNumber) // The input is an id?
|
||||
|
||||
channel = guild.getVoiceChannelById(arg);
|
||||
if (channel == null) // Then the input must be a name?
|
||||
{
|
||||
|
@ -158,6 +168,8 @@ public class Main extends ListenerAdapter
|
|||
if (ok)
|
||||
{
|
||||
musicHandler.addSong(song);
|
||||
if (musicHandler.isPlaying())
|
||||
musicHandler.setPlaying(true);
|
||||
event.getChannel().sendMessage("Downloaded and added to queue!").queue();
|
||||
}
|
||||
|
||||
|
@ -171,21 +183,85 @@ public class Main extends ListenerAdapter
|
|||
}
|
||||
}
|
||||
|
||||
private void onRestartCommand(GuildMessageReceivedEvent event)
|
||||
{
|
||||
// TODO: this needs to clear the current data queue
|
||||
boolean ok = musicHandler.restartSong();
|
||||
if (ok)
|
||||
event.getChannel().sendMessage("Restarted current song!").queue();
|
||||
else
|
||||
event.getChannel().sendMessage("Cannot restart!").queue();
|
||||
}
|
||||
|
||||
private void onSkipCommand(GuildMessageReceivedEvent event)
|
||||
{
|
||||
boolean ok = musicHandler.nextSong(true);
|
||||
if (ok)
|
||||
event.getChannel().sendMessage("Skipped to next song!").queue();
|
||||
else
|
||||
event.getChannel().sendMessage("There's no more songs!").queue();
|
||||
}
|
||||
|
||||
private void onQueueCommand(GuildMessageReceivedEvent event, Guild guild)
|
||||
{
|
||||
Queue<Song> songQueue = musicHandler.getSongQueue();
|
||||
String message = new String();
|
||||
int i = 1;
|
||||
message += "Now playing: " + musicHandler.getCurrentSong() + "\n";
|
||||
message += "---\n";
|
||||
for (Song song : songQueue)
|
||||
message += (i) + ": " + song + "\n";
|
||||
event.getChannel().sendMessage(message).queue();
|
||||
}
|
||||
|
||||
private void onRemoveCommand(GuildMessageReceivedEvent event, Guild guild, String arg)
|
||||
{
|
||||
try
|
||||
{
|
||||
int i = Integer.parseInt(arg);
|
||||
boolean removed = musicHandler.removeSong(i - 1);
|
||||
final int size = musicHandler.getSongQueue().size();
|
||||
if (removed)
|
||||
event.getChannel().sendMessage("Song removed.").queue();
|
||||
else if (size > 1)
|
||||
event.getChannel().sendMessage("That's not a number between 1 and " + size + "!").queue();
|
||||
else if (size == 1)
|
||||
event.getChannel().sendMessage("There's only one song to remove and that's not one of them!").queue();
|
||||
|
||||
} catch (NumberFormatException ex)
|
||||
{
|
||||
event.getChannel().sendMessage(arg + " isn't a number!").queue();
|
||||
}
|
||||
}
|
||||
|
||||
private void onHelpCommand(GuildMessageReceivedEvent event)
|
||||
{
|
||||
String help = "Commands available:\n"
|
||||
+ "!join <Channel> - Joins a voice channel\n"
|
||||
+ "!play <URL> - Downloads the track at that URL and adds it to the queue.\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";
|
||||
event.getChannel().sendMessage(help).queue();
|
||||
}
|
||||
|
||||
private boolean downloadSong(Song song) throws IOException, RuntimeException, InterruptedException
|
||||
{
|
||||
String cmd = "/usr/bin/youtube-dl -x --audio-format=wav " + song.getUrl().toString();
|
||||
String cmd = "/usr/bin/youtube-dl -x --audio-format=wav --no-playlist --write-info-json " + song.getUrl().toString();
|
||||
System.out.println("Running command: " + cmd);
|
||||
// Process exec = Runtime.getRuntime().exec().split(" "));
|
||||
Process exec = new ProcessBuilder(cmd.split(" ")).redirectOutput(ProcessBuilder.Redirect.PIPE).start();
|
||||
exec.waitFor(10000, TimeUnit.MILLISECONDS);
|
||||
exec.waitFor(10, TimeUnit.SECONDS);
|
||||
InputStream in = exec.getInputStream();
|
||||
String output = new String(in.readAllBytes(), Charset.defaultCharset());
|
||||
System.out.println(output);
|
||||
if (exec.exitValue() != 0)
|
||||
throw new RuntimeException("youtube-dl failed with error " + exec.exitValue());
|
||||
Matcher matcher = Pattern.compile("Destination: (.*\\.wav)").matcher(output);
|
||||
matcher.find();
|
||||
song.setLocation(new File(matcher.group(0)));
|
||||
if (matcher.find())
|
||||
song.setLocation(new File(matcher.group(1)));
|
||||
else
|
||||
if (exec.exitValue() != 0)
|
||||
throw new RuntimeException("youtube-dl failed with error " + exec.exitValue());
|
||||
return true;
|
||||
// String destination = matcher.group(1);
|
||||
// return destination;
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
package moe.nekojimi.chords;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.logging.Level;
|
||||
|
@ -26,12 +26,15 @@ import net.dv8tion.jda.api.audio.AudioSendHandler;
|
|||
public class MusicHandler implements AudioSendHandler, Closeable
|
||||
{
|
||||
|
||||
private final Queue<Song> songQueue = new ConcurrentLinkedQueue<>();
|
||||
private final LinkedList<Song> songQueue = new LinkedList<>();
|
||||
private Song currentSong;
|
||||
private AudioInputStream din = null;
|
||||
private final Queue<byte[]> queue = new ConcurrentLinkedQueue<>();
|
||||
private boolean playing = true;
|
||||
private int byteCount;
|
||||
|
||||
private boolean arrayErr = false;
|
||||
|
||||
public MusicHandler()
|
||||
{
|
||||
}
|
||||
|
@ -40,12 +43,44 @@ public class MusicHandler implements AudioSendHandler, Closeable
|
|||
{
|
||||
System.out.println("Song added to queue: " + song.getLocation().getAbsolutePath());
|
||||
songQueue.add(song);
|
||||
if (!canProvide())
|
||||
if (!canProvide() && playing)
|
||||
nextSong();
|
||||
}
|
||||
|
||||
public boolean removeSong(int i)
|
||||
{
|
||||
try
|
||||
{
|
||||
songQueue.remove(i);
|
||||
return true;
|
||||
} catch (ArrayIndexOutOfBoundsException ex)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean removeSong(Song song)
|
||||
{
|
||||
return songQueue.remove(song);
|
||||
}
|
||||
|
||||
public boolean restartSong()
|
||||
{
|
||||
songQueue.addFirst(currentSong);
|
||||
currentSong = null;
|
||||
return nextSong(true);
|
||||
}
|
||||
|
||||
private boolean nextSong()
|
||||
{
|
||||
return nextSong(false);
|
||||
}
|
||||
|
||||
public boolean nextSong(boolean immediate)
|
||||
{
|
||||
if (immediate)
|
||||
queue.clear();
|
||||
|
||||
AudioInputStream in = null;
|
||||
try
|
||||
{
|
||||
|
@ -63,6 +98,7 @@ public class MusicHandler implements AudioSendHandler, Closeable
|
|||
if (currentSong == null)
|
||||
return false;
|
||||
System.out.println("Playing song " + currentSong.getLocation().getAbsolutePath());
|
||||
arrayErr = false;
|
||||
in = AudioSystem.getAudioInputStream(currentSong.getLocation());
|
||||
AudioFormat decodedFormat = AudioSendHandler.INPUT_FORMAT;
|
||||
din = AudioSystem.getAudioInputStream(decodedFormat, in);
|
||||
|
@ -81,11 +117,23 @@ public class MusicHandler implements AudioSendHandler, Closeable
|
|||
return false;
|
||||
}
|
||||
|
||||
public boolean isPlaying()
|
||||
{
|
||||
return playing;
|
||||
}
|
||||
|
||||
public void setPlaying(boolean playing)
|
||||
{
|
||||
if (!this.playing && playing)
|
||||
nextSong();
|
||||
this.playing = playing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canProvide()
|
||||
{
|
||||
// If we have something in our buffer we can provide it to the send system
|
||||
return !queue.isEmpty();
|
||||
return !queue.isEmpty() && playing;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -121,10 +169,29 @@ public class MusicHandler implements AudioSendHandler, Closeable
|
|||
{
|
||||
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
|
||||
return false;
|
||||
} catch (ArrayIndexOutOfBoundsException ex)
|
||||
{
|
||||
if (!arrayErr)
|
||||
arrayErr = true;
|
||||
else
|
||||
{
|
||||
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public Queue<Song> getSongQueue()
|
||||
{
|
||||
return songQueue;
|
||||
}
|
||||
|
||||
public Song getCurrentSong()
|
||||
{
|
||||
return currentSong;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpus()
|
||||
{
|
||||
|
|
|
@ -61,7 +61,17 @@ public class Song
|
|||
|
||||
void delete()
|
||||
{
|
||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
if (location != null)
|
||||
location.delete();
|
||||
location = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
if (title != null && !title.isEmpty())
|
||||
return title;
|
||||
else
|
||||
return url.toExternalForm();
|
||||
}
|
||||
}
|
||||
|
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue