Adds a CLI that will interface with the currently running instance of the player.
This commit is contained in:
@@ -9,12 +9,18 @@ import java.io.File;
|
|||||||
|
|
||||||
public class ConfigManager
|
public class ConfigManager
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* The port the player will listen for connecting instances on.
|
||||||
|
*/
|
||||||
|
public static final int PORT = 3001;
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory
|
private static final Logger logger = LoggerFactory
|
||||||
.getLogger(ConfigManager.class);
|
.getLogger(ConfigManager.class);
|
||||||
|
|
||||||
private static File dataDir;
|
private static File dataDir;
|
||||||
private static File commDir;
|
private static File commDir;
|
||||||
private static File configDir;
|
private static File configDir;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtains the data storage directory for the application, creating it if
|
* Obtains the data storage directory for the application, creating it if
|
||||||
* needed.
|
* needed.
|
||||||
|
|||||||
@@ -0,0 +1,160 @@
|
|||||||
|
package edu.regis.universeplayer;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.ServerSocket;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.InputMismatchException;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Scanner;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This runner is used to handle other instances of the program wanting to
|
||||||
|
* manipulate the main state.
|
||||||
|
*
|
||||||
|
* @author William Hubbard.
|
||||||
|
* @version 0.1
|
||||||
|
*/
|
||||||
|
public class InstanceConnector implements Runnable
|
||||||
|
{
|
||||||
|
private static final Logger logger =
|
||||||
|
LoggerFactory.getLogger(InstanceConnector.class);
|
||||||
|
private AtomicBoolean running = new AtomicBoolean(true);
|
||||||
|
ExecutorService service = Executors.newFixedThreadPool(5);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
ServerSocket server = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
server = new ServerSocket(ConfigManager.PORT, 50, InetAddress
|
||||||
|
.getByName(null));
|
||||||
|
|
||||||
|
while (this.running.get())
|
||||||
|
{
|
||||||
|
Socket socket = server.accept();
|
||||||
|
service.submit(() -> {
|
||||||
|
try (Scanner scanner = new Scanner(socket.getInputStream()))
|
||||||
|
{
|
||||||
|
String[] args = scanner.nextLine().trim().split(" ");
|
||||||
|
ArrayList<String> parsedArgs = new ArrayList<>();
|
||||||
|
StringBuilder cachedString = null;
|
||||||
|
for (String arg : args)
|
||||||
|
{
|
||||||
|
if (cachedString != null)
|
||||||
|
{
|
||||||
|
if (arg.endsWith("\""))
|
||||||
|
{
|
||||||
|
cachedString
|
||||||
|
.append(arg, 0, arg.length() - 1);
|
||||||
|
parsedArgs.add(cachedString.toString());
|
||||||
|
cachedString = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cachedString.append(arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (arg.startsWith("\""))
|
||||||
|
{
|
||||||
|
if (arg.endsWith("\""))
|
||||||
|
{
|
||||||
|
parsedArgs.add(arg.substring(1,
|
||||||
|
arg.length() - 1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cachedString =
|
||||||
|
new StringBuilder(arg.substring(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
parsedArgs.add(arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args = parsedArgs.toArray(String[]::new);
|
||||||
|
LinkedHashMap<String, Object> ops = new LinkedHashMap<>();
|
||||||
|
parsedArgs.clear();
|
||||||
|
PlayerEnvironment.parseArgs(args, ops, parsedArgs);
|
||||||
|
if (ops.containsKey("h") || ops.containsKey("help"))
|
||||||
|
{
|
||||||
|
PlayerEnvironment.printHelp();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
PlayerEnvironment.runArguments(ops, parsedArgs,
|
||||||
|
new PrintStream(socket.getOutputStream()));
|
||||||
|
socket.shutdownOutput();
|
||||||
|
/*
|
||||||
|
* Wait for the client to acknowledge the print
|
||||||
|
* before closing the stream.
|
||||||
|
*/
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
scanner.nextInt();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
catch (InputMismatchException e)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
logger.debug("Finished request");
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
logger.error("Error reading socket stream");
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
socket.close();
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
logger.error("Could not close socket", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
logger.error("Error starting server", e);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (server != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
server.close();
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
logger.error("Unable to close server", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops the server.
|
||||||
|
*/
|
||||||
|
public void stop()
|
||||||
|
{
|
||||||
|
this.running.set(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,16 +3,18 @@ package edu.regis.universeplayer;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.lang.reflect.Array;
|
import java.io.IOException;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.net.Socket;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.ResourceBundle;
|
import java.util.ResourceBundle;
|
||||||
|
import java.util.Scanner;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@@ -46,69 +48,7 @@ public class PlayerEnvironment
|
|||||||
{
|
{
|
||||||
LinkedHashMap<String, Object> ops = new LinkedHashMap<>();
|
LinkedHashMap<String, Object> ops = new LinkedHashMap<>();
|
||||||
ArrayList<String> params = new ArrayList<>();
|
ArrayList<String> params = new ArrayList<>();
|
||||||
int equals = -1;
|
parseArgs(args, ops, params);
|
||||||
Object value;
|
|
||||||
String key;
|
|
||||||
String valStr;
|
|
||||||
int i, j, l, l2;
|
|
||||||
for (i = 0, l = args.length; i < l; i++)
|
|
||||||
{
|
|
||||||
valStr = null;
|
|
||||||
if (args[i].startsWith("-"))
|
|
||||||
{
|
|
||||||
if (args[i].startsWith("--"))
|
|
||||||
{
|
|
||||||
equals = args[i].indexOf('=');
|
|
||||||
if (equals != -1)
|
|
||||||
{
|
|
||||||
valStr = args[i].substring(equals + 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
equals = args[i].length();
|
|
||||||
valStr = null;
|
|
||||||
}
|
|
||||||
key = args[i].substring(2, equals);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (j = 1, l2 = args[i].length() - 1; j < l2; j++)
|
|
||||||
{
|
|
||||||
ops.put(args[i].substring(j, j + 1), null);
|
|
||||||
}
|
|
||||||
key = args[i].substring(j, j + 1);
|
|
||||||
}
|
|
||||||
if (valStr == null && i < args.length - 1 && !args[i + 1]
|
|
||||||
.startsWith("-"))
|
|
||||||
{
|
|
||||||
valStr = args[++i];
|
|
||||||
}
|
|
||||||
if (valStr != null)
|
|
||||||
{
|
|
||||||
if (Pattern.matches("\\d+", valStr))
|
|
||||||
{
|
|
||||||
value = Integer.parseInt(valStr);
|
|
||||||
}
|
|
||||||
else if (Pattern.matches("\\d*\\.\\d+", valStr))
|
|
||||||
{
|
|
||||||
value = Double.parseDouble(valStr);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
value = valStr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
value = true;
|
|
||||||
}
|
|
||||||
ops.put(key, value);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
params.add(args[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ops.containsKey("h") || ops.containsKey("help"))
|
if (ops.containsKey("h") || ops.containsKey("help"))
|
||||||
{
|
{
|
||||||
@@ -116,6 +56,63 @@ public class PlayerEnvironment
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!connectToServer(args))
|
||||||
|
{
|
||||||
|
init(ops, params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forwards command arguments to the server.
|
||||||
|
*
|
||||||
|
* @param args - The argument list to forward.
|
||||||
|
* @return True if the server exists, false if not.
|
||||||
|
*/
|
||||||
|
private static boolean connectToServer(String[] args)
|
||||||
|
{
|
||||||
|
Socket socket;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
socket = new Socket("localhost", ConfigManager.PORT);
|
||||||
|
try (PrintStream out = new PrintStream(socket.getOutputStream()))
|
||||||
|
{
|
||||||
|
boolean quote;
|
||||||
|
for (String arg : args)
|
||||||
|
{
|
||||||
|
quote = arg.contains(" ");
|
||||||
|
if (quote)
|
||||||
|
{
|
||||||
|
out.print('"');
|
||||||
|
}
|
||||||
|
out.print(arg);
|
||||||
|
if (quote)
|
||||||
|
{
|
||||||
|
out.print('"');
|
||||||
|
}
|
||||||
|
out.print(' ');
|
||||||
|
}
|
||||||
|
out.println();
|
||||||
|
try (Scanner in = new Scanner(socket.getInputStream()))
|
||||||
|
{
|
||||||
|
while (in.hasNextLine())
|
||||||
|
{
|
||||||
|
System.out.println(in.nextLine());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out.print(1);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
logger.debug("Couldn't connect to server", e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void init(HashMap<String, Object> ops,
|
||||||
|
ArrayList<String> params)
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
* Add this just in case of a crash or something. It won't work if the
|
* Add this just in case of a crash or something. It won't work if the
|
||||||
* program is forcibly terminated by the OS, but it could be helpful
|
* program is forcibly terminated by the OS, but it could be helpful
|
||||||
@@ -123,6 +120,9 @@ public class PlayerEnvironment
|
|||||||
*/
|
*/
|
||||||
logger.info("Starting application {} {}", params, ops);
|
logger.info("Starting application {} {}", params, ops);
|
||||||
|
|
||||||
|
InstanceConnector connector = new InstanceConnector();
|
||||||
|
new Thread(connector).start();
|
||||||
|
|
||||||
Queue queue = Queue.getInstance();
|
Queue queue = Queue.getInstance();
|
||||||
PlayerManager playback = PlayerManager.getPlayers();
|
PlayerManager playback = PlayerManager.getPlayers();
|
||||||
queue.addSongChangeListener(queue1 -> {
|
queue.addSongChangeListener(queue1 -> {
|
||||||
@@ -146,7 +146,7 @@ public class PlayerEnvironment
|
|||||||
logger.error("Could not run command",
|
logger.error("Could not run command",
|
||||||
command.getConfirmation().getError());
|
command.getConfirmation().getError());
|
||||||
}
|
}
|
||||||
else
|
else if (queue1.getCurrentSong() != null)
|
||||||
{
|
{
|
||||||
command =
|
command =
|
||||||
PlayerManager.getPlayers()
|
PlayerManager.getPlayers()
|
||||||
@@ -201,31 +201,258 @@ public class PlayerEnvironment
|
|||||||
/*
|
/*
|
||||||
* Open up the relevant songs
|
* Open up the relevant songs
|
||||||
*/
|
*/
|
||||||
HashMap<Song, Integer> matchMap = new HashMap<>();
|
runArguments(ops, params, System.out);
|
||||||
for (String param : params)
|
|
||||||
|
Runtime.getRuntime().addShutdownHook(new Thread(connector::stop));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts an array of string arguments into a map of options and extra
|
||||||
|
* parameters.
|
||||||
|
*
|
||||||
|
* @param args - The arguments to parse.
|
||||||
|
* @param options - The map to dump the options into.
|
||||||
|
* @param params - The list to dump the other parameters into.
|
||||||
|
*/
|
||||||
|
public static void parseArgs(String[] args,
|
||||||
|
Map<String, Object> options,
|
||||||
|
List<String> params)
|
||||||
|
{
|
||||||
|
int equals = -1;
|
||||||
|
Object value;
|
||||||
|
String key;
|
||||||
|
String valStr;
|
||||||
|
int i, j, l, l2;
|
||||||
|
for (i = 0, l = args.length; i < l; i++)
|
||||||
{
|
{
|
||||||
String finalParam = param.toLowerCase();
|
valStr = null;
|
||||||
SongProvider.INSTANCE.getSongs().stream().forEach(song -> {
|
if (args[i].startsWith("-"))
|
||||||
Integer matches = matchMap.get(song);
|
{
|
||||||
if (matches == null)
|
if (args[i].startsWith("--"))
|
||||||
{
|
{
|
||||||
matches = 0;
|
equals = args[i].indexOf('=');
|
||||||
|
if (equals != -1)
|
||||||
|
{
|
||||||
|
valStr = args[i].substring(equals + 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
equals = args[i].length();
|
||||||
|
valStr = null;
|
||||||
|
}
|
||||||
|
key = args[i].substring(2, equals);
|
||||||
}
|
}
|
||||||
if (song.title != null && song.title.toLowerCase()
|
else
|
||||||
.contains(finalParam))
|
|
||||||
{
|
{
|
||||||
matches++;
|
for (j = 1, l2 = args[i].length() - 1; j < l2; j++)
|
||||||
|
{
|
||||||
|
options.put(args[i].substring(j, j + 1), null);
|
||||||
|
}
|
||||||
|
key = args[i].substring(j, j + 1);
|
||||||
}
|
}
|
||||||
if (song.album != null)
|
if (valStr == null && i < args.length - 1 && !args[i + 1]
|
||||||
|
.startsWith("-"))
|
||||||
{
|
{
|
||||||
if (song.album.name != null && song.album.name.toLowerCase()
|
valStr = args[++i];
|
||||||
.contains(finalParam))
|
}
|
||||||
|
if (valStr != null)
|
||||||
|
{
|
||||||
|
if (Pattern.matches("\\d+", valStr))
|
||||||
|
{
|
||||||
|
value = Integer.parseInt(valStr);
|
||||||
|
}
|
||||||
|
else if (Pattern.matches("\\d*\\.\\d+", valStr))
|
||||||
|
{
|
||||||
|
value = Double.parseDouble(valStr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
value = valStr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
value = true;
|
||||||
|
}
|
||||||
|
options.put(key, value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
params.add(args[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs command-line arguments
|
||||||
|
*
|
||||||
|
* @param options - Run options
|
||||||
|
* @param params - A list of song terms to search for and enqueue.
|
||||||
|
* @param out - Program output. While this may simply be System .out,
|
||||||
|
* this is just as likely going to be outputting to another
|
||||||
|
* program instance.
|
||||||
|
*/
|
||||||
|
public static void runArguments(Map<String, Object> options,
|
||||||
|
List<String> params, PrintStream out)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
out.println(options.toString());
|
||||||
|
out.println(params.toString());
|
||||||
|
for (String op : options.keySet())
|
||||||
|
{
|
||||||
|
switch (op)
|
||||||
|
{
|
||||||
|
case "play" -> {
|
||||||
|
PlayerManager.getPlayers().play();
|
||||||
|
out.println("Playing");
|
||||||
|
}
|
||||||
|
case "pause" -> {
|
||||||
|
PlayerManager.getPlayers().pause();
|
||||||
|
out.println("Pausing");
|
||||||
|
}
|
||||||
|
case "toggle", "t" -> {
|
||||||
|
PlayerManager.getPlayers().toggle();
|
||||||
|
out.println("Toggling playback");
|
||||||
|
}
|
||||||
|
case "seek" -> {
|
||||||
|
PlayerManager.getPlayers()
|
||||||
|
.seek((int) options.get("seek"));
|
||||||
|
out.println("Seeking");
|
||||||
|
}
|
||||||
|
case "clear", "c" -> {
|
||||||
|
out.println("Clearing");
|
||||||
|
Queue.getInstance().clear();
|
||||||
|
}
|
||||||
|
case "next", "n" -> {
|
||||||
|
Integer number = null;
|
||||||
|
if (options.get("next") instanceof Integer)
|
||||||
|
{
|
||||||
|
number = (Integer) options.get("next");
|
||||||
|
}
|
||||||
|
else if (options.get("n") instanceof Integer)
|
||||||
|
{
|
||||||
|
number = (Integer) options.get("n");
|
||||||
|
}
|
||||||
|
if (number == null)
|
||||||
|
{
|
||||||
|
Queue.getInstance().skipNext();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Queue.getInstance().skipToSong(Queue.getInstance()
|
||||||
|
.getCurrentIndex() + number);
|
||||||
|
}
|
||||||
|
out.println("Next Song");
|
||||||
|
}
|
||||||
|
case "prev", "p" -> {
|
||||||
|
Integer number = null;
|
||||||
|
if (options.get("prev") instanceof Integer)
|
||||||
|
{
|
||||||
|
number = (Integer) options.get("prev");
|
||||||
|
}
|
||||||
|
else if (options.get("p") instanceof Integer)
|
||||||
|
{
|
||||||
|
number = (Integer) options.get("p");
|
||||||
|
}
|
||||||
|
if (number == null)
|
||||||
|
{
|
||||||
|
Queue.getInstance().skipNext();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Queue.getInstance().skipToSong(Queue.getInstance()
|
||||||
|
.getCurrentIndex() - number);
|
||||||
|
}
|
||||||
|
out.println("Clearing");
|
||||||
|
}
|
||||||
|
case "skip" -> {
|
||||||
|
Integer number = null;
|
||||||
|
if (options.get("skip") instanceof Integer)
|
||||||
|
{
|
||||||
|
number = (Integer) options.get("skip");
|
||||||
|
}
|
||||||
|
if (number == null)
|
||||||
|
{
|
||||||
|
Queue.getInstance().skipNext();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Queue.getInstance().skipToSong(number);
|
||||||
|
}
|
||||||
|
out.println("Clearing");
|
||||||
|
}
|
||||||
|
case "status" -> {
|
||||||
|
QueryFuture<PlaybackStatus> status =
|
||||||
|
PlayerManager.getPlayers().getStatus();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
out.println(status.get());
|
||||||
|
}
|
||||||
|
catch (InterruptedException | ExecutionException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace(out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case "song" -> {
|
||||||
|
Song song = PlayerManager.getPlayers().getCurrentSong();
|
||||||
|
out.println(song.toString());
|
||||||
|
}
|
||||||
|
case "queue" -> {
|
||||||
|
for (Song song : Queue.getInstance())
|
||||||
|
{
|
||||||
|
out.print(" ");
|
||||||
|
if (song == PlayerManager.getPlayers().getCurrentSong())
|
||||||
|
{
|
||||||
|
out.print("*");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
out.print(" ");
|
||||||
|
}
|
||||||
|
out.print(" ");
|
||||||
|
out.println(song.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
HashMap<Song, Integer> matchMap = new HashMap<>();
|
||||||
|
for (String param : params)
|
||||||
|
{
|
||||||
|
String finalParam = param.toLowerCase();
|
||||||
|
SongProvider.INSTANCE.getSongs().forEach(song -> {
|
||||||
|
Integer matches = matchMap.get(song);
|
||||||
|
if (matches == null)
|
||||||
|
{
|
||||||
|
matches = 0;
|
||||||
|
}
|
||||||
|
if (song.title != null && song.title.toLowerCase()
|
||||||
|
.contains(finalParam))
|
||||||
{
|
{
|
||||||
matches++;
|
matches++;
|
||||||
}
|
}
|
||||||
if (song.album.artists != null && song.album.artists.length > 0)
|
if (song.album != null)
|
||||||
{
|
{
|
||||||
for (String artist : song.album.artists)
|
if (song.album.name != null && song.album.name
|
||||||
|
.toLowerCase()
|
||||||
|
.contains(finalParam))
|
||||||
|
{
|
||||||
|
matches++;
|
||||||
|
}
|
||||||
|
if (song.album.artists != null && song.album.artists.length > 0)
|
||||||
|
{
|
||||||
|
for (String artist : song.album.artists)
|
||||||
|
{
|
||||||
|
if (artist.toLowerCase().contains(finalParam))
|
||||||
|
{
|
||||||
|
matches++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (song.artists != null && song.artists.length > 0)
|
||||||
|
{
|
||||||
|
for (String artist : song.artists)
|
||||||
{
|
{
|
||||||
if (artist.toLowerCase().contains(finalParam))
|
if (artist.toLowerCase().contains(finalParam))
|
||||||
{
|
{
|
||||||
@@ -233,54 +460,73 @@ public class PlayerEnvironment
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if (matches > 0)
|
||||||
if (song.artists != null && song.artists.length > 0)
|
|
||||||
{
|
|
||||||
for (String artist : song.artists)
|
|
||||||
{
|
{
|
||||||
if (artist.toLowerCase().contains(finalParam))
|
out.printf("%d matches for %s and %s\n", matches,
|
||||||
{
|
finalParam, song);
|
||||||
matches++;
|
matchMap.put(song, matches);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
if (matches > 0)
|
|
||||||
{
|
|
||||||
matchMap.put(song, matches);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (matchMap.size() > 0)
|
|
||||||
{
|
|
||||||
List<Song> songs = matchMap.entrySet().stream().sorted(Map.Entry
|
|
||||||
.comparingByValue()).filter(entry -> (entry
|
|
||||||
.getValue() / (float) params.size()) >= 0.65F)
|
|
||||||
.map(Map.Entry::getKey)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
System.out.println("Playing " + songs.toString());
|
|
||||||
Collections.reverse(songs);
|
|
||||||
Queue.getInstance().addAll(songs);
|
|
||||||
}
|
|
||||||
for (String op : ops.keySet())
|
|
||||||
{
|
|
||||||
switch (op)
|
|
||||||
{
|
|
||||||
case "play" -> PlayerManager.getPlayers().play();
|
|
||||||
case "pause" -> PlayerManager.getPlayers().pause();
|
|
||||||
case "toggle", "t" -> PlayerManager.getPlayers().toggle();
|
|
||||||
case "seek" -> PlayerManager.getPlayers()
|
|
||||||
.seek((int) ops.get("seek"));
|
|
||||||
}
|
}
|
||||||
|
if (matchMap.size() > 0)
|
||||||
|
{
|
||||||
|
List<Song> songs = matchMap.entrySet().stream().sorted(Map.Entry
|
||||||
|
.comparingByValue()).filter(entry -> (entry
|
||||||
|
.getValue() / (float) params.size()) >= 0.65F)
|
||||||
|
.map(entry -> {
|
||||||
|
out.printf("%s: %d / %d (%f)\n",
|
||||||
|
entry.getKey(),
|
||||||
|
entry.getValue(),
|
||||||
|
params.size(),
|
||||||
|
entry.getValue() / (float) params
|
||||||
|
.size());
|
||||||
|
return entry.getKey();
|
||||||
|
})
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
Collections.reverse(songs);
|
||||||
|
out.println("Playing " + songs.toString());
|
||||||
|
Queue.getInstance().addAll(songs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Throwable e)
|
||||||
|
{
|
||||||
|
e.printStackTrace(out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void printHelp()
|
public static void printHelp()
|
||||||
{
|
{
|
||||||
System.out.println("Universal Music Player");
|
System.out.println("Universal Music Player");
|
||||||
System.out.println("----------------------");
|
System.out.println("----------------------");
|
||||||
System.out.println("CLI Arguments");
|
System.out.println("CLI Arguments");
|
||||||
System.out.println("\t--headless");
|
System.out.println("\t--headless");
|
||||||
System.out.println("\t\tRuns the player without a GUI.");
|
System.out.println("\t\tRuns the player without a GUI.");
|
||||||
|
System.out.println("\t--play");
|
||||||
|
System.out.println("\t\tStarts playback");
|
||||||
|
System.out.println("\t--pause");
|
||||||
|
System.out.println("\t\tPauses playback");
|
||||||
|
System.out.println("\t--toggle, -t");
|
||||||
|
System.out.println("\t\tToggles playback");
|
||||||
|
System.out.println("\t--seek <time>");
|
||||||
|
System.out.println("\t\tSeeks the player to the provided time, in " +
|
||||||
|
"seconds");
|
||||||
|
System.out.println("\t--clear, -c");
|
||||||
|
System.out.println("\t\tClears the queue before adding songs");
|
||||||
|
System.out.println("\t--next, -n [skipBy]");
|
||||||
|
System.out.println("\t\tSkips to the next song by skipBy songs. " +
|
||||||
|
"Defaults to 1.");
|
||||||
|
System.out.println("\t--prev, -p [skipBy]");
|
||||||
|
System.out.println("\t\tSkips to the previous song by skipBy songs. " +
|
||||||
|
"Defaults to 1.");
|
||||||
|
System.out.println("\t--skip [skipTo]");
|
||||||
|
System.out.println("\t\tSkips to the requested song in the queue. " +
|
||||||
|
"Defaults to the next song.");
|
||||||
|
System.out.println("\t--status");
|
||||||
|
System.out.println("\t\tObtains the playback status");
|
||||||
|
System.out.println("\t--song");
|
||||||
|
System.out.println("\t\tObtains the current song");
|
||||||
|
System.out.println("\t--queue");
|
||||||
|
System.out.println("\t\tGets the queue");
|
||||||
System.out.println("\t--help, -h");
|
System.out.println("\t--help, -h");
|
||||||
System.out.println("\t\tPrints this help message");
|
System.out.println("\t\tPrints this help message");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,6 +75,10 @@ public class PlayerManager implements PlaybackListener
|
|||||||
*/
|
*/
|
||||||
public Player<?> getCompatiblePlayer(Song song)
|
public Player<?> getCompatiblePlayer(Song song)
|
||||||
{
|
{
|
||||||
|
if (song == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
Player<?> player = this.players.get(song.getClass());
|
Player<?> player = this.players.get(song.getClass());
|
||||||
if (player == null)
|
if (player == null)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user