package computician.janusclient;
import android.content.Context;
import android.opengl.EGLContext;
import android.util.Log;
import org.json.JSONArray;
import org.json.JSONObject;
import org.webrtc.MediaStream;
import org.webrtc.PeerConnection;
import org.webrtc.VideoRenderer;
import org.webrtc.VideoRendererGui;
import java.math.BigInteger;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.HashMap;
import java.util.List;
import java.util.Stack;
import computician.janusclientapi.IJanusGatewayCallbacks;
import computician.janusclientapi.IJanusPluginCallbacks;
import computician.janusclientapi.IPluginHandleWebRTCCallbacks;
import computician.janusclientapi.JanusMediaConstraints;
import computician.janusclientapi.JanusPluginHandle;
import computician.janusclientapi.JanusServer;
import computician.janusclientapi.JanusSupportedPluginPackages;
import computician.janusclientapi.PluginHandleSendMessageCallbacks;
import computician.janusclientapi.PluginHandleWebRTCCallbacks;
//TODO create message classes unique to this plugin
/**
* Created by ben.trent on 7/24/2015.
*/
public class VideoRoomTest {
public static final String REQUEST = "request";
public static final String MESSAGE = "message";
public static final String PUBLISHERS = "publishers";
private final String JANUS_URI = "ws://192.168.1.197:8188";
private JanusPluginHandle handle = null;
private VideoRenderer.Callbacks localRender;
private Deque<VideoRenderer.Callbacks> availableRemoteRenderers = new ArrayDeque<>();
private HashMap<BigInteger, VideoRenderer.Callbacks> remoteRenderers = new HashMap<>();
private JanusServer janusServer;
private BigInteger myid;
final private String user_name = "android";
final private int roomid = 1234;
public VideoRoomTest(VideoRenderer.Callbacks localRender, VideoRenderer.Callbacks[] remoteRenders) {
this.localRender = localRender;
for(int i = 0; i < remoteRenders.length; i++)
{
this.availableRemoteRenderers.push(remoteRenders[i]);
}
janusServer = new JanusServer(new JanusGlobalCallbacks());
}
class ListenerAttachCallbacks implements IJanusPluginCallbacks{
final private VideoRenderer.Callbacks renderer;
final private BigInteger feedid;
private JanusPluginHandle listener_handle = null;
public ListenerAttachCallbacks(BigInteger id, VideoRenderer.Callbacks renderer){
this.renderer = renderer;
this.feedid = id;
}
public void success(JanusPluginHandle handle) {
listener_handle = handle;
try
{
JSONObject body = new JSONObject();
JSONObject msg = new JSONObject();
body.put(REQUEST, "join");
body.put("room", roomid);
body.put("ptype", "listener");
body.put("feed", feedid);
msg.put(MESSAGE, body);
handle.sendMessage(new PluginHandleSendMessageCallbacks(msg));
}
catch(Exception ex)
{
}
}
@Override
public void onMessage(JSONObject msg, JSONObject jsep) {
try {
String event = msg.getString("videoroom");
if (event.equals("attached") && jsep != null) {
final JSONObject remoteJsep = jsep;
listener_handle.createAnswer(new IPluginHandleWebRTCCallbacks() {
@Override
public void onSuccess(JSONObject obj) {
try {
JSONObject mymsg = new JSONObject();
JSONObject body = new JSONObject();
body.put(REQUEST, "start");
body.put("room", roomid);
mymsg.put(MESSAGE, body);
mymsg.put("jsep", obj);
listener_handle.sendMessage(new PluginHandleSendMessageCallbacks(mymsg));
} catch (Exception ex) {
}
}
@Override
public JSONObject getJsep() {
return remoteJsep;
}
@Override
public JanusMediaConstraints getMedia() {
JanusMediaConstraints cons = new JanusMediaConstraints();
cons.setVideo(null);
cons.setRecvAudio(true);
cons.setRecvVideo(true);
cons.setSendAudio(false);
return cons;
}
@Override
public Boolean getTrickle() {
return true;
}
@Override
public void onCallbackError(String error) {
}
});
}
}
catch(Exception ex)
{
}
}
@Override
public void onLocalStream(MediaStream stream) {
}
@Override
public void onRemoteStream(MediaStream stream) {
stream.videoTracks.get(0).addRenderer(new VideoRenderer(renderer));
}
@Override
public void onDataOpen(Object data) {
}
@Override
public void onData(Object data) {
}
@Override
public void onCleanup() {
}
@Override
public void onDetached() {
}
@Override
public JanusSupportedPluginPackages getPlugin() {
return JanusSupportedPluginPackages.JANUS_VIDEO_ROOM;
}
@Override
public void onCallbackError(String error) {
}
}
public class JanusPublisherPluginCallbacks implements IJanusPluginCallbacks {
private void publishOwnFeed() {
if(handle != null) {
handle.createOffer(new IPluginHandleWebRTCCallbacks() {
@Override
public void onSuccess(JSONObject obj) {
try
{
JSONObject msg = new JSONObject();
JSONObject body = new JSONObject();
body.put(REQUEST, "configure");
body.put("audio", true);
body.put("video", true);
msg.put(MESSAGE, body);
msg.put("jsep", obj);
handle.sendMessage(new PluginHandleSendMessageCallbacks(msg));
}catch (Exception ex) {
}
}
@Override
public JSONObject getJsep() {
return null;
}
@Override
public JanusMediaConstraints getMedia() {
JanusMediaConstraints cons = new JanusMediaConstraints();
cons.setRecvAudio(false);
cons.setRecvVideo(false);
cons.setSendAudio(true);
return cons;
}
@Override
public Boolean getTrickle() {
return true;
}
@Override
public void onCallbackError(String error) {
}
});
}
}
private void registerUsername() {
if(handle != null) {
JSONObject obj = new JSONObject();
JSONObject msg = new JSONObject();
try
{
obj.put(REQUEST, "join");
obj.put("room", roomid);
obj.put("ptype", "publisher");
obj.put("display", user_name);
msg.put(MESSAGE, obj);
}
catch(Exception ex)
{
}
handle.sendMessage(new PluginHandleSendMessageCallbacks(msg));
}
}
private void newRemoteFeed(BigInteger id) { //todo attach the plugin as a listener
VideoRenderer.Callbacks myrenderer;
if(!remoteRenderers.containsKey(id))
{
if(availableRemoteRenderers.isEmpty())
{
//TODO no more space
return;
}
remoteRenderers.put(id, availableRemoteRenderers.pop());
}
myrenderer = remoteRenderers.get(id);
janusServer.Attach(new ListenerAttachCallbacks(id, myrenderer));
}
@Override
public void success(JanusPluginHandle pluginHandle) {
handle = pluginHandle;
registerUsername();
}
@Override
public void onMessage(JSONObject msg, JSONObject jsepLocal) {
try
{
String event = msg.getString("videoroom");
if(event.equals("joined")) {
myid = new BigInteger(msg.getString("id"));
publishOwnFeed();
if(msg.has(PUBLISHERS)){
JSONArray pubs = msg.getJSONArray(PUBLISHERS);
for(int i = 0; i < pubs.length(); i++) {
JSONObject pub = pubs.getJSONObject(i);
BigInteger tehId = new BigInteger(pub.getString("id"));
newRemoteFeed(tehId);
}
}
} else if(event.equals("destroyed")) {
} else if(event.equals("event")) {
if(msg.has(PUBLISHERS)){
JSONArray pubs = msg.getJSONArray(PUBLISHERS);
for(int i = 0; i < pubs.length(); i++) {
JSONObject pub = pubs.getJSONObject(i);
newRemoteFeed(new BigInteger(pub.getString("id")));
}
} else if(msg.has("leaving")) {
} else if(msg.has("unpublished")) {
} else {
//todo error
}
}
if(jsepLocal != null) {
handle.handleRemoteJsep(new PluginHandleWebRTCCallbacks(null, jsepLocal, false));
}
}
catch (Exception ex)
{
}
}
@Override
public void onLocalStream(MediaStream stream) {
stream.videoTracks.get(0).addRenderer(new VideoRenderer(localRender));
}
@Override
public void onRemoteStream(MediaStream stream) {
}
@Override
public void onDataOpen(Object data) {
}
@Override
public void onData(Object data) {
}
@Override
public void onCleanup() {
}
@Override
public JanusSupportedPluginPackages getPlugin() {
return JanusSupportedPluginPackages.JANUS_VIDEO_ROOM;
}
@Override
public void onCallbackError(String error) {
}
@Override
public void onDetached() {
}
}
public class JanusGlobalCallbacks implements IJanusGatewayCallbacks {
public void onSuccess() {
janusServer.Attach(new JanusPublisherPluginCallbacks());
}
@Override
public void onDestroy() {
}
@Override
public String getServerUri() {
return JANUS_URI;
}
@Override
public List<PeerConnection.IceServer> getIceServers() {
return new ArrayList<PeerConnection.IceServer>();
}
@Override
public Boolean getIpv6Support() {
return Boolean.FALSE;
}
@Override
public Integer getMaxPollEvents() {
return 0;
}
@Override
public void onCallbackError(String error) {
}
}
public boolean initializeMediaContext(Context context, boolean audio, boolean video, boolean videoHwAcceleration, EGLContext eglContext){
return janusServer.initializeMediaContext(context, audio, video, videoHwAcceleration, eglContext);
}
public void Start() {
janusServer.Connect();
}
}