Adds the ability to play youtube videos.
It still needs a bit of work, but playing and pausing are operational.
This commit is contained in:
@@ -9,6 +9,9 @@ plugins {
|
||||
// In this section you declare where to find the dependencies of your project
|
||||
repositories {
|
||||
mavenCentral()
|
||||
flatDir {
|
||||
dirs new File(rootDir, 'libs')
|
||||
}
|
||||
}
|
||||
|
||||
// In this section you declare the dependencies for your production and test code
|
||||
@@ -19,6 +22,8 @@ dependencies {
|
||||
implementation 'org.apache.logging.log4j:log4j-core:2.13.3'
|
||||
implementation 'org.apache.logging.log4j:log4j-slf4j-impl:2.13.3'
|
||||
|
||||
implementation 'net.harawata:appdirs:1.2.1'
|
||||
|
||||
// Declare the dependency for your favourite test framework you want to use in your tests.
|
||||
// TestNG is also supported by the Gradle Test task. Just change the
|
||||
// testCompile dependency to testCompile 'org.testng:testng:6.8.1' and add
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2021 William Hubbard. All Rights Reserved.
|
||||
*/
|
||||
|
||||
package edu.regis.universeplayer;
|
||||
|
||||
/**
|
||||
* This contains possible states that a player can be in.
|
||||
*/
|
||||
public enum PlaybackStatus
|
||||
{
|
||||
/**
|
||||
* The player is currently playing a song.
|
||||
*/
|
||||
PLAYING,
|
||||
/**
|
||||
* The player has been paused.
|
||||
*/
|
||||
PAUSED,
|
||||
/**
|
||||
* The player has a song loaded, but is not playing it.
|
||||
*/
|
||||
STOPPED,
|
||||
/**
|
||||
* The player has is stopped, but just finished a song and may have more.
|
||||
*/
|
||||
FINISHED,
|
||||
/**
|
||||
* No song is loaded.
|
||||
*/
|
||||
EMPTY
|
||||
}
|
||||
@@ -4,14 +4,51 @@
|
||||
|
||||
package edu.regis.universeplayer.browserCommands;
|
||||
|
||||
import net.harawata.appdirs.AppDirsFactory;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class BrowserConstants
|
||||
{
|
||||
private static final Logger logger = LoggerFactory.getLogger(BrowserConstants.class);
|
||||
/**
|
||||
* The IP that the connection will be hosted on.
|
||||
*/
|
||||
public static final String IP = "127.0.0.1";
|
||||
public static final String IP = "localhost";
|
||||
/**
|
||||
* The port both processes use for connection.
|
||||
*/
|
||||
public static final int PORT = 3000;
|
||||
|
||||
private static File commDir;
|
||||
|
||||
/**
|
||||
* Obtains the directory for memory mapped files
|
||||
*
|
||||
* @return The communications storage directory.
|
||||
*/
|
||||
public static File getCommDir()
|
||||
{
|
||||
if (commDir == null)
|
||||
{
|
||||
commDir = new File(AppDirsFactory.getInstance().getSharedDir("universalmusic", null, null), "comm");
|
||||
if (!commDir.getParentFile().exists())
|
||||
{
|
||||
if (!commDir.getParentFile().mkdir())
|
||||
{
|
||||
logger.error("Could not create shared directory {}", commDir.getParent());
|
||||
}
|
||||
}
|
||||
if (!commDir.exists())
|
||||
{
|
||||
if (!commDir.mkdir())
|
||||
{
|
||||
logger.error("Could not create data directory {}", commDir);
|
||||
}
|
||||
}
|
||||
}
|
||||
return commDir;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2021 William Hubbard. All Rights Reserved.
|
||||
*/
|
||||
|
||||
package edu.regis.universeplayer.browserCommands;
|
||||
|
||||
/**
|
||||
* The quit command tells the browser to shut down.
|
||||
*
|
||||
* @author William Hubbard
|
||||
* @version 0.1
|
||||
*/
|
||||
public class CommandQuit implements BrowserCommand
|
||||
{
|
||||
public CommandQuit()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName()
|
||||
{
|
||||
return "quit";
|
||||
}
|
||||
}
|
||||
@@ -19,20 +19,20 @@ import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
/**
|
||||
*
|
||||
* Dispatches messages sent from a corresponding {@link MessageRunner}.
|
||||
*/
|
||||
public class MessageHandler implements Runnable, MessageSerializer
|
||||
{
|
||||
private final Logger logger;
|
||||
|
||||
private final String name;
|
||||
public final String name;
|
||||
|
||||
private final InputStream input;
|
||||
private final OutputStream output;
|
||||
|
||||
private final ExecutorService executor;
|
||||
private final LinkedList<MessageListener> listeners = new LinkedList<>();
|
||||
private final HashMap<Integer, Future<Object>> messageResponses = new HashMap<>();
|
||||
protected final HashMap<Integer, Future<Object>> messageResponses = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Creates a message handler.
|
||||
@@ -56,14 +56,22 @@ public class MessageHandler implements Runnable, MessageSerializer
|
||||
return logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called at the beginning of every loop to do extra processing and check to see if we can still run.
|
||||
*
|
||||
* @return True if we should close the runner, false otherwise.
|
||||
*/
|
||||
protected boolean onRun()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
BufferedInputStream browserIn = null;
|
||||
BufferedOutputStream browserOut = null;
|
||||
|
||||
boolean running = true;
|
||||
|
||||
byte[][] message;
|
||||
byte[] messageByte;
|
||||
Object messageOb;
|
||||
@@ -76,7 +84,7 @@ public class MessageHandler implements Runnable, MessageSerializer
|
||||
browserIn = new BufferedInputStream(this.input);
|
||||
browserOut = new BufferedOutputStream(this.output);
|
||||
|
||||
while (running)
|
||||
while (!this.onRun())
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -86,7 +94,7 @@ public class MessageHandler implements Runnable, MessageSerializer
|
||||
if (message == null)
|
||||
{
|
||||
logger.info("Connection closed.");
|
||||
running = false;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -24,25 +24,25 @@ public abstract class MessageRunner implements Runnable, MessageSerializer
|
||||
{
|
||||
private final Logger logger;
|
||||
|
||||
private final String name;
|
||||
public final String name;
|
||||
private final InputStream input;
|
||||
private final OutputStream output;
|
||||
private final Object readLock = new Object();
|
||||
protected final Object readLock = new Object();
|
||||
|
||||
/**
|
||||
* This queue serves as a cache for objects we need to send.
|
||||
*/
|
||||
private final LinkedList<MessagePacket> sendQueue = new LinkedList<>();
|
||||
protected final LinkedList<MessagePacket> sendQueue = new LinkedList<>();
|
||||
/**
|
||||
* This queue serves as a cache for objects that are waiting for a response.
|
||||
*/
|
||||
private final HashMap<Integer, MessagePacket> sentQueue = new HashMap<>();
|
||||
private int messagesSent = 0;
|
||||
protected final HashMap<Integer, MessagePacket> sentQueue = new HashMap<>();
|
||||
protected int messagesSent = 0;
|
||||
|
||||
/**
|
||||
* Creates a message runner.
|
||||
*
|
||||
* @param name - The name of the runner. This is used in logging.
|
||||
* @param name - The name of the runner. This is used in logging.
|
||||
* @param input - The input from our external source.
|
||||
* @param output - The output to the external source.
|
||||
*/
|
||||
@@ -60,14 +60,22 @@ public abstract class MessageRunner implements Runnable, MessageSerializer
|
||||
return logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called at the beginning of every loop to do extra processing and check to see if we can still run.
|
||||
*
|
||||
* @return True if we should close the runner, false otherwise.
|
||||
*/
|
||||
protected boolean onRun()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
BufferedInputStream browserIn = null;
|
||||
BufferedOutputStream browserOut = null;
|
||||
MessagePacket packet;
|
||||
|
||||
boolean running = true;
|
||||
|
||||
byte[][] returnMessage;
|
||||
ByteBuffer numBuffer = ByteBuffer.allocate(4);
|
||||
@@ -77,7 +85,7 @@ public abstract class MessageRunner implements Runnable, MessageSerializer
|
||||
browserIn = new BufferedInputStream(this.input);
|
||||
browserOut = new BufferedOutputStream(this.output);
|
||||
|
||||
while (running)
|
||||
while (!this.onRun())
|
||||
{
|
||||
/*
|
||||
* Sends a messages
|
||||
@@ -121,7 +129,7 @@ public abstract class MessageRunner implements Runnable, MessageSerializer
|
||||
if (returnMessage == null)
|
||||
{
|
||||
logger.info("Connection closed.");
|
||||
running = false;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -138,7 +146,7 @@ public abstract class MessageRunner implements Runnable, MessageSerializer
|
||||
{
|
||||
packet.returnMessage = returnMessage[1];
|
||||
numBuffer.clear();
|
||||
logger.debug("Reading message {} {}", numBuffer.getInt(), packet.returnMessage);
|
||||
logger.debug("Reading message {} {}", numBuffer.getInt(), new String(packet.returnMessage, StandardCharsets.UTF_8));
|
||||
synchronized (this.readLock)
|
||||
{
|
||||
logger.trace("Received message {}, notifying futures.", packet.returnValue.index);
|
||||
@@ -254,9 +262,9 @@ public abstract class MessageRunner implements Runnable, MessageSerializer
|
||||
*/
|
||||
public class MessageFuture implements Future<Object>
|
||||
{
|
||||
private final MessagePacket packetEntry;
|
||||
private int index;
|
||||
private boolean canceled = false;
|
||||
protected final MessagePacket packetEntry;
|
||||
public int index;
|
||||
protected boolean canceled = false;
|
||||
|
||||
private MessageFuture(MessagePacket packet)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 2021 William Hubbard. All Rights Reserved.
|
||||
*/
|
||||
|
||||
package edu.regis.universeplayer.browserCommands;
|
||||
|
||||
/**
|
||||
* This query asks for whether a song is currently playing or not. Note that
|
||||
* this is not the same as whether it is paused or not, as a song could have
|
||||
* run into a playback error.
|
||||
*
|
||||
* @author William Hubbard
|
||||
* @version 0.1
|
||||
*/
|
||||
public class QueryStatus implements BrowserQuery<Integer>
|
||||
{
|
||||
@Override
|
||||
public String getCommandName()
|
||||
{
|
||||
return "getStatus";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<Integer> getReturnType()
|
||||
{
|
||||
return Integer.class;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user