RealTimeTalk/app/src/main/java/com/smarthomies/realtimetalk/utils/MediaStreamServer.java

172 lines
4.8 KiB
Java

package com.smarthomies.realtimetalk.utils;
import android.content.Context;
import android.util.Log;
import com.smarthomies.realtimetalk.R;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Properties;
import java.util.concurrent.CountDownLatch;
public class MediaStreamServer implements Runnable {
private static final String TAG = MediaStreamServer.class.getSimpleName();
private boolean isListening;
private Socket socketConnection;
private ServerSocket serverSocket;
private final int SERVERPORT;
private Thread serverThread;
private CallCallbacks callListener;
private static MediaStreamServer instance;
public static void initWithContext(Context context) {
instance = new MediaStreamServer(context);
}
public static MediaStreamServer getInstance() {
if(instance == null) {
throw new RuntimeException("Initialize server first with initWithContext");
}
return instance;
}
public void setCallListener(CallCallbacks callListener) {
this.callListener = callListener;
}
public void removeCallListener() {
this.callListener = null;
}
private MediaStreamServer(Context ctx) {
Properties prop = new Properties();
try {
InputStream inputStream = ctx.getResources().openRawResource(R.raw.config);
prop.load(inputStream);
} catch (FileNotFoundException e) {
Log.d(TAG, "Can't find config");
} catch (IOException e) {
Log.d(TAG, "Can't load config");
}
SERVERPORT = Integer.parseInt(prop.getProperty("port_client"));
}
public void stop() {
isListening = false;
serverThread.interrupt();
}
public void startListeningToPort() {
if(serverThread == null) {
serverThread = new Thread(this);
}
serverThread.start();
}
public void stopListeningToPort() {
isListening = false;
}
@Override
public void run() {
isListening = true;
try {
serverSocket = new ServerSocket(SERVERPORT);
Log.d(TAG, "Server socket open on port: " + SERVERPORT);
}
catch (IOException e) {
e.printStackTrace();
notifyError(ERROR_PORT_UNAVAILABLE);
isListening = false;
return;
}
while(isListening) {
try {
socketConnection = serverSocket.accept();
Log.d(TAG, "Accepted socket connection!");
Log.d(TAG, "Socket connection info: " + socketConnection);
notifyConnectionRequested(socketConnection);
} catch (IOException e) {
e.printStackTrace();
notifyError(ERROR_WHILE_ACCEPTING);
continue;
}
final CountDownLatch callTerminationLock = new CountDownLatch(1);
Log.d(TAG, "Playing audio!");
MediaStreamerThread.getInstance().playAudioFromSocket(socketConnection, callTerminationLock);
try {
callTerminationLock.await();
Log.d(TAG, "Done playing!");
} catch (InterruptedException ex) {
ex.printStackTrace();
notifyError(ERROR_CALL_INTERRUPTED);
continue;
}
try {
socketConnection.close();
notifyConnectionFinished();
} catch (Exception e) {
e.printStackTrace();
notifyError(ERROR_WHILE_CLOSING_CONNECTION);
}
}
try {
serverSocket.close();
}
catch (IOException e) {
e.printStackTrace();
notifyError(ERROR_WHILE_CLOSING);
isListening = false;
}
}
private void notifyError(int errorCode) {
if(callListener != null) {
callListener.onError(errorCode);
}
}
private void notifyConnectionRequested(Socket sourceSocket) {
if(callListener != null) {
callListener.onConnectionRequested(sourceSocket);
}
}
private void notifyConnectionFinished() {
if(callListener != null) {
callListener.onConnectionFinished();
}
}
public static final int ERROR_PORT_UNAVAILABLE = 0;
public static final int ERROR_WHILE_CLOSING = 1;
public static final int ERROR_WHILE_ACCEPTING = 2;
public static final int ERROR_WHILE_PLAYING = 3;
public static final int ERROR_WHILE_CLOSING_CONNECTION = 4;
public static final int ERROR_CALL_INTERRUPTED = 5;
public interface CallCallbacks {
void onError(int errorCode);
void onConnectionRequested(Socket sourceSocket);
void onConnectionFinished();
}
}