As the title suggests I'm making an application that Streams audio from a client to a server where I store the audio and then distribute it to multiple clients to be played. I've got everything working up until the audio storage, but I can't seem to stream the audio to multiple clients.
Here is my attempt:
Server Code:
class Server {
static int port = 50005;
static int listen = 50010;
static int listenerPort = 50015;
static DatagramSocket serverSocket, listenSocket,
broadcastSocket;
static byte[] receiveData, listenData;
static DatagramPacket receivePacket, listenPacket;
static DataOutputStream out;
static ArrayList<String> listeners = new ArrayList<String>();
static File file = new File("recording.bin");
static boolean active = true;
public static void main(String args[]) throws Exception {
//Define the Receiving Datagram Socket
serverSocket = new DatagramSocket(port);
//Define the Timeout of the socket
serverSocket.setSoTimeout(10000);
//Define the listening socket
listenSocket = new DatagramSocket(listen);
listenSocket.setSoTimeout(10000);
//Define Broadcasting socket
broadcastSocket = new DatagramSocket();
//Define data size, 1400 is best sound rate so far
receiveData = new byte[1400];
listenData = new byte[256];
//Define the DatagramPacket object
receivePacket = new DatagramPacket(receiveData, receiveData.length);
listenPacket = new DatagramPacket(listenData, listenData.length);
//Prepare the DataOutputStream to write to file.
out = new DataOutputStream(new FileOutputStream(file));
//Write and Broadcast on a separate thread
Thread t = new Thread() {
@Override public void run() {
getPackets();
}
};
t.start();
//Set up Connection Listener on a separate thread
Thread l = new Thread() {
@Override public void run() {
listen();
}
};
l.start();
}
/***
* Function that gets the audio data packets
* saves them, and outputs the audio to the speakers.
*/
public static void getPackets() {
while (active) {
try {
//Wait until packet is received
serverSocket.receive(receivePacket);
System.out.println("Receiving Data");
//Write to Binary file
out.write(receiveData, 0, receiveData.length);
//Send data
sendData(receivePacket.getData());
} catch (IOException e) {
active = false;
//If connection times out close it
try {
out.close();
} catch (IOException t) {
//Do nothing
}
System.out.println("Converting to audio");
//Convert audio file
new Convert().toWAV();
}
}
}
/***
* Function that listens if there are any connections made to
* the listener port and creates a datagram socket to stream audio
* to anyone who connects
*/
public static void listen() {
while (active) {
try {
//Wait until packet is received
listenSocket.receive(listenPacket);
listeners.add(listenPacket.getAddress().getHostAddress());
System.out.println("Client received");
} catch (IOException e) {
if(active) {
listen();
}
}
}
}
public static void sendData(byte[] data) {
try {
for (int i = 0; i < listeners.size(); i++) {
InetAddress destination = InetAddress.getByName(listeners.get(i));
broadcastSocket.send(new DatagramPacket(data, data.length, destination, listenerPort));
System.out.println("Sending Data");
}
} catch (Exception e) {
//If it failed to send don't do anything
e.printStackTrace();
}
}
}
And here is the code I run on the multiple clients:
class Receiver {
static AudioInputStream ais;
static AudioFormat format;
static boolean active = true;
static int port = 50015;
static DatagramSocket serverSocket, socket;
static byte[] receiveData;
static DatagramPacket receivePacket, packet;
static ByteArrayInputStream bais;
static int sampleRate = 8000;
static int time = 10;
static DataLine.Info dataLineInfo;
static SourceDataLine sourceDataLine;
public static void main(String args[]) throws Exception {
socket = new DatagramSocket();
InetAddress destination = InetAddress.getByName("server ip address");
byte[] temp = new byte[256];
//putting buffer in the packet
packet = new DatagramPacket(temp, temp.length, destination, 50010);
socket.send(packet);
//Define the Receiving Datagram Socket
serverSocket = new DatagramSocket(port);
//Define data size, 1400 is best sound rate so far
receiveData = new byte[1400];
//Define the format sampleRate, Sample Size in Bits, Channels (Mono), Signed, Big Endian
format = new AudioFormat(sampleRate, 16, 1, true, false);
//Define the DatagramPacket object
receivePacket = new DatagramPacket(receiveData, receiveData.length);
//Prepare the Byte Array Input Stream
bais = new ByteArrayInputStream(receivePacket.getData());
//Now concert the Byte Array into an Audio Input Stream
ais = new AudioInputStream(bais, format, receivePacket.getLength());
//Define DataLineInfo
dataLineInfo = new DataLine.Info(SourceDataLine.class, format);
//Get the current Audio Line from the system
sourceDataLine = (SourceDataLine) AudioSystem.getLine(dataLineInfo);
//Open up sourceDataLine and Start it
sourceDataLine.open(format);
sourceDataLine.start();
//Write and play on a separate thread
Thread t = new Thread() {
@Override
public void run() {
getPackets();
}
};
t.start();
//Now keep track of time
while (time > 0) {
time--;
Thread.sleep(1000);
if (time == 0) {
active = false;
}
}
//Close SourceDataLine
sourceDataLine.drain();
sourceDataLine.close();
}
/***
* Function that gets the audio data packets
* saves them, and outputs the audio to the speakers.
*/
public static void getPackets() {
try {
while (active) {
System.out.println("Receiving");
//Wait until packet is received
serverSocket.receive(receivePacket);
//Reset time
time = 10;
//Send data to speakers
toSpeaker(receivePacket.getData());
}
} catch (IOException e) {
}
}
/***
* Function that plays the sound bytes with the speakers.
* @param soundbytes = bytes of sound sent to speakers
*/
public static void toSpeaker(byte soundbytes[]) {
try {
sourceDataLine.write(soundbytes, 0, soundbytes.length);
} catch (Exception e) {
System.out.println("Not working in speakers...");
e.printStackTrace();
}
}
}
I've verified that the server does receive the initial connection which I use to get the clients ip address, but the client does not seem to receive any data, and I'm getting no errors on run time.
Any help would be much appreciated.
Ok so after messing around with this for a while I've realized the problem was not the code, but rather that the admins of the building's network where blocking me. So I'm going to go ahead and mark this as answered.