You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openmeetings.apache.org by so...@apache.org on 2015/02/03 18:22:30 UTC
svn commit: r1656837 - in /openmeetings:
branches/3.0.x/src/main/java/org/apache/openmeetings/remote/
branches/3.0.x/src/main/java/org/apache/openmeetings/remote/red5/
branches/3.0.x/src/screenshare/java/org/apache/openmeetings/screen/webstart/
trunk/s...
Author: solomax
Date: Tue Feb 3 17:22:29 2015
New Revision: 1656837
URL: http://svn.apache.org/r1656837
Log:
[OPENMEETINGS-1154] screen-sharing app is refactored to work without delays
Modified:
openmeetings/branches/3.0.x/src/main/java/org/apache/openmeetings/remote/FLVRecorderService.java
openmeetings/branches/3.0.x/src/main/java/org/apache/openmeetings/remote/red5/ScopeApplicationAdapter.java
openmeetings/branches/3.0.x/src/screenshare/java/org/apache/openmeetings/screen/webstart/CaptureScreen.java
openmeetings/branches/3.0.x/src/screenshare/java/org/apache/openmeetings/screen/webstart/CoreScreenShare.java
openmeetings/branches/3.0.x/src/screenshare/java/org/apache/openmeetings/screen/webstart/IScreenShare.java
openmeetings/trunk/singlewebapp/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/FLVRecorderService.java
openmeetings/trunk/singlewebapp/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java
openmeetings/trunk/singlewebapp/openmeetings-screenshare/src/main/java/org/apache/openmeetings/screen/webstart/CaptureScreen.java
openmeetings/trunk/singlewebapp/openmeetings-screenshare/src/main/java/org/apache/openmeetings/screen/webstart/CoreScreenShare.java
openmeetings/trunk/singlewebapp/openmeetings-screenshare/src/main/java/org/apache/openmeetings/screen/webstart/IScreenShare.java
Modified: openmeetings/branches/3.0.x/src/main/java/org/apache/openmeetings/remote/FLVRecorderService.java
URL: http://svn.apache.org/viewvc/openmeetings/branches/3.0.x/src/main/java/org/apache/openmeetings/remote/FLVRecorderService.java?rev=1656837&r1=1656836&r2=1656837&view=diff
==============================================================================
--- openmeetings/branches/3.0.x/src/main/java/org/apache/openmeetings/remote/FLVRecorderService.java (original)
+++ openmeetings/branches/3.0.x/src/main/java/org/apache/openmeetings/remote/FLVRecorderService.java Tue Feb 3 17:22:29 2015
@@ -98,12 +98,11 @@ public class FLVRecorderService implemen
return "rec_" + flvRecording_id + "_stream_" + streamid + "_" + dateString;
}
- public String recordMeetingStream(IConnection current, String roomRecordingName, String comment, Boolean isInterview) {
+ public String recordMeetingStream(IConnection current, Client client, String roomRecordingName, String comment, Boolean isInterview) {
try {
log.debug("##REC:: recordMeetingStream ::");
- Client currentClient = sessionManager.getClientByStreamId(current.getClient().getId(), null);
- Long room_id = currentClient.getRoom_id();
+ Long room_id = client.getRoom_id();
Date now = new Date();
@@ -111,7 +110,7 @@ public class FLVRecorderService implemen
flvRecording.setFileHash("");
flvRecording.setFileName(roomRecordingName);
- flvRecording.setInsertedBy(currentClient.getUser_id());
+ flvRecording.setInsertedBy(client.getUser_id());
flvRecording.setFolder(false);
flvRecording.setIsImage(false);
flvRecording.setIsPresentation(false);
@@ -122,20 +121,20 @@ public class FLVRecorderService implemen
flvRecording.setRoom_id(room_id);
flvRecording.setRecordStart(now);
- flvRecording.setWidth(currentClient.getVWidth());
- flvRecording.setHeight(currentClient.getVHeight());
+ flvRecording.setWidth(client.getVWidth());
+ flvRecording.setHeight(client.getVHeight());
- flvRecording.setOwnerId(currentClient.getUser_id());
+ flvRecording.setOwnerId(client.getUser_id());
flvRecording.setStatus(FlvRecording.Status.RECORDING);
flvRecording = recordingDao.update(flvRecording);
// Receive flvRecordingId
Long flvRecordingId = flvRecording.getFlvRecordingId();
- log.debug("##REC:: recording created by USER: " + currentClient.getUser_id());
+ log.debug("##REC:: recording created by USER: " + client.getUser_id());
// Update Client and set Flag
- currentClient.setIsRecording(true);
- currentClient.setFlvRecordingId(flvRecordingId);
- sessionManager.updateClientByStreamId(current.getClient().getId(), currentClient, false, null);
+ client.setIsRecording(true);
+ client.setFlvRecordingId(flvRecordingId);
+ sessionManager.updateClientByStreamId(client.getStreamid(), client, false, null);
// get all stream and start recording them
for (IConnection conn : current.getScope().getClientConnections()) {
@@ -145,7 +144,7 @@ public class FLVRecorderService implemen
// Send every user a notification that the recording did start
if (!rcl.getIsAVClient()) {
- ((IServiceCapableConnection) conn).invoke("startedRecording", new Object[] { currentClient }, this);
+ ((IServiceCapableConnection) conn).invoke("startedRecording", new Object[] { client }, this);
}
// If its the recording client we need another type of Meta Data
Modified: openmeetings/branches/3.0.x/src/main/java/org/apache/openmeetings/remote/red5/ScopeApplicationAdapter.java
URL: http://svn.apache.org/viewvc/openmeetings/branches/3.0.x/src/main/java/org/apache/openmeetings/remote/red5/ScopeApplicationAdapter.java?rev=1656837&r1=1656836&r2=1656837&view=diff
==============================================================================
--- openmeetings/branches/3.0.x/src/main/java/org/apache/openmeetings/remote/red5/ScopeApplicationAdapter.java (original)
+++ openmeetings/branches/3.0.x/src/main/java/org/apache/openmeetings/remote/red5/ScopeApplicationAdapter.java Tue Feb 3 17:22:29 2015
@@ -152,42 +152,59 @@ public class ScopeApplicationAdapter ext
public boolean roomConnect(IConnection conn, Object[] params) {
log.debug("roomConnect : ");
- try {
+ IServiceCapableConnection service = (IServiceCapableConnection) conn;
+ String streamId = conn.getClient().getId();
+
+ boolean isAVClient = params.length == 1 ? Boolean.valueOf("" + params[0]) : false;
- IServiceCapableConnection service = (IServiceCapableConnection) conn;
- String streamId = conn.getClient().getId();
-
- boolean isAVClient = false;
- if (params.length == 1) {
- isAVClient = Boolean.valueOf("" + params[0]);
- }
+ log.debug("### Client connected to OpenMeetings, register Client StreamId: " + streamId + " scope "
+ + conn.getScope().getName() + " isAVClient " + isAVClient);
- log.debug("### Client connected to OpenMeetings, register Client StreamId: " + streamId + " scope "
- + conn.getScope().getName() + " isAVClient " + isAVClient);
+ // Set StreamId in Client
+ service.invoke("setId", new Object[] { streamId }, this);
- // Set StreamId in Client
- service.invoke("setId", new Object[] { streamId }, this);
+ Map<String, Object> map = conn.getConnectParams();
+ String swfURL = map.containsKey("swfUrl") ? (String)map.get("swfUrl") : "";
- String swfURL = "";
- if (conn.getConnectParams().get("swfUrl") != null) {
- swfURL = conn.getConnectParams().get("swfUrl").toString();
+ //TODO add similar code for other connections
+ if (map.containsKey("screenClient")) {
+ String parentSid = (String)map.get("parentSid");
+ Client parentClient = sessionManager.getClientByPublicSID(parentSid, false, null);
+ if (parentClient == null) {
+ rejectClient();
}
-
- Client rcm = sessionManager.addClientListItem(streamId,
- conn.getScope().getName(), conn.getRemotePort(),
- conn.getRemoteAddress(), swfURL, isAVClient, null);
+ }
+ Client rcm = sessionManager.addClientListItem(conn.getClient().getId(),
+ conn.getScope().getName(), conn.getRemotePort(),
+ conn.getRemoteAddress(), swfURL, isAVClient, null);
+
+ SessionVariablesUtil.initClient(conn.getClient(), isAVClient, rcm.getPublicSID());
+ //TODO add similar code for other connections, merge with above block
+ if (map.containsKey("screenClient")) {
+ //TODO add check for room rights
+ String parentSid = (String)map.get("parentSid");
+ rcm.setRoom_id(Long.parseLong(conn.getScope().getName()));
+ rcm.setIsScreenClient(true);
+ SessionVariablesUtil.setIsScreenClient(conn.getClient());
- SessionVariablesUtil.initClient(conn.getClient(), isAVClient, rcm.getPublicSID());
+ rcm.setUser_id(((Integer)map.get("userId")).longValue());
+ SessionVariablesUtil.setUserId(conn.getClient(), rcm.getUser_id());
- // Log the User
- conferenceLogDao.addConferenceLog("ClientConnect",
- rcm.getUser_id(), streamId, null, rcm.getUserip(),
- rcm.getScope(), rcm.getExternalUserId(),
- rcm.getExternalUserType(), rcm.getEmail(),
- rcm.getFirstname(), rcm.getLastname());
- } catch (Exception err) {
- log.error("roomJoin", err);
- }
+ rcm.setStreamPublishName(parentSid);
+ User u = usersDao.get(rcm.getUser_id());
+ rcm.setUsername(u.getLogin());
+ rcm.setFirstname(u.getFirstname());
+ rcm.setLastname(u.getLastname());
+ log.debug("publishName :: " + rcm.getStreamPublishName());
+ sessionManager.updateClientByStreamId(streamId, rcm, false, null);
+ }
+
+ // Log the User
+ conferenceLogDao.addConferenceLog("ClientConnect",
+ rcm.getUser_id(), streamId, null, rcm.getUserip(),
+ rcm.getScope(), rcm.getExternalUserId(),
+ rcm.getExternalUserType(), rcm.getEmail(),
+ rcm.getFirstname(), rcm.getLastname());
return true;
}
@@ -196,44 +213,45 @@ public class ScopeApplicationAdapter ext
log.debug("----------- screenSharerAction ENTER");
IConnection current = Red5.getConnectionLocal();
- Client rc = sessionManager.getClientByStreamId(current.getClient().getId(), null);
+ Client control = sessionManager.getClientByStreamId(current.getClient().getId(), null);
+ Client client = sessionManager.getClientByPublicSID(control.getStreamPublishName(), false, null);
Map<String, String> returnMap = new HashMap<String, String>();
- if (rc != null) {
+ if (client != null) {
boolean changed = false;
- if (Boolean.valueOf("" + map.get("stopStreaming")) && rc.isStartStreaming()) {
+ if (Boolean.valueOf("" + map.get("stopStreaming")) && client.isStartStreaming()) {
changed = true;
- rc.setStartStreaming(false);
+ client.setStartStreaming(false);
//Send message to all users
- sendMessageToCurrentScope("stopScreenSharingMessage", rc, false);
+ sendMessageToCurrentScope("stopScreenSharingMessage", client, false);
returnMap.put("result", "stopSharingOnly");
}
- if (Boolean.valueOf("" + map.get("stopRecording")) && rc.getIsRecording()) {
+ if (Boolean.valueOf("" + map.get("stopRecording")) && client.getIsRecording()) {
changed = true;
- rc.setStartRecording(false);
- rc.setIsRecording(false);
+ client.setStartRecording(false);
+ client.setIsRecording(false);
returnMap.put("result", "stopRecordingOnly");
//Send message to all users
- sendMessageToCurrentScope("stopRecordingMessage", rc, false);
+ sendMessageToCurrentScope("stopRecordingMessage", client, false);
- flvRecorderService.stopRecordAndSave(current.getScope(), rc, null);
+ flvRecorderService.stopRecordAndSave(current.getScope(), client, null);
}
- if (Boolean.valueOf("" + map.get("stopPublishing")) && rc.isScreenPublishStarted()) {
+ if (Boolean.valueOf("" + map.get("stopPublishing")) && client.isScreenPublishStarted()) {
changed = true;
- rc.setScreenPublishStarted(false);
+ client.setScreenPublishStarted(false);
returnMap.put("result", "stopPublishingOnly");
//Send message to all users
- sendMessageToCurrentScope("stopPublishingMessage", rc, false);
+ sendMessageToCurrentScope("stopPublishingMessage", client, false);
}
if (changed) {
- sessionManager.updateClientByStreamId(rc.getStreamid(), rc, false, null);
+ sessionManager.updateClientByStreamId(client.getStreamid(), client, false, null);
- if (!rc.isStartStreaming() && !rc.isStartRecording() && !rc.isStreamPublishStarted()) {
+ if (!client.isStartStreaming() && !client.isStartRecording() && !client.isStreamPublishStarted()) {
returnMap.put("result", "stopAll");
}
}
@@ -277,75 +295,50 @@ public class ScopeApplicationAdapter ext
* @return returns key,value Map with multiple return values or null in case of exception
*
*/
- @SuppressWarnings({ "rawtypes", "unchecked" })
- public Map setConnectionAsSharingClient(Map map) {
+ public Map<String, Object> setConnectionAsSharingClient(Map<String, Object> map) {
try {
log.debug("----------- setConnectionAsSharingClient");
IConnection current = Red5.getConnectionLocal();
- Client currentClient = sessionManager.getClientByStreamId(current.getClient().getId(), null);
+ Client control = sessionManager.getClientByStreamId(current.getClient().getId(), null);
+ Client client = sessionManager.getClientByPublicSID(control.getStreamPublishName(), false, null);
- if (currentClient != null) {
+ if (client != null) {
boolean startRecording = Boolean.valueOf("" + map.get("startRecording"));
boolean startStreaming = Boolean.valueOf("" + map.get("startStreaming"));
- boolean startPublishing = Boolean.valueOf("" + map.get("startPublishing"))
- && (0 == sessionManager.getPublishingCount(currentClient.getRoom_id()));
-
- currentClient.setRoom_id(Long.parseLong(current.getScope().getName()));
-
- // Set this connection to be a RTMP-Java Client
- currentClient.setIsScreenClient(true);
-
- SessionVariablesUtil.setIsScreenClient(current.getClient());
-
- currentClient.setUser_id(Long.parseLong(map.get("user_id").toString()));
- SessionVariablesUtil.setUserId(current.getClient(), Long.parseLong(map.get("user_id").toString()));
+ boolean startPublishing = Boolean.valueOf("" + map.get("startPublishing")) && (0 == sessionManager.getPublishingCount(client.getRoom_id()));
- boolean alreadyStreaming = currentClient.isStartStreaming();
+ boolean alreadyStreaming = client.isStartStreaming();
if (startStreaming) {
- currentClient.setStartStreaming(true);
+ client.setStartStreaming(true);
}
- boolean alreadyRecording = currentClient.isStartRecording();
+ boolean alreadyRecording = client.isStartRecording();
if (startRecording) {
- currentClient.setStartRecording(true);
+ client.setStartRecording(true);
}
if (startPublishing) {
- currentClient.setStreamPublishStarted(true);
+ client.setStreamPublishStarted(true);
}
- sessionManager.updateClientByStreamId(current.getClient().getId(), currentClient, false, null);
+ client.setVX(Integer.parseInt(map.get("screenX").toString()));
+ client.setVY(Integer.parseInt(map.get("screenY").toString()));
+ client.setVWidth(Integer.parseInt(map.get("screenWidth").toString()));
+ client.setVHeight(Integer.parseInt(map.get("screenHeight").toString()));
+ sessionManager.updateClientByStreamId(current.getClient().getId(), client, false, null);
- Map returnMap = new HashMap();
+ Map<String, Object> returnMap = new HashMap<String, Object>();
returnMap.put("alreadyPublished", false);
// if is already started screen sharing, then there is no need
// to start it again
- if (currentClient.isScreenPublishStarted()) {
+ if (client.isScreenPublishStarted()) {
returnMap.put("alreadyPublished", true);
}
- currentClient.setVX(Integer.parseInt(map.get("screenX").toString()));
- currentClient.setVY(Integer.parseInt(map.get("screenY").toString()));
- currentClient.setVWidth(Integer.parseInt(map.get("screenWidth").toString()));
- currentClient.setVHeight(Integer.parseInt(map.get("screenHeight").toString()));
-
- log.debug("screen x,y,width,height " + currentClient.getVX()
- + " " + currentClient.getVY() + " "
- + currentClient.getVWidth() + " "
- + currentClient.getVHeight());
-
- log.debug("publishName :: " + map.get("publishName"));
-
- currentClient.setStreamPublishName(map.get("publishName").toString());
-
- Client currentScreenUser = sessionManager.getClientByPublicSID(currentClient.getStreamPublishName(), false, null);
-
- currentClient.setFirstname(currentScreenUser.getFirstname());
- currentClient.setLastname(currentScreenUser.getLastname());
-
- // This is duplicated, but its not sure that in the meantime
- // somebody requests this Client Object Info
- sessionManager.updateClientByStreamId(current.getClient().getId(), currentClient, false, null);
+ log.debug("screen x,y,width,height " + client.getVX()
+ + " " + client.getVY() + " "
+ + client.getVWidth() + " "
+ + client.getVHeight());
if (startStreaming) {
if (!alreadyStreaming) {
@@ -354,9 +347,9 @@ public class ScopeApplicationAdapter ext
log.debug("start streamPublishStart Is Screen Sharing ");
//Send message to all users
- sendMessageToCurrentScope("newScreenSharing", currentClient, false);
+ sendMessageToCurrentScope("newScreenSharing", client, false);
} else {
- log.warn("Streaming is already started for the client id=" + currentClient.getId() + ". Second request is ignored.");
+ log.warn("Streaming is already started for the client id=" + client.getId() + ". Second request is ignored.");
}
}
if (startRecording) {
@@ -365,17 +358,16 @@ public class ScopeApplicationAdapter ext
String recordingName = "Recording " + CalendarPatterns.getDateWithTimeByMiliSeconds(new Date());
- flvRecorderService.recordMeetingStream(current, recordingName, "", false);
+ flvRecorderService.recordMeetingStream(current, client, recordingName, "", false);
} else {
- log.warn("Recording is already started for the client id=" + currentClient.getId() + ". Second request is ignored.");
+ log.warn("Recording is already started for the client id=" + client.getId() + ". Second request is ignored.");
}
}
if (startPublishing) {
- sendMessageToCurrentScope("startedPublishing", new Object[]{currentClient, "rtmp://" + map.get("publishingHost") + ":1935/"
+ sendMessageToCurrentScope("startedPublishing", new Object[]{client, "rtmp://" + map.get("publishingHost") + ":1935/"
+ map.get("publishingApp") + "/" + map.get("publishingId")}, false, true);
returnMap.put("modus", "startPublishing");
}
-
return returnMap;
} else {
@@ -836,10 +828,8 @@ public class ScopeApplicationAdapter ext
@SuppressWarnings("unchecked")
public void setNewCursorPosition(Object item) {
try {
-
IConnection current = Red5.getConnectionLocal();
- String streamid = current.getClient().getId();
- Client currentClient = sessionManager.getClientByStreamId(streamid, null);
+ Client currentClient = sessionManager.getClientByStreamId(current.getClient().getId(), null);
@SuppressWarnings("rawtypes")
Map cursor = (Map) item;
@@ -1813,7 +1803,10 @@ public class ScopeApplicationAdapter ext
@Override
public void run() {
try {
- if (scope != null) {
+ if (scope == null) {
+ log.debug(String.format("[MessageSender] -> 'Unable to send message to NULL scope' %s, %s", remoteMethodName, newMessage));
+ } else {
+ log.trace(String.format("[MessageSender] -> 'sending message' %s, %s", remoteMethodName, newMessage));
// Send to all Clients of that Scope(Room)
for (IConnection conn : scope.getClientConnections()) {
if (conn != null && conn instanceof IServiceCapableConnection) {
@@ -1823,9 +1816,10 @@ public class ScopeApplicationAdapter ext
((IServiceCapableConnection) conn).invoke(remoteMethodName, new Object[] { newMessage }, ScopeApplicationAdapter.this);
}
}
+ log.trace(String.format("[MessageSender] -> 'sending message DONE' %s", remoteMethodName));
}
} catch (Exception err) {
- log.error(String.format("[sendMessageToCurrentScope -> %s, %s]", remoteMethodName, newMessage), err);
+ log.error(String.format("[MessageSender -> %s, %s]", remoteMethodName, newMessage), err);
}
}
}
@@ -2132,7 +2126,7 @@ public class ScopeApplicationAdapter ext
}
String recordingName = "Interview " + CalendarPatterns.getDateWithTimeByMiliSeconds(new Date());
- flvRecorderService.recordMeetingStream(current, recordingName, "", true);
+ flvRecorderService.recordMeetingStream(current, current_rcl, recordingName, "", true);
return true;
} catch (Exception err) {
@@ -2142,24 +2136,15 @@ public class ScopeApplicationAdapter ext
}
@SuppressWarnings({ "rawtypes" })
- public Boolean sendRemoteCursorEvent(String streamid, Map messageObj) {
- try {
-
- IConnection current = Red5.getConnectionLocal();
-
- for (IConnection conn : current.getScope().getClientConnections()) {
- if (conn != null) {
- IClient client = conn.getClient();
- if (SessionVariablesUtil.isScreenClient(client)) {
- if (conn.getClient().getId().equals(streamid)) {
- ((IServiceCapableConnection) conn).invoke("sendRemoteCursorEvent", new Object[] { messageObj }, this);
- }
- }
- }
+ public Boolean sendRemoteCursorEvent(final String streamid, Map messageObj) {
+ new MessageSender("sendRemoteCursorEvent", messageObj) {
+
+ @Override
+ public boolean filter(IConnection conn) {
+ IClient client = conn.getClient();
+ return SessionVariablesUtil.isScreenClient(client) && conn.getClient().getId().equals(streamid);
}
- } catch (Exception err) {
- log.debug("[sendRemoteCursorEvent]", err);
- }
+ }.start();
return null;
}
Modified: openmeetings/branches/3.0.x/src/screenshare/java/org/apache/openmeetings/screen/webstart/CaptureScreen.java
URL: http://svn.apache.org/viewvc/openmeetings/branches/3.0.x/src/screenshare/java/org/apache/openmeetings/screen/webstart/CaptureScreen.java?rev=1656837&r1=1656836&r2=1656837&view=diff
==============================================================================
--- openmeetings/branches/3.0.x/src/screenshare/java/org/apache/openmeetings/screen/webstart/CaptureScreen.java (original)
+++ openmeetings/branches/3.0.x/src/screenshare/java/org/apache/openmeetings/screen/webstart/CaptureScreen.java Tue Feb 3 17:22:29 2015
@@ -30,9 +30,6 @@ import java.awt.Rectangle;
import java.awt.Robot;
import java.io.IOException;
import java.util.concurrent.ArrayBlockingQueue;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
@@ -41,7 +38,9 @@ import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
+import org.quartz.JobKey;
import org.quartz.Scheduler;
+import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
@@ -54,7 +53,9 @@ import org.slf4j.Logger;
class CaptureScreen extends Thread {
private static final Logger log = getLogger(CaptureScreen.class);
- private static final int NANO_MULTIPLIER = 1000 * 1000;
+ private final static String QUARTZ_GROUP_NAME = "ScreenShare";
+ private final static String QUARTZ_CURSOR_TRIGGER_NAME = "CursorTrigger";
+ private final static String QUARTZ_CURSOR_JOB_NAME = "CursorJob";
private CoreScreenShare core;
private int timeBetweenFrames;
private volatile int timestamp = 0;
@@ -68,8 +69,6 @@ class CaptureScreen extends Thread {
private int port = -1;
private int streamId;
private boolean startPublish = false;
- private boolean sendCursor = false;
- private final ScheduledExecutorService cursorScheduler = Executors.newScheduledThreadPool(1);
private Scheduler scheduler;
public CaptureScreen(CoreScreenShare coreScreenShare, IScreenShare client, String host, String app, int port) {
@@ -78,6 +77,12 @@ class CaptureScreen extends Thread {
this.host = host;
this.app = app;
this.port = port;
+ SchedulerFactory sf = new StdSchedulerFactory();
+ try {
+ scheduler = sf.getScheduler();
+ } catch (SchedulerException e) {
+ log.error("Unexpected error while creating scheduler", e);
+ }
}
public void release() {
@@ -89,11 +94,6 @@ class CaptureScreen extends Thread {
} catch (Exception e) {
log.error("Unexpected error while shutting down scheduler", e);
}
- try {
- cursorScheduler.shutdownNow();
- } catch (Exception e) {
- log.error("Unexpected error while shutting down scheduler", e);
- }
active = false;
timestamp = 0;
timeCaptureStarted = 0;
@@ -109,32 +109,22 @@ class CaptureScreen extends Thread {
se = new ScreenV1Encoder(3 * FPS); //send keyframe every 3 seconds
timeCaptureStarted = System.currentTimeMillis();
- JobDetail encodeJob = JobBuilder.newJob(EncodeJob.class).withIdentity("EncodeJob", "ScreenShare").build();
+ JobDetail encodeJob = JobBuilder.newJob(EncodeJob.class).withIdentity("EncodeJob", QUARTZ_GROUP_NAME).build();
encodeJob.getJobDataMap().put(EncodeJob.CAPTURE_KEY, this);
Trigger encodeTrigger = TriggerBuilder.newTrigger()
- .withIdentity("EncodeTrigger", "ScreenShare")
+ .withIdentity("EncodeTrigger", QUARTZ_GROUP_NAME)
.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInMilliseconds(timeBetweenFrames).repeatForever())
.build();
- JobDetail sendJob = JobBuilder.newJob(SendJob.class).withIdentity("SendJob", "ScreenShare").build();
+ JobDetail sendJob = JobBuilder.newJob(SendJob.class).withIdentity("SendJob", QUARTZ_GROUP_NAME).build();
Trigger sendTrigger = TriggerBuilder.newTrigger()
- .withIdentity("SendTrigger", "ScreenShare")
+ .withIdentity("SendTrigger", QUARTZ_GROUP_NAME)
.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInMilliseconds(timeBetweenFrames).repeatForever())
.build();
sendJob.getJobDataMap().put(SendJob.CAPTURE_KEY, this);
- SchedulerFactory sf = new StdSchedulerFactory();
- scheduler = sf.getScheduler();
scheduler.scheduleJob(encodeJob, encodeTrigger);
scheduler.scheduleJob(sendJob, sendTrigger);
scheduler.start();
-
- if (sendCursor) {
- cursorScheduler.scheduleWithFixedDelay(new Runnable() {
- public void run() {
- core.sendCursorStatus();
- }
- }, 0, timeBetweenFrames * NANO_MULTIPLIER, TimeUnit.NANOSECONDS);
- }
} catch (Exception e) {
log.error("Error while running: ", e);
}
@@ -229,6 +219,20 @@ class CaptureScreen extends Thread {
}
}
+ @DisallowConcurrentExecution
+ public static class CursorJob implements Job {
+ private static final String CAPTURE_KEY = "capture";
+
+ public CursorJob() {}
+
+ @Override
+ public void execute(JobExecutionContext context) throws JobExecutionException {
+ JobDataMap data = context.getJobDetail().getJobDataMap();
+ CaptureScreen capture = (CaptureScreen)data.get(CAPTURE_KEY);
+ capture.core.sendCursorStatus();
+ }
+ }
+
private void pushVideo(VideoData data, int ts) throws IOException {
if (startPublish) {
if (Red5.getConnectionLocal() == null) {
@@ -264,6 +268,20 @@ class CaptureScreen extends Thread {
}
public void setSendCursor(boolean sendCursor) {
- this.sendCursor = sendCursor;
+ try {
+ if (sendCursor) {
+ JobDetail cursorJob = JobBuilder.newJob(CursorJob.class).withIdentity(QUARTZ_CURSOR_JOB_NAME, QUARTZ_GROUP_NAME).build();
+ Trigger cursorTrigger = TriggerBuilder.newTrigger()
+ .withIdentity(QUARTZ_CURSOR_TRIGGER_NAME, QUARTZ_GROUP_NAME)
+ .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInMilliseconds(1000 / Math.min(2, FPS)).repeatForever())
+ .build();
+ cursorJob.getJobDataMap().put(CursorJob.CAPTURE_KEY, this);
+ scheduler.scheduleJob(cursorJob, cursorTrigger);
+ } else {
+ scheduler.deleteJob(JobKey.jobKey(QUARTZ_CURSOR_JOB_NAME, QUARTZ_GROUP_NAME));
+ }
+ } catch (SchedulerException e) {
+ log.error("Unexpected Error schedule/unschedule cursor job", e);
+ }
}
}
Modified: openmeetings/branches/3.0.x/src/screenshare/java/org/apache/openmeetings/screen/webstart/CoreScreenShare.java
URL: http://svn.apache.org/viewvc/openmeetings/branches/3.0.x/src/screenshare/java/org/apache/openmeetings/screen/webstart/CoreScreenShare.java?rev=1656837&r1=1656836&r2=1656837&view=diff
==============================================================================
--- openmeetings/branches/3.0.x/src/screenshare/java/org/apache/openmeetings/screen/webstart/CoreScreenShare.java (original)
+++ openmeetings/branches/3.0.x/src/screenshare/java/org/apache/openmeetings/screen/webstart/CoreScreenShare.java Tue Feb 3 17:22:29 2015
@@ -63,6 +63,7 @@ public class CoreScreenShare implements
rtmp, rtmpt, rtmpe, rtmps
}
private IScreenShare instance = null;
+ private IScreenShare controlInstance = null;
private Protocol protocol;
private String host;
private String app;
@@ -79,7 +80,7 @@ public class CoreScreenShare implements
public boolean showFPS = true;
public boolean allowRemote = true;
- public Long user_id = null;
+ public Long userId = null;
private boolean allowRecording = true;
private boolean allowPublishing = true;
@@ -118,7 +119,7 @@ public class CoreScreenShare implements
host = args[1];
port = Integer.parseInt(args[2]);
app = args[3];
- user_id = Long.parseLong(args[4]);
+ userId = Long.parseLong(args[4]);
publishName = args[5];
String labelTexts = args[6];
defaultQuality = Integer.parseInt(args[7]);
@@ -143,21 +144,28 @@ public class CoreScreenShare implements
switch (protocol) {
case rtmp:
instance = new RTMPScreenShare(this);
+ controlInstance = new RTMPScreenShare(this);
break;
case rtmpt:
instance = new RTMPTScreenShare(this);
+ controlInstance = new RTMPTScreenShare(this);
break;
case rtmps:
RTMPSScreenShare client = new RTMPSScreenShare(this);
client.setKeystoreBytes(Hex.decodeHex(args[13].toCharArray()));
client.setKeyStorePassword(args[14]);
instance = client;
+ RTMPSScreenShare controlClient = new RTMPSScreenShare(this);
+ controlClient.setKeystoreBytes(Hex.decodeHex(args[13].toCharArray()));
+ controlClient.setKeyStorePassword(args[14]);
+ controlInstance = controlClient;
break;
case rtmpe:
default:
throw new Exception("Unsupported protocol");
}
- instance.setServiceProvider(instance);
+ instance.setServiceProvider(this);
+ controlInstance.setServiceProvider(this);
log.debug(String.format("host: %s, app: %s, port: %s, publish: %s", host, port, app, publishName));
} else {
System.exit(0);
@@ -190,7 +198,7 @@ public class CoreScreenShare implements
}
}
- synchronized public void sendCursorStatus() {
+ public void sendCursorStatus() {
try {
Point mouseP = MouseInfo.getPointerInfo().getLocation();
@@ -205,11 +213,11 @@ public class CoreScreenShare implements
cursorPosition.put("cursor_x", x);
cursorPosition.put("cursor_y", y);
- if (instance.getConnection() != null) {
+ if (controlInstance.getConnection() != null) {
if (Red5.getConnectionLocal() == null) {
- Red5.setConnectionLocal(instance.getConnection());
+ Red5.setConnectionLocal(controlInstance.getConnection());
}
- instance.invoke("setNewCursorPosition", new Object[] { cursorPosition }, this);
+ controlInstance.invoke("setNewCursorPosition", new Object[] { cursorPosition }, this);
}
} catch (NullPointerException npe) {
//noop
@@ -219,11 +227,13 @@ public class CoreScreenShare implements
}
}
- synchronized public void setConnectionAsSharingClient() {
+ public void setConnectionAsSharingClient() {
+ log.debug("########## setConnectionAsSharingClient");
try {
- log.debug("########## setConnectionAsSharingClient");
-
- Map<Object, Object> map = new HashMap<Object, Object>();
+ if (Red5.getConnectionLocal() == null) {
+ Red5.setConnectionLocal(controlInstance.getConnection());
+ }
+ Map<String, Object> map = new HashMap<String, Object>();
map.put("screenX", spinnerX);
map.put("screenY", spinnerY);
@@ -233,20 +243,16 @@ public class CoreScreenShare implements
map.put("screenWidth", scaledWidth);
map.put("screenHeight", scaledHeight);
- map.put("publishName", publishName);
map.put("startRecording", startRecording);
map.put("startStreaming", startStreaming);
map.put("startPublishing", startPublishing);
map.put("publishingHost", frame.getPublishHost());
map.put("publishingApp", frame.getPublishApp());
map.put("publishingId", frame.getPublishId());
-
- map.put("user_id", user_id);
-
if (Red5.getConnectionLocal() == null) {
- Red5.setConnectionLocal(instance.getConnection());
+ Red5.setConnectionLocal(controlInstance.getConnection());
}
- instance.invoke("setConnectionAsSharingClient", new Object[] { map }, this);
+ controlInstance.invoke("setConnectionAsSharingClient", new Object[] { map }, this);
} catch (Exception err) {
frame.setStatus("Error: " + err.getLocalizedMessage());
log.error("[setConnectionAsSharingClient]", err);
@@ -268,14 +274,21 @@ public class CoreScreenShare implements
captureScreenStart();
}
+ private void connect(String parentSid, boolean control) {
+ Map<String, Object> map = instance.makeDefaultConnectionParams(host, port, app);
+ map.put("screenClient", true);
+ map.put("userId", userId);
+ map.put("parentSid", parentSid);
+ (control ? controlInstance : instance).connect(host, port, map, this);
+ }
+
private void captureScreenStart() {
try {
log.debug("captureScreenStart");
if (!isConnected) {
- instance.connect(host, port, app, this);
- }
- if (isConnected) {
+ connect(publishName, false);
+ } else {
setConnectionAsSharingClient();
}
} catch (Exception err) {
@@ -307,9 +320,9 @@ public class CoreScreenShare implements
map.put(action, true);
if (Red5.getConnectionLocal() == null) {
- Red5.setConnectionLocal(instance.getConnection());
+ Red5.setConnectionLocal(controlInstance.getConnection());
}
- instance.invoke("screenSharerAction", new Object[] { map }, this);
+ controlInstance.invoke("screenSharerAction", new Object[] { map }, this);
} catch (Exception err) {
log.error("captureScreenStop Exception: ", err);
frame.setStatus("Exception: " + err);
@@ -382,6 +395,7 @@ public class CoreScreenShare implements
isConnected = false;
instance.disconnect();
+ controlInstance.disconnect();
setReadyToRecord(false);
getCapture().setStartPublish(false);
getCapture().release();
@@ -546,7 +560,7 @@ public class CoreScreenShare implements
String clientId = returnMap.get("clientId").toString();
- instance.invoke("sendMessageWithClientById", new Object[]{map, clientId}, this);
+ controlInstance.invoke("sendMessageWithClientById", new Object[]{map, clientId}, this);
} else if (action.equals("show")) {
String paste = getClipboardText();
@@ -556,10 +570,7 @@ public class CoreScreenShare implements
String clientId = returnMap.get("clientId").toString();
- // public synchronized int sendMessageWithClientById(Object
- // newMessage, String clientId)
-
- instance.invoke("sendMessageWithClientById", new Object[]{map, clientId}, this);
+ controlInstance.invoke("sendMessageWithClientById", new Object[]{map, clientId}, this);
}
} catch (Exception err) {
log.error("[sendRemoteCursorEvent]", err);
@@ -603,14 +614,14 @@ public class CoreScreenShare implements
}
}
- private String getHighlightedText(Robot instance) {
+ private String getHighlightedText(Robot robot) {
try {
if (System.getProperty("os.name").toUpperCase().indexOf("WINDOWS") >= 0) {
// pressing STRG+C == copy
- pressSequence(instance, 200, KeyEvent.VK_CONTROL, KeyEvent.VK_C, KeyEvent.VK_C, KeyEvent.VK_CONTROL);
+ pressSequence(robot, 200, KeyEvent.VK_CONTROL, KeyEvent.VK_C, KeyEvent.VK_C, KeyEvent.VK_CONTROL);
} else {
// Macintosh simulate Copy
- pressSequence(instance, 200, 157, 67, 67, 157);
+ pressSequence(robot, 200, 157, 67, 67, 157);
}
return getClipboardText();
} catch (Exception e) {
@@ -619,7 +630,7 @@ public class CoreScreenShare implements
return "";
}
- private void pressSpecialSign(String charValue, Robot instance) {
+ private void pressSpecialSign(String charValue, Robot robot) {
Clipboard clippy = getDefaultToolkit().getSystemClipboard();
try {
Transferable transferableText = new StringSelection(charValue);
@@ -627,10 +638,10 @@ public class CoreScreenShare implements
if (System.getProperty("os.name").toUpperCase().indexOf("WINDOWS") >= 0) {
// pressing STRG+V == insert-mode
- pressSequence(instance, 100, KeyEvent.VK_CONTROL, KeyEvent.VK_V, KeyEvent.VK_V, KeyEvent.VK_CONTROL);
+ pressSequence(robot, 100, KeyEvent.VK_CONTROL, KeyEvent.VK_V, KeyEvent.VK_V, KeyEvent.VK_CONTROL);
} else {
// Macintosh simulate Insert
- pressSequence(instance, 100, 157, 86, 86, 157);
+ pressSequence(robot, 100, 157, 86, 86, 157);
}
} catch (Exception e) {
log.error("Unexpected exception while pressSpecialSign", e);
@@ -640,17 +651,30 @@ public class CoreScreenShare implements
public void resultReceived(IPendingServiceCall call) {
try {
- log.trace( "service call result: " + call );
+ log.trace("service call result: " + call);
String method = call == null ? null : call.getServiceMethodName();
+ Object o = call == null ? null : call.getResult();
log.trace("call ### get Method Name " + method);
if ("connect".equals(method)) {
+ if (o instanceof Map) {
+ @SuppressWarnings("unchecked")
+ Map<String, Object> map = (Map<String, Object>) o;
+ Object code = map.get("code");
+ if ("NetConnection.Connect.Rejected".equals(code) || "NetConnection.Connect.Failed".equals(code)) {
+ frame.setStatus(String.format("Error: %s %s", code, map.get("description")));
+ return;
+ }
+ }
+ if (!isConnected) {
+ instance.invoke("getPublicSID", null, this);
+ } else {
+ setConnectionAsSharingClient();
+ }
isConnected = true;
- setConnectionAsSharingClient();
+ } else if ("getPublicSID".equals(method)) {
+ connect((String)o, true);
} else if ("setConnectionAsSharingClient".equals(method)) {
-
- Object o = call.getResult();
-
@SuppressWarnings("unchecked")
Map<String, Object> returnMap = (Map<String, Object>) o;
@@ -692,13 +716,15 @@ public class CoreScreenShare implements
log.debug("setup capture thread spinnerWidth = {}; spinnerHeight = {};", spinnerWidth, spinnerHeight);
- getCapture().setSendCursor(true);
- getCapture().start();
+ if (!getCapture().isAlive()) {
+ getCapture().setSendCursor(startStreaming);
+ getCapture().start();
+ }
}
} else if ("screenSharerAction".equals(method)) {
- Object o = call.getResult();
-
- log.trace("Result Map Type " + o.getClass().getName());
+ if (log.isTraceEnabled()) {
+ log.trace("Result Map Type " + (o == null ? null : o.getClass().getName()));
+ }
@SuppressWarnings("unchecked")
Map<String, Object> returnMap = (Map<String, Object>)o;
Modified: openmeetings/branches/3.0.x/src/screenshare/java/org/apache/openmeetings/screen/webstart/IScreenShare.java
URL: http://svn.apache.org/viewvc/openmeetings/branches/3.0.x/src/screenshare/java/org/apache/openmeetings/screen/webstart/IScreenShare.java?rev=1656837&r1=1656836&r2=1656837&view=diff
==============================================================================
--- openmeetings/branches/3.0.x/src/screenshare/java/org/apache/openmeetings/screen/webstart/IScreenShare.java (original)
+++ openmeetings/branches/3.0.x/src/screenshare/java/org/apache/openmeetings/screen/webstart/IScreenShare.java Tue Feb 3 17:22:29 2015
@@ -18,6 +18,8 @@
*/
package org.apache.openmeetings.screen.webstart;
+import java.util.Map;
+
import org.red5.client.net.rtmp.ClientExceptionHandler;
import org.red5.client.net.rtmp.INetStreamEventHandler;
import org.red5.server.api.service.IPendingServiceCallback;
@@ -27,7 +29,8 @@ import org.red5.server.net.rtmp.RTMPConn
public interface IScreenShare extends ClientExceptionHandler {
RTMPConnection getConnection();
void invoke(String method, Object[] params, IPendingServiceCallback callback);
- void connect(String server, int port, String application, IPendingServiceCallback connectCallback);
+ Map<String, Object> makeDefaultConnectionParams(String server, int port, String application);
+ void connect(String server, int port, Map<String, Object> connectionParams, IPendingServiceCallback connectCallback);
void setServiceProvider(Object serviceProvider);
void disconnect();
void createStream(IPendingServiceCallback callback);
Modified: openmeetings/trunk/singlewebapp/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/FLVRecorderService.java
URL: http://svn.apache.org/viewvc/openmeetings/trunk/singlewebapp/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/FLVRecorderService.java?rev=1656837&r1=1656836&r2=1656837&view=diff
==============================================================================
--- openmeetings/trunk/singlewebapp/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/FLVRecorderService.java (original)
+++ openmeetings/trunk/singlewebapp/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/FLVRecorderService.java Tue Feb 3 17:22:29 2015
@@ -99,12 +99,11 @@ public class FLVRecorderService implemen
return "rec_" + flvRecording_id + "_stream_" + streamid + "_" + dateString;
}
- public String recordMeetingStream(IConnection current, String roomRecordingName, String comment, Boolean isInterview) {
+ public String recordMeetingStream(IConnection current, Client client, String roomRecordingName, String comment, Boolean isInterview) {
try {
log.debug("##REC:: recordMeetingStream ::");
- Client currentClient = sessionManager.getClientByStreamId(current.getClient().getId(), null);
- Long room_id = currentClient.getRoom_id();
+ Long room_id = client.getRoom_id();
Date now = new Date();
@@ -112,7 +111,7 @@ public class FLVRecorderService implemen
flvRecording.setFileHash("");
flvRecording.setFileName(roomRecordingName);
- flvRecording.setInsertedBy(currentClient.getUser_id());
+ flvRecording.setInsertedBy(client.getUser_id());
flvRecording.setType(Type.Recording);
flvRecording.setComment(comment);
flvRecording.setIsInterview(isInterview);
@@ -120,20 +119,20 @@ public class FLVRecorderService implemen
flvRecording.setRoomId(room_id);
flvRecording.setRecordStart(now);
- flvRecording.setWidth(currentClient.getVWidth());
- flvRecording.setHeight(currentClient.getVHeight());
+ flvRecording.setWidth(client.getVWidth());
+ flvRecording.setHeight(client.getVHeight());
- flvRecording.setOwnerId(currentClient.getUser_id());
+ flvRecording.setOwnerId(client.getUser_id());
flvRecording.setStatus(FlvRecording.Status.RECORDING);
flvRecording = recordingDao.update(flvRecording);
// Receive flvRecordingId
Long flvRecordingId = flvRecording.getId();
- log.debug("##REC:: recording created by USER: " + currentClient.getUser_id());
+ log.debug("##REC:: recording created by USER: " + client.getUser_id());
// Update Client and set Flag
- currentClient.setIsRecording(true);
- currentClient.setFlvRecordingId(flvRecordingId);
- sessionManager.updateClientByStreamId(current.getClient().getId(), currentClient, false, null);
+ client.setIsRecording(true);
+ client.setFlvRecordingId(flvRecordingId);
+ sessionManager.updateClientByStreamId(client.getStreamid(), client, false, null);
// get all stream and start recording them
for (IConnection conn : current.getScope().getClientConnections()) {
@@ -143,7 +142,7 @@ public class FLVRecorderService implemen
// Send every user a notification that the recording did start
if (!rcl.isAvClient()) {
- ((IServiceCapableConnection) conn).invoke("startedRecording", new Object[] { currentClient }, this);
+ ((IServiceCapableConnection) conn).invoke("startedRecording", new Object[] { client }, this);
}
// If its the recording client we need another type of Meta Data
Modified: openmeetings/trunk/singlewebapp/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java
URL: http://svn.apache.org/viewvc/openmeetings/trunk/singlewebapp/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java?rev=1656837&r1=1656836&r2=1656837&view=diff
==============================================================================
--- openmeetings/trunk/singlewebapp/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java (original)
+++ openmeetings/trunk/singlewebapp/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java Tue Feb 3 17:22:29 2015
@@ -143,42 +143,59 @@ public class ScopeApplicationAdapter ext
public boolean roomConnect(IConnection conn, Object[] params) {
log.debug("roomConnect : ");
- try {
+ IServiceCapableConnection service = (IServiceCapableConnection) conn;
+ String streamId = conn.getClient().getId();
+
+ boolean isAVClient = params.length == 1 ? Boolean.valueOf("" + params[0]) : false;
- IServiceCapableConnection service = (IServiceCapableConnection) conn;
- String streamId = conn.getClient().getId();
-
- boolean isAVClient = false;
- if (params.length == 1) {
- isAVClient = Boolean.valueOf("" + params[0]);
- }
+ log.debug("### Client connected to OpenMeetings, register Client StreamId: " + streamId + " scope "
+ + conn.getScope().getName() + " isAVClient " + isAVClient);
- log.debug("### Client connected to OpenMeetings, register Client StreamId: " + streamId + " scope "
- + conn.getScope().getName() + " isAVClient " + isAVClient);
+ // Set StreamId in Client
+ service.invoke("setId", new Object[] { streamId }, this);
- // Set StreamId in Client
- service.invoke("setId", new Object[] { streamId }, this);
+ Map<String, Object> map = conn.getConnectParams();
+ String swfURL = map.containsKey("swfUrl") ? (String)map.get("swfUrl") : "";
- String swfURL = "";
- if (conn.getConnectParams().get("swfUrl") != null) {
- swfURL = conn.getConnectParams().get("swfUrl").toString();
+ //TODO add similar code for other connections
+ if (map.containsKey("screenClient")) {
+ String parentSid = (String)map.get("parentSid");
+ Client parentClient = sessionManager.getClientByPublicSID(parentSid, false, null);
+ if (parentClient == null) {
+ rejectClient();
}
-
- Client rcm = sessionManager.addClientListItem(streamId,
- conn.getScope().getName(), conn.getRemotePort(),
- conn.getRemoteAddress(), swfURL, isAVClient, null);
+ }
+ Client rcm = sessionManager.addClientListItem(conn.getClient().getId(),
+ conn.getScope().getName(), conn.getRemotePort(),
+ conn.getRemoteAddress(), swfURL, isAVClient, null);
+
+ SessionVariablesUtil.initClient(conn.getClient(), isAVClient, rcm.getPublicSID());
+ //TODO add similar code for other connections, merge with above block
+ if (map.containsKey("screenClient")) {
+ //TODO add check for room rights
+ String parentSid = (String)map.get("parentSid");
+ rcm.setRoom_id(Long.parseLong(conn.getScope().getName()));
+ rcm.setScreenClient(true);
+ SessionVariablesUtil.setIsScreenClient(conn.getClient());
- SessionVariablesUtil.initClient(conn.getClient(), isAVClient, rcm.getPublicSID());
+ rcm.setUser_id(((Integer)map.get("userId")).longValue());
+ SessionVariablesUtil.setUserId(conn.getClient(), rcm.getUser_id());
- // Log the User
- conferenceLogDao.addConferenceLog("ClientConnect",
- rcm.getUser_id(), streamId, null, rcm.getUserip(),
- rcm.getScope(), rcm.getExternalUserId(),
- rcm.getExternalUserType(), rcm.getEmail(),
- rcm.getFirstname(), rcm.getLastname());
- } catch (Exception err) {
- log.error("roomJoin", err);
- }
+ rcm.setStreamPublishName(parentSid);
+ User u = usersDao.get(rcm.getUser_id());
+ rcm.setUsername(u.getLogin());
+ rcm.setFirstname(u.getFirstname());
+ rcm.setLastname(u.getLastname());
+ log.debug("publishName :: " + rcm.getStreamPublishName());
+ sessionManager.updateClientByStreamId(streamId, rcm, false, null);
+ }
+
+ // Log the User
+ conferenceLogDao.addConferenceLog("ClientConnect",
+ rcm.getUser_id(), streamId, null, rcm.getUserip(),
+ rcm.getScope(), rcm.getExternalUserId(),
+ rcm.getExternalUserType(), rcm.getEmail(),
+ rcm.getFirstname(), rcm.getLastname());
return true;
}
@@ -187,44 +204,45 @@ public class ScopeApplicationAdapter ext
log.debug("----------- screenSharerAction ENTER");
IConnection current = Red5.getConnectionLocal();
- Client rc = sessionManager.getClientByStreamId(current.getClient().getId(), null);
+ Client control = sessionManager.getClientByStreamId(current.getClient().getId(), null);
+ Client client = sessionManager.getClientByPublicSID(control.getStreamPublishName(), false, null);
Map<String, String> returnMap = new HashMap<String, String>();
- if (rc != null) {
+ if (client != null) {
boolean changed = false;
- if (Boolean.valueOf("" + map.get("stopStreaming")) && rc.isStartStreaming()) {
+ if (Boolean.valueOf("" + map.get("stopStreaming")) && client.isStartStreaming()) {
changed = true;
- rc.setStartStreaming(false);
+ client.setStartStreaming(false);
//Send message to all users
- sendMessageToCurrentScope("stopScreenSharingMessage", rc, false);
+ sendMessageToCurrentScope("stopScreenSharingMessage", client, false);
returnMap.put("result", "stopSharingOnly");
}
- if (Boolean.valueOf("" + map.get("stopRecording")) && rc.getIsRecording()) {
+ if (Boolean.valueOf("" + map.get("stopRecording")) && client.getIsRecording()) {
changed = true;
- rc.setStartRecording(false);
- rc.setIsRecording(false);
+ client.setStartRecording(false);
+ client.setIsRecording(false);
returnMap.put("result", "stopRecordingOnly");
//Send message to all users
- sendMessageToCurrentScope("stopRecordingMessage", rc, false);
+ sendMessageToCurrentScope("stopRecordingMessage", client, false);
- flvRecorderService.stopRecordAndSave(current.getScope(), rc, null);
+ flvRecorderService.stopRecordAndSave(current.getScope(), client, null);
}
- if (Boolean.valueOf("" + map.get("stopPublishing")) && rc.isScreenPublishStarted()) {
+ if (Boolean.valueOf("" + map.get("stopPublishing")) && client.isScreenPublishStarted()) {
changed = true;
- rc.setScreenPublishStarted(false);
+ client.setScreenPublishStarted(false);
returnMap.put("result", "stopPublishingOnly");
//Send message to all users
- sendMessageToCurrentScope("stopPublishingMessage", rc, false);
+ sendMessageToCurrentScope("stopPublishingMessage", client, false);
}
if (changed) {
- sessionManager.updateClientByStreamId(rc.getStreamid(), rc, false, null);
+ sessionManager.updateClientByStreamId(client.getStreamid(), client, false, null);
- if (!rc.isStartStreaming() && !rc.isStartRecording() && !rc.isStreamPublishStarted()) {
+ if (!client.isStartStreaming() && !client.isStartRecording() && !client.isStreamPublishStarted()) {
returnMap.put("result", "stopAll");
}
}
@@ -268,75 +286,50 @@ public class ScopeApplicationAdapter ext
* @return returns key,value Map with multiple return values or null in case of exception
*
*/
- @SuppressWarnings({ "rawtypes", "unchecked" })
- public Map setConnectionAsSharingClient(Map map) {
+ public Map<String, Object> setConnectionAsSharingClient(Map<String, Object> map) {
try {
log.debug("----------- setConnectionAsSharingClient");
IConnection current = Red5.getConnectionLocal();
- Client currentClient = sessionManager.getClientByStreamId(current.getClient().getId(), null);
+ Client control = sessionManager.getClientByStreamId(current.getClient().getId(), null);
+ Client client = sessionManager.getClientByPublicSID(control.getStreamPublishName(), false, null);
- if (currentClient != null) {
+ if (client != null) {
boolean startRecording = Boolean.valueOf("" + map.get("startRecording"));
boolean startStreaming = Boolean.valueOf("" + map.get("startStreaming"));
- boolean startPublishing = Boolean.valueOf("" + map.get("startPublishing"))
- && (0 == sessionManager.getPublishingCount(currentClient.getRoom_id()));
-
- currentClient.setRoom_id(Long.parseLong(current.getScope().getName()));
-
- // Set this connection to be a RTMP-Java Client
- currentClient.setScreenClient(true);
-
- SessionVariablesUtil.setIsScreenClient(current.getClient());
-
- currentClient.setUser_id(Long.parseLong(map.get("user_id").toString()));
- SessionVariablesUtil.setUserId(current.getClient(), Long.parseLong(map.get("user_id").toString()));
+ boolean startPublishing = Boolean.valueOf("" + map.get("startPublishing")) && (0 == sessionManager.getPublishingCount(client.getRoom_id()));
- boolean alreadyStreaming = currentClient.isStartStreaming();
+ boolean alreadyStreaming = client.isStartStreaming();
if (startStreaming) {
- currentClient.setStartStreaming(true);
+ client.setStartStreaming(true);
}
- boolean alreadyRecording = currentClient.isStartRecording();
+ boolean alreadyRecording = client.isStartRecording();
if (startRecording) {
- currentClient.setStartRecording(true);
+ client.setStartRecording(true);
}
if (startPublishing) {
- currentClient.setStreamPublishStarted(true);
+ client.setStreamPublishStarted(true);
}
- sessionManager.updateClientByStreamId(current.getClient().getId(), currentClient, false, null);
+ client.setVX(Integer.parseInt(map.get("screenX").toString()));
+ client.setVY(Integer.parseInt(map.get("screenY").toString()));
+ client.setVWidth(Integer.parseInt(map.get("screenWidth").toString()));
+ client.setVHeight(Integer.parseInt(map.get("screenHeight").toString()));
+ sessionManager.updateClientByStreamId(current.getClient().getId(), client, false, null);
- Map returnMap = new HashMap();
+ Map<String, Object> returnMap = new HashMap<String, Object>();
returnMap.put("alreadyPublished", false);
// if is already started screen sharing, then there is no need
// to start it again
- if (currentClient.isScreenPublishStarted()) {
+ if (client.isScreenPublishStarted()) {
returnMap.put("alreadyPublished", true);
}
- currentClient.setVX(Integer.parseInt(map.get("screenX").toString()));
- currentClient.setVY(Integer.parseInt(map.get("screenY").toString()));
- currentClient.setVWidth(Integer.parseInt(map.get("screenWidth").toString()));
- currentClient.setVHeight(Integer.parseInt(map.get("screenHeight").toString()));
-
- log.debug("screen x,y,width,height " + currentClient.getVX()
- + " " + currentClient.getVY() + " "
- + currentClient.getVWidth() + " "
- + currentClient.getVHeight());
-
- log.debug("publishName :: " + map.get("publishName"));
-
- currentClient.setStreamPublishName(map.get("publishName").toString());
-
- Client currentScreenUser = sessionManager.getClientByPublicSID(currentClient.getStreamPublishName(), false, null);
-
- currentClient.setFirstname(currentScreenUser.getFirstname());
- currentClient.setLastname(currentScreenUser.getLastname());
-
- // This is duplicated, but its not sure that in the meantime
- // somebody requests this Client Object Info
- sessionManager.updateClientByStreamId(current.getClient().getId(), currentClient, false, null);
+ log.debug("screen x,y,width,height " + client.getVX()
+ + " " + client.getVY() + " "
+ + client.getVWidth() + " "
+ + client.getVHeight());
if (startStreaming) {
if (!alreadyStreaming) {
@@ -345,9 +338,9 @@ public class ScopeApplicationAdapter ext
log.debug("start streamPublishStart Is Screen Sharing ");
//Send message to all users
- sendMessageToCurrentScope("newScreenSharing", currentClient, false);
+ sendMessageToCurrentScope("newScreenSharing", client, false);
} else {
- log.warn("Streaming is already started for the client id=" + currentClient.getId() + ". Second request is ignored.");
+ log.warn("Streaming is already started for the client id=" + client.getId() + ". Second request is ignored.");
}
}
if (startRecording) {
@@ -356,17 +349,16 @@ public class ScopeApplicationAdapter ext
String recordingName = "Recording " + CalendarPatterns.getDateWithTimeByMiliSeconds(new Date());
- flvRecorderService.recordMeetingStream(current, recordingName, "", false);
+ flvRecorderService.recordMeetingStream(current, client, recordingName, "", false);
} else {
- log.warn("Recording is already started for the client id=" + currentClient.getId() + ". Second request is ignored.");
+ log.warn("Recording is already started for the client id=" + client.getId() + ". Second request is ignored.");
}
}
if (startPublishing) {
- sendMessageToCurrentScope("startedPublishing", new Object[]{currentClient, "rtmp://" + map.get("publishingHost") + ":1935/"
+ sendMessageToCurrentScope("startedPublishing", new Object[]{client, "rtmp://" + map.get("publishingHost") + ":1935/"
+ map.get("publishingApp") + "/" + map.get("publishingId")}, false, true);
returnMap.put("modus", "startPublishing");
}
-
return returnMap;
} else {
@@ -827,10 +819,8 @@ public class ScopeApplicationAdapter ext
@SuppressWarnings("unchecked")
public void setNewCursorPosition(Object item) {
try {
-
IConnection current = Red5.getConnectionLocal();
- String streamid = current.getClient().getId();
- Client currentClient = sessionManager.getClientByStreamId(streamid, null);
+ Client currentClient = sessionManager.getClientByStreamId(current.getClient().getId(), null);
@SuppressWarnings("rawtypes")
Map cursor = (Map) item;
@@ -1799,7 +1789,10 @@ public class ScopeApplicationAdapter ext
@Override
public void run() {
try {
- if (scope != null) {
+ if (scope == null) {
+ log.debug(String.format("[MessageSender] -> 'Unable to send message to NULL scope' %s, %s", remoteMethodName, newMessage));
+ } else {
+ log.trace(String.format("[MessageSender] -> 'sending message' %s, %s", remoteMethodName, newMessage));
// Send to all Clients of that Scope(Room)
for (IConnection conn : scope.getClientConnections()) {
if (conn != null && conn instanceof IServiceCapableConnection) {
@@ -1809,9 +1802,10 @@ public class ScopeApplicationAdapter ext
((IServiceCapableConnection) conn).invoke(remoteMethodName, new Object[] { newMessage }, ScopeApplicationAdapter.this);
}
}
+ log.trace(String.format("[MessageSender] -> 'sending message DONE' %s", remoteMethodName));
}
} catch (Exception err) {
- log.error(String.format("[sendMessageToCurrentScope -> %s, %s]", remoteMethodName, newMessage), err);
+ log.error(String.format("[MessageSender -> %s, %s]", remoteMethodName, newMessage), err);
}
}
}
@@ -2118,7 +2112,7 @@ public class ScopeApplicationAdapter ext
}
String recordingName = "Interview " + CalendarPatterns.getDateWithTimeByMiliSeconds(new Date());
- flvRecorderService.recordMeetingStream(current, recordingName, "", true);
+ flvRecorderService.recordMeetingStream(current, current_rcl, recordingName, "", true);
return true;
} catch (Exception err) {
@@ -2128,24 +2122,15 @@ public class ScopeApplicationAdapter ext
}
@SuppressWarnings({ "rawtypes" })
- public Boolean sendRemoteCursorEvent(String streamid, Map messageObj) {
- try {
-
- IConnection current = Red5.getConnectionLocal();
-
- for (IConnection conn : current.getScope().getClientConnections()) {
- if (conn != null) {
- IClient client = conn.getClient();
- if (SessionVariablesUtil.isScreenClient(client)) {
- if (conn.getClient().getId().equals(streamid)) {
- ((IServiceCapableConnection) conn).invoke("sendRemoteCursorEvent", new Object[] { messageObj }, this);
- }
- }
- }
+ public Boolean sendRemoteCursorEvent(final String streamid, Map messageObj) {
+ new MessageSender("sendRemoteCursorEvent", messageObj) {
+
+ @Override
+ public boolean filter(IConnection conn) {
+ IClient client = conn.getClient();
+ return SessionVariablesUtil.isScreenClient(client) && conn.getClient().getId().equals(streamid);
}
- } catch (Exception err) {
- log.debug("[sendRemoteCursorEvent]", err);
- }
+ }.start();
return null;
}
Modified: openmeetings/trunk/singlewebapp/openmeetings-screenshare/src/main/java/org/apache/openmeetings/screen/webstart/CaptureScreen.java
URL: http://svn.apache.org/viewvc/openmeetings/trunk/singlewebapp/openmeetings-screenshare/src/main/java/org/apache/openmeetings/screen/webstart/CaptureScreen.java?rev=1656837&r1=1656836&r2=1656837&view=diff
==============================================================================
--- openmeetings/trunk/singlewebapp/openmeetings-screenshare/src/main/java/org/apache/openmeetings/screen/webstart/CaptureScreen.java (original)
+++ openmeetings/trunk/singlewebapp/openmeetings-screenshare/src/main/java/org/apache/openmeetings/screen/webstart/CaptureScreen.java Tue Feb 3 17:22:29 2015
@@ -30,9 +30,6 @@ import java.awt.Rectangle;
import java.awt.Robot;
import java.io.IOException;
import java.util.concurrent.ArrayBlockingQueue;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
@@ -41,7 +38,9 @@ import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
+import org.quartz.JobKey;
import org.quartz.Scheduler;
+import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
@@ -54,7 +53,9 @@ import org.slf4j.Logger;
class CaptureScreen extends Thread {
private static final Logger log = getLogger(CaptureScreen.class);
- private static final int NANO_MULTIPLIER = 1000 * 1000;
+ private final static String QUARTZ_GROUP_NAME = "ScreenShare";
+ private final static String QUARTZ_CURSOR_TRIGGER_NAME = "CursorTrigger";
+ private final static String QUARTZ_CURSOR_JOB_NAME = "CursorJob";
private CoreScreenShare core;
private int timeBetweenFrames;
private volatile int timestamp = 0;
@@ -68,8 +69,6 @@ class CaptureScreen extends Thread {
private int port = -1;
private int streamId;
private boolean startPublish = false;
- private boolean sendCursor = false;
- private final ScheduledExecutorService cursorScheduler = Executors.newScheduledThreadPool(1);
private Scheduler scheduler;
public CaptureScreen(CoreScreenShare coreScreenShare, IScreenShare client, String host, String app, int port) {
@@ -78,6 +77,12 @@ class CaptureScreen extends Thread {
this.host = host;
this.app = app;
this.port = port;
+ SchedulerFactory sf = new StdSchedulerFactory();
+ try {
+ scheduler = sf.getScheduler();
+ } catch (SchedulerException e) {
+ log.error("Unexpected error while creating scheduler", e);
+ }
}
public void release() {
@@ -89,11 +94,6 @@ class CaptureScreen extends Thread {
} catch (Exception e) {
log.error("Unexpected error while shutting down scheduler", e);
}
- try {
- cursorScheduler.shutdownNow();
- } catch (Exception e) {
- log.error("Unexpected error while shutting down scheduler", e);
- }
active = false;
timestamp = 0;
timeCaptureStarted = 0;
@@ -109,32 +109,22 @@ class CaptureScreen extends Thread {
se = new ScreenV1Encoder(3 * FPS); //send keyframe every 3 seconds
timeCaptureStarted = System.currentTimeMillis();
- JobDetail encodeJob = JobBuilder.newJob(EncodeJob.class).withIdentity("EncodeJob", "ScreenShare").build();
+ JobDetail encodeJob = JobBuilder.newJob(EncodeJob.class).withIdentity("EncodeJob", QUARTZ_GROUP_NAME).build();
encodeJob.getJobDataMap().put(EncodeJob.CAPTURE_KEY, this);
Trigger encodeTrigger = TriggerBuilder.newTrigger()
- .withIdentity("EncodeTrigger", "ScreenShare")
+ .withIdentity("EncodeTrigger", QUARTZ_GROUP_NAME)
.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInMilliseconds(timeBetweenFrames).repeatForever())
.build();
- JobDetail sendJob = JobBuilder.newJob(SendJob.class).withIdentity("SendJob", "ScreenShare").build();
+ JobDetail sendJob = JobBuilder.newJob(SendJob.class).withIdentity("SendJob", QUARTZ_GROUP_NAME).build();
Trigger sendTrigger = TriggerBuilder.newTrigger()
- .withIdentity("SendTrigger", "ScreenShare")
+ .withIdentity("SendTrigger", QUARTZ_GROUP_NAME)
.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInMilliseconds(timeBetweenFrames).repeatForever())
.build();
sendJob.getJobDataMap().put(SendJob.CAPTURE_KEY, this);
- SchedulerFactory sf = new StdSchedulerFactory();
- scheduler = sf.getScheduler();
scheduler.scheduleJob(encodeJob, encodeTrigger);
scheduler.scheduleJob(sendJob, sendTrigger);
scheduler.start();
-
- if (sendCursor) {
- cursorScheduler.scheduleWithFixedDelay(new Runnable() {
- public void run() {
- core.sendCursorStatus();
- }
- }, 0, timeBetweenFrames * NANO_MULTIPLIER, TimeUnit.NANOSECONDS);
- }
} catch (Exception e) {
log.error("Error while running: ", e);
}
@@ -229,6 +219,20 @@ class CaptureScreen extends Thread {
}
}
+ @DisallowConcurrentExecution
+ public static class CursorJob implements Job {
+ private static final String CAPTURE_KEY = "capture";
+
+ public CursorJob() {}
+
+ @Override
+ public void execute(JobExecutionContext context) throws JobExecutionException {
+ JobDataMap data = context.getJobDetail().getJobDataMap();
+ CaptureScreen capture = (CaptureScreen)data.get(CAPTURE_KEY);
+ capture.core.sendCursorStatus();
+ }
+ }
+
private void pushVideo(VideoData data, int ts) throws IOException {
if (startPublish) {
if (Red5.getConnectionLocal() == null) {
@@ -264,6 +268,20 @@ class CaptureScreen extends Thread {
}
public void setSendCursor(boolean sendCursor) {
- this.sendCursor = sendCursor;
+ try {
+ if (sendCursor) {
+ JobDetail cursorJob = JobBuilder.newJob(CursorJob.class).withIdentity(QUARTZ_CURSOR_JOB_NAME, QUARTZ_GROUP_NAME).build();
+ Trigger cursorTrigger = TriggerBuilder.newTrigger()
+ .withIdentity(QUARTZ_CURSOR_TRIGGER_NAME, QUARTZ_GROUP_NAME)
+ .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInMilliseconds(1000 / Math.min(2, FPS)).repeatForever())
+ .build();
+ cursorJob.getJobDataMap().put(CursorJob.CAPTURE_KEY, this);
+ scheduler.scheduleJob(cursorJob, cursorTrigger);
+ } else {
+ scheduler.deleteJob(JobKey.jobKey(QUARTZ_CURSOR_JOB_NAME, QUARTZ_GROUP_NAME));
+ }
+ } catch (SchedulerException e) {
+ log.error("Unexpected Error schedule/unschedule cursor job", e);
+ }
}
}
Modified: openmeetings/trunk/singlewebapp/openmeetings-screenshare/src/main/java/org/apache/openmeetings/screen/webstart/CoreScreenShare.java
URL: http://svn.apache.org/viewvc/openmeetings/trunk/singlewebapp/openmeetings-screenshare/src/main/java/org/apache/openmeetings/screen/webstart/CoreScreenShare.java?rev=1656837&r1=1656836&r2=1656837&view=diff
==============================================================================
--- openmeetings/trunk/singlewebapp/openmeetings-screenshare/src/main/java/org/apache/openmeetings/screen/webstart/CoreScreenShare.java (original)
+++ openmeetings/trunk/singlewebapp/openmeetings-screenshare/src/main/java/org/apache/openmeetings/screen/webstart/CoreScreenShare.java Tue Feb 3 17:22:29 2015
@@ -63,6 +63,7 @@ public class CoreScreenShare implements
rtmp, rtmpt, rtmpe, rtmps
}
private IScreenShare instance = null;
+ private IScreenShare controlInstance = null;
private Protocol protocol;
private String host;
private String app;
@@ -79,7 +80,7 @@ public class CoreScreenShare implements
public boolean showFPS = true;
public boolean allowRemote = true;
- public Long user_id = null;
+ public Long userId = null;
private boolean allowRecording = true;
private boolean allowPublishing = true;
@@ -118,7 +119,7 @@ public class CoreScreenShare implements
host = args[1];
port = Integer.parseInt(args[2]);
app = args[3];
- user_id = Long.parseLong(args[4]);
+ userId = Long.parseLong(args[4]);
publishName = args[5];
String labelTexts = args[6];
defaultQuality = Integer.parseInt(args[7]);
@@ -143,21 +144,28 @@ public class CoreScreenShare implements
switch (protocol) {
case rtmp:
instance = new RTMPScreenShare(this);
+ controlInstance = new RTMPScreenShare(this);
break;
case rtmpt:
instance = new RTMPTScreenShare(this);
+ controlInstance = new RTMPTScreenShare(this);
break;
case rtmps:
RTMPSScreenShare client = new RTMPSScreenShare(this);
client.setKeystoreBytes(Hex.decodeHex(args[13].toCharArray()));
client.setKeyStorePassword(args[14]);
instance = client;
+ RTMPSScreenShare controlClient = new RTMPSScreenShare(this);
+ controlClient.setKeystoreBytes(Hex.decodeHex(args[13].toCharArray()));
+ controlClient.setKeyStorePassword(args[14]);
+ controlInstance = controlClient;
break;
case rtmpe:
default:
throw new Exception("Unsupported protocol");
}
- instance.setServiceProvider(instance);
+ instance.setServiceProvider(this);
+ controlInstance.setServiceProvider(this);
log.debug(String.format("host: %s, app: %s, port: %s, publish: %s", host, port, app, publishName));
} else {
System.exit(0);
@@ -190,7 +198,7 @@ public class CoreScreenShare implements
}
}
- synchronized public void sendCursorStatus() {
+ public void sendCursorStatus() {
try {
Point mouseP = MouseInfo.getPointerInfo().getLocation();
@@ -205,11 +213,11 @@ public class CoreScreenShare implements
cursorPosition.put("cursor_x", x);
cursorPosition.put("cursor_y", y);
- if (instance.getConnection() != null) {
+ if (controlInstance.getConnection() != null) {
if (Red5.getConnectionLocal() == null) {
- Red5.setConnectionLocal(instance.getConnection());
+ Red5.setConnectionLocal(controlInstance.getConnection());
}
- instance.invoke("setNewCursorPosition", new Object[] { cursorPosition }, this);
+ controlInstance.invoke("setNewCursorPosition", new Object[] { cursorPosition }, this);
}
} catch (NullPointerException npe) {
//noop
@@ -219,11 +227,13 @@ public class CoreScreenShare implements
}
}
- synchronized public void setConnectionAsSharingClient() {
+ public void setConnectionAsSharingClient() {
+ log.debug("########## setConnectionAsSharingClient");
try {
- log.debug("########## setConnectionAsSharingClient");
-
- Map<Object, Object> map = new HashMap<Object, Object>();
+ if (Red5.getConnectionLocal() == null) {
+ Red5.setConnectionLocal(controlInstance.getConnection());
+ }
+ Map<String, Object> map = new HashMap<String, Object>();
map.put("screenX", spinnerX);
map.put("screenY", spinnerY);
@@ -233,20 +243,16 @@ public class CoreScreenShare implements
map.put("screenWidth", scaledWidth);
map.put("screenHeight", scaledHeight);
- map.put("publishName", publishName);
map.put("startRecording", startRecording);
map.put("startStreaming", startStreaming);
map.put("startPublishing", startPublishing);
map.put("publishingHost", frame.getPublishHost());
map.put("publishingApp", frame.getPublishApp());
map.put("publishingId", frame.getPublishId());
-
- map.put("user_id", user_id);
-
if (Red5.getConnectionLocal() == null) {
- Red5.setConnectionLocal(instance.getConnection());
+ Red5.setConnectionLocal(controlInstance.getConnection());
}
- instance.invoke("setConnectionAsSharingClient", new Object[] { map }, this);
+ controlInstance.invoke("setConnectionAsSharingClient", new Object[] { map }, this);
} catch (Exception err) {
frame.setStatus("Error: " + err.getLocalizedMessage());
log.error("[setConnectionAsSharingClient]", err);
@@ -268,14 +274,21 @@ public class CoreScreenShare implements
captureScreenStart();
}
+ private void connect(String parentSid, boolean control) {
+ Map<String, Object> map = instance.makeDefaultConnectionParams(host, port, app);
+ map.put("screenClient", true);
+ map.put("userId", userId);
+ map.put("parentSid", parentSid);
+ (control ? controlInstance : instance).connect(host, port, map, this);
+ }
+
private void captureScreenStart() {
try {
log.debug("captureScreenStart");
if (!isConnected) {
- instance.connect(host, port, app, this);
- }
- if (isConnected) {
+ connect(publishName, false);
+ } else {
setConnectionAsSharingClient();
}
} catch (Exception err) {
@@ -307,9 +320,9 @@ public class CoreScreenShare implements
map.put(action, true);
if (Red5.getConnectionLocal() == null) {
- Red5.setConnectionLocal(instance.getConnection());
+ Red5.setConnectionLocal(controlInstance.getConnection());
}
- instance.invoke("screenSharerAction", new Object[] { map }, this);
+ controlInstance.invoke("screenSharerAction", new Object[] { map }, this);
} catch (Exception err) {
log.error("captureScreenStop Exception: ", err);
frame.setStatus("Exception: " + err);
@@ -382,6 +395,7 @@ public class CoreScreenShare implements
isConnected = false;
instance.disconnect();
+ controlInstance.disconnect();
setReadyToRecord(false);
getCapture().setStartPublish(false);
getCapture().release();
@@ -546,7 +560,7 @@ public class CoreScreenShare implements
String clientId = returnMap.get("clientId").toString();
- instance.invoke("sendMessageWithClientById", new Object[]{map, clientId}, this);
+ controlInstance.invoke("sendMessageWithClientById", new Object[]{map, clientId}, this);
} else if (action.equals("show")) {
String paste = getClipboardText();
@@ -556,10 +570,7 @@ public class CoreScreenShare implements
String clientId = returnMap.get("clientId").toString();
- // public synchronized int sendMessageWithClientById(Object
- // newMessage, String clientId)
-
- instance.invoke("sendMessageWithClientById", new Object[]{map, clientId}, this);
+ controlInstance.invoke("sendMessageWithClientById", new Object[]{map, clientId}, this);
}
} catch (Exception err) {
log.error("[sendRemoteCursorEvent]", err);
@@ -603,14 +614,14 @@ public class CoreScreenShare implements
}
}
- private String getHighlightedText(Robot instance) {
+ private String getHighlightedText(Robot robot) {
try {
if (System.getProperty("os.name").toUpperCase().indexOf("WINDOWS") >= 0) {
// pressing STRG+C == copy
- pressSequence(instance, 200, KeyEvent.VK_CONTROL, KeyEvent.VK_C, KeyEvent.VK_C, KeyEvent.VK_CONTROL);
+ pressSequence(robot, 200, KeyEvent.VK_CONTROL, KeyEvent.VK_C, KeyEvent.VK_C, KeyEvent.VK_CONTROL);
} else {
// Macintosh simulate Copy
- pressSequence(instance, 200, 157, 67, 67, 157);
+ pressSequence(robot, 200, 157, 67, 67, 157);
}
return getClipboardText();
} catch (Exception e) {
@@ -619,7 +630,7 @@ public class CoreScreenShare implements
return "";
}
- private void pressSpecialSign(String charValue, Robot instance) {
+ private void pressSpecialSign(String charValue, Robot robot) {
Clipboard clippy = getDefaultToolkit().getSystemClipboard();
try {
Transferable transferableText = new StringSelection(charValue);
@@ -627,10 +638,10 @@ public class CoreScreenShare implements
if (System.getProperty("os.name").toUpperCase().indexOf("WINDOWS") >= 0) {
// pressing STRG+V == insert-mode
- pressSequence(instance, 100, KeyEvent.VK_CONTROL, KeyEvent.VK_V, KeyEvent.VK_V, KeyEvent.VK_CONTROL);
+ pressSequence(robot, 100, KeyEvent.VK_CONTROL, KeyEvent.VK_V, KeyEvent.VK_V, KeyEvent.VK_CONTROL);
} else {
// Macintosh simulate Insert
- pressSequence(instance, 100, 157, 86, 86, 157);
+ pressSequence(robot, 100, 157, 86, 86, 157);
}
} catch (Exception e) {
log.error("Unexpected exception while pressSpecialSign", e);
@@ -640,17 +651,30 @@ public class CoreScreenShare implements
public void resultReceived(IPendingServiceCall call) {
try {
- log.trace( "service call result: " + call );
+ log.trace("service call result: " + call);
String method = call == null ? null : call.getServiceMethodName();
+ Object o = call == null ? null : call.getResult();
log.trace("call ### get Method Name " + method);
if ("connect".equals(method)) {
+ if (o instanceof Map) {
+ @SuppressWarnings("unchecked")
+ Map<String, Object> map = (Map<String, Object>) o;
+ Object code = map.get("code");
+ if ("NetConnection.Connect.Rejected".equals(code) || "NetConnection.Connect.Failed".equals(code)) {
+ frame.setStatus(String.format("Error: %s %s", code, map.get("description")));
+ return;
+ }
+ }
+ if (!isConnected) {
+ instance.invoke("getPublicSID", null, this);
+ } else {
+ setConnectionAsSharingClient();
+ }
isConnected = true;
- setConnectionAsSharingClient();
+ } else if ("getPublicSID".equals(method)) {
+ connect((String)o, true);
} else if ("setConnectionAsSharingClient".equals(method)) {
-
- Object o = call.getResult();
-
@SuppressWarnings("unchecked")
Map<String, Object> returnMap = (Map<String, Object>) o;
@@ -692,13 +716,15 @@ public class CoreScreenShare implements
log.debug("setup capture thread spinnerWidth = {}; spinnerHeight = {};", spinnerWidth, spinnerHeight);
- getCapture().setSendCursor(true);
- getCapture().start();
+ if (!getCapture().isAlive()) {
+ getCapture().setSendCursor(startStreaming);
+ getCapture().start();
+ }
}
} else if ("screenSharerAction".equals(method)) {
- Object o = call.getResult();
-
- log.trace("Result Map Type " + o.getClass().getName());
+ if (log.isTraceEnabled()) {
+ log.trace("Result Map Type " + (o == null ? null : o.getClass().getName()));
+ }
@SuppressWarnings("unchecked")
Map<String, Object> returnMap = (Map<String, Object>)o;
Modified: openmeetings/trunk/singlewebapp/openmeetings-screenshare/src/main/java/org/apache/openmeetings/screen/webstart/IScreenShare.java
URL: http://svn.apache.org/viewvc/openmeetings/trunk/singlewebapp/openmeetings-screenshare/src/main/java/org/apache/openmeetings/screen/webstart/IScreenShare.java?rev=1656837&r1=1656836&r2=1656837&view=diff
==============================================================================
--- openmeetings/trunk/singlewebapp/openmeetings-screenshare/src/main/java/org/apache/openmeetings/screen/webstart/IScreenShare.java (original)
+++ openmeetings/trunk/singlewebapp/openmeetings-screenshare/src/main/java/org/apache/openmeetings/screen/webstart/IScreenShare.java Tue Feb 3 17:22:29 2015
@@ -18,6 +18,8 @@
*/
package org.apache.openmeetings.screen.webstart;
+import java.util.Map;
+
import org.red5.client.net.rtmp.ClientExceptionHandler;
import org.red5.client.net.rtmp.INetStreamEventHandler;
import org.red5.server.api.service.IPendingServiceCallback;
@@ -27,7 +29,8 @@ import org.red5.server.net.rtmp.RTMPConn
public interface IScreenShare extends ClientExceptionHandler {
RTMPConnection getConnection();
void invoke(String method, Object[] params, IPendingServiceCallback callback);
- void connect(String server, int port, String application, IPendingServiceCallback connectCallback);
+ Map<String, Object> makeDefaultConnectionParams(String server, int port, String application);
+ void connect(String server, int port, Map<String, Object> connectionParams, IPendingServiceCallback connectCallback);
void setServiceProvider(Object serviceProvider);
void disconnect();
void createStream(IPendingServiceCallback callback);