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 2018/03/13 17:36:35 UTC

[openmeetings] branch master updated: [OPENMEETINGS-1649] basic work on test recording

This is an automated email from the ASF dual-hosted git repository.

solomax pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/openmeetings.git


The following commit(s) were added to refs/heads/master by this push:
     new f3a6489  [OPENMEETINGS-1649] basic work on test recording
f3a6489 is described below

commit f3a6489cebef16e688f2a0fa1e40cf9beeee7b4d
Author: Maxim Solodovnik <so...@gmail.com>
AuthorDate: Wed Mar 14 00:36:21 2018 +0700

    [OPENMEETINGS-1649] basic work on test recording
---
 .../openmeetings/core/remote/KurentoHandler.java   |   6 +-
 openmeetings-web/pom.xml                           |  18 ++-
 .../apache/openmeetings/web/common/MainPanel.java  |  21 ++-
 .../apache/openmeetings/web/pages/HashPage.java    |  88 +++++++++---
 .../apache/openmeetings/web/room/RoomPanel.java    |   2 +-
 .../openmeetings/web/room/VideoSettings.java       |  76 +----------
 .../web/room/menu/StartSharingButton.java          |   2 +-
 .../web/room/{settings.js => settings-base.js}     | 150 ++++++++++++++++-----
 .../java/org/apache/openmeetings/web/room/video.js |   4 +-
 9 files changed, 232 insertions(+), 135 deletions(-)

diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KurentoHandler.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KurentoHandler.java
index da9f222..0d72547 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KurentoHandler.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KurentoHandler.java
@@ -98,6 +98,10 @@ public class KurentoHandler {
 						candidate.getString("sdpMid"), candidate.getInt("sdpMLineIndex"));
 				user.addCandidate(cand, msg.getString("uid"));
 				break;
+			case "testStart":
+				break;
+			case "onTestIceCandidate":
+				break;
 			default:
 				break;
 		}
@@ -149,7 +153,7 @@ public class KurentoHandler {
 	}
 
 	public KUser getByUid(String uid) {
-		return usersByUid.get(uid);
+		return uid == null ? null : usersByUid.get(uid);
 	}
 
 	public boolean exists(String name) {
diff --git a/openmeetings-web/pom.xml b/openmeetings-web/pom.xml
index 60a7718..7ce4b2c 100644
--- a/openmeetings-web/pom.xml
+++ b/openmeetings-web/pom.xml
@@ -217,7 +217,6 @@
 								<jsSourceFile>video.js</jsSourceFile>
 								<jsSourceFile>video-manager.js</jsSourceFile>
 								<jsSourceFile>room-base.js</jsSourceFile>
-								<jsSourceFile>kurento-utils.js</jsSourceFile>
 							</jsSourceFiles>
 							<jsFinalFile>room.js</jsFinalFile>
 							<jsEngine>CLOSURE</jsEngine>
@@ -225,6 +224,23 @@
 						</configuration>
 					</execution>
 					<execution>
+						<id>settings-js</id>
+						<goals>
+							<goal>minify</goal>
+						</goals>
+						<configuration>
+							<charset>UTF-8</charset>
+							<jsSourceDir>../java/org/apache/openmeetings/web/room</jsSourceDir>
+							<jsSourceFiles>
+								<jsSourceFile>settings-base.js</jsSourceFile>
+								<jsSourceFile>kurento-utils.js</jsSourceFile>
+							</jsSourceFiles>
+							<jsFinalFile>settings.js</jsFinalFile>
+							<jsEngine>CLOSURE</jsEngine>
+							<jsTargetDir>../generated-sources/main/java/org/apache/openmeetings/web/room</jsTargetDir>
+						</configuration>
+					</execution>
+					<execution>
 						<id>chat-js</id>
 						<goals>
 							<goal>minify</goal>
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java
index b0ce22e..1db863e 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java
@@ -23,7 +23,6 @@ import static org.apache.openmeetings.db.util.AuthLevelUtil.hasAdminLevel;
 import static org.apache.openmeetings.db.util.AuthLevelUtil.hasGroupAdminLevel;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_MYROOMS_ENABLED;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.PARAM_USER_ID;
-import static org.apache.openmeetings.web.app.Application.getBean;
 import static org.apache.openmeetings.web.app.WebSession.getUserId;
 import static org.apache.openmeetings.web.util.CallbackFunctionHelper.getNamedFunction;
 import static org.apache.openmeetings.web.util.CallbackFunctionHelper.getParam;
@@ -123,6 +122,14 @@ public class MainPanel extends Panel {
 
 	@SpringBean
 	private KurentoHandler kHandler;
+	@SpringBean
+	private ClientManager clientManager;
+	@SpringBean
+	private ConfigurationDao cfgDao;
+	@SpringBean
+	private UserDao userDao;
+	@SpringBean
+	private RoomDao roomDao;
 
 	public MainPanel(String id) {
 		this(id, null);
@@ -142,9 +149,9 @@ public class MainPanel extends Panel {
 			protected void onConnect(ConnectedMessage msg) {
 				super.onConnect(msg);
 				ExtendedClientProperties cp = WebSession.get().getExtendedProperties();
-				final Client client = new Client(getSession().getId(), msg.getKey().hashCode(), getUserId(), getBean(UserDao.class));
+				final Client client = new Client(getSession().getId(), msg.getKey().hashCode(), getUserId(), userDao);
 				uid = client.getUid();
-				getBean(ClientManager.class).add(cp.update(client));
+				clientManager.add(cp.update(client));
 				log.debug("WebSocketBehavior::onConnect [uid: {}, session: {}, key: {}]", client.getUid(), msg.getSessionId(), msg.getKey());
 			}
 
@@ -196,7 +203,7 @@ public class MainPanel extends Panel {
 				log.debug("WebSocketBehavior::closeHandler [uid: {}, session: {}, key: {}]", uid, msg.getSessionId(), msg.getKey());
 				//no chance to stop pingTimer here :(
 				if (uid != null) {
-					getBean(ClientManager.class).exit(getClient());
+					clientManager.exit(getClient());
 					uid = null;
 				}
 			}
@@ -347,10 +354,10 @@ public class MainPanel extends Panel {
 			List<IMenuItem> l = new ArrayList<>();
 			l.add(getSubItem("777", "1506", MenuActions.conferenceModuleRoomList, MenuParams.publicTabButton));
 			l.add(getSubItem("779", "1507", MenuActions.conferenceModuleRoomList, MenuParams.privateTabButton));
-			if (getBean(ConfigurationDao.class).getBool(CONFIG_MYROOMS_ENABLED, true)) {
+			if (cfgDao.getBool(CONFIG_MYROOMS_ENABLED, true)) {
 				l.add(getSubItem("781", "1508", MenuActions.conferenceModuleRoomList, MenuParams.myTabButton));
 			}
-			List<Room> recent = getBean(RoomDao.class).getRecent(getUserId());
+			List<Room> recent = roomDao.getRecent(getUserId());
 			if (!recent.isEmpty()) {
 				l.add(new OmMenuItem(DELIMITER, (String)null));
 			}
@@ -456,6 +463,6 @@ public class MainPanel extends Panel {
 	}
 
 	public Client getClient() {
-		return getBean(ClientManager.class).get(uid);
+		return clientManager.get(uid);
 	}
 }
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/HashPage.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/HashPage.java
index ffa1823..c887f09 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/HashPage.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/HashPage.java
@@ -18,7 +18,7 @@
  */
 package org.apache.openmeetings.web.pages;
 
-import static org.apache.openmeetings.web.app.Application.getBean;
+import static org.apache.openmeetings.core.remote.KurentoHandler.KURENTO_TYPE;
 import static org.apache.openmeetings.web.app.WebSession.getRecordingId;
 import static org.apache.openmeetings.web.room.SwfPanel.SWF;
 import static org.apache.openmeetings.web.room.SwfPanel.SWF_TYPE_NETWORK;
@@ -26,6 +26,7 @@ import static org.apache.openmeetings.web.room.SwfPanel.SWF_TYPE_SETTINGS;
 import static org.apache.openmeetings.web.util.OmUrlFragment.CHILD_ID;
 
 import org.apache.commons.lang3.time.FastDateFormat;
+import org.apache.openmeetings.core.remote.KurentoHandler;
 import org.apache.openmeetings.db.dao.record.RecordingDao;
 import org.apache.openmeetings.db.dao.room.RoomDao;
 import org.apache.openmeetings.db.entity.record.Recording;
@@ -42,7 +43,6 @@ import org.apache.openmeetings.web.room.SwfPanel;
 import org.apache.openmeetings.web.room.VideoSettings;
 import org.apache.openmeetings.web.user.record.VideoInfo;
 import org.apache.openmeetings.web.user.record.VideoPlayer;
-import org.apache.openmeetings.web.util.ExtendedClientProperties;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.core.request.handler.IPartialPageRequestHandler;
 import org.apache.wicket.markup.head.CssHeaderItem;
@@ -50,10 +50,21 @@ import org.apache.wicket.markup.head.IHeaderResponse;
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.html.panel.EmptyPanel;
 import org.apache.wicket.protocol.http.request.WebClientInfo;
+import org.apache.wicket.protocol.ws.api.WebSocketBehavior;
+import org.apache.wicket.protocol.ws.api.WebSocketRequestHandler;
+import org.apache.wicket.protocol.ws.api.message.AbortedMessage;
+import org.apache.wicket.protocol.ws.api.message.AbstractClientMessage;
+import org.apache.wicket.protocol.ws.api.message.ClosedMessage;
+import org.apache.wicket.protocol.ws.api.message.ErrorMessage;
+import org.apache.wicket.protocol.ws.api.message.TextMessage;
 import org.apache.wicket.request.IRequestParameters;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
+import org.apache.wicket.spring.injection.annot.SpringBean;
 import org.apache.wicket.util.string.StringValue;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
+import com.github.openjson.JSONObject;
 import com.googlecode.wicket.jquery.core.JQueryBehavior;
 import com.googlecode.wicket.jquery.ui.widget.dialog.DialogButton;
 import com.googlecode.wicket.jquery.ui.widget.dialog.DialogButtons;
@@ -62,6 +73,7 @@ import com.googlecode.wicket.jquery.ui.widget.dialog.MessageDialog;
 
 public class HashPage extends BaseInitedPage implements IUpdatable {
 	private static final long serialVersionUID = 1L;
+	private static final Logger log = LoggerFactory.getLogger(HashPage.class);
 	public static final String PANEL_MAIN = "panel-main";
 	public static final String INVITATION_HASH = "invitation";
 	private static final String HASH = "secure";
@@ -73,6 +85,13 @@ public class HashPage extends BaseInitedPage implements IUpdatable {
 	private RoomPanel rp = null;
 	private final PageParameters p;
 
+	@SpringBean
+	private KurentoHandler kHandler;
+	@SpringBean
+	private RoomDao roomDao;
+	@SpringBean
+	private RecordingDao recDao;
+
 	public HashPage(PageParameters p) {
 		this.p = p;
 	}
@@ -81,7 +100,7 @@ public class HashPage extends BaseInitedPage implements IUpdatable {
 		getLoader().setVisible(true);
 		getHeader().setVisible(false);
 		// need to re-fetch Room object to initialize all collections
-		Room room = getBean(RoomDao.class).get(roomId);
+		Room room = roomDao.get(roomId);
 		if (room != null && !room.isDeleted()) {
 			error = false;
 			rp = new RoomPanel(CHILD_ID, room);
@@ -140,7 +159,7 @@ public class HashPage extends BaseInitedPage implements IUpdatable {
 				errorMsg = getString("1599");
 			} else if (recId != null) {
 				recContainer.setVisible(true);
-				Recording rec = getBean(RecordingDao.class).get(recId);
+				Recording rec = recDao.get(recId);
 				vi.update(null, rec);
 				vp.update(null, rec);
 				error = false;
@@ -155,18 +174,55 @@ public class HashPage extends BaseInitedPage implements IUpdatable {
 				error = false;
 			}
 			if (SWF_TYPE_SETTINGS.equals(swf.toString())) {
-				replace(new VideoSettings(PANEL_MAIN).add(new OmAjaxClientInfoBehavior() {
-					private static final long serialVersionUID = 1L;
-
-					@Override
-					protected void onClientInfo(AjaxRequestTarget target, WebClientInfo info) {
-						super.onClientInfo(target, info);
-						ExtendedClientProperties cp = (ExtendedClientProperties)info.getProperties();
-						target.appendJavaScript(
-								String.format("VideoSettings.init(%s);VideoSettings.open();"
-										, VideoSettings.getInitJson(cp, null, "noclient")));
-					}
-				}));
+				replace(new VideoSettings(PANEL_MAIN)
+					.add(new OmAjaxClientInfoBehavior() {
+						private static final long serialVersionUID = 1L;
+
+						@Override
+						protected void onClientInfo(AjaxRequestTarget target, WebClientInfo info) {
+							super.onClientInfo(target, info);
+							target.appendJavaScript(
+									String.format("VideoSettings.init(%s);VideoSettings.open();", VideoSettings.getInitJson("noclient")));
+						}
+					}, new WebSocketBehavior() { //This WS will not be created in room
+						private static final long serialVersionUID = 1L;
+
+						@Override
+						protected void onMessage(WebSocketRequestHandler handler, TextMessage msg) {
+							final JSONObject m;
+							try {
+								m = new JSONObject(msg.getText());
+								if (KURENTO_TYPE.equals(m.optString("type"))) {
+									kHandler.onMessage(null, m);
+								}
+							} catch (Exception e) {
+								//no-op
+							}
+						}
+
+						@Override
+						protected void onAbort(AbortedMessage msg) {
+							super.onAbort(msg);
+							closeHandler(msg);
+						}
+
+						@Override
+						protected void onClose(ClosedMessage msg) {
+							super.onClose(msg);
+							closeHandler(msg);
+						}
+
+						@Override
+						protected void onError(WebSocketRequestHandler handler, ErrorMessage msg) {
+							super.onError(handler, msg);
+							closeHandler(msg);
+						}
+
+						private void closeHandler(AbstractClientMessage msg) {
+							log.debug("HashPage::WebSocketBehavior::closeHandler {}", msg);
+							//TODO FIXME perform Kurento clean-up (is this necessary???)
+						}
+					}));
 				error = false;
 			}
 		}
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
index 28e144d..4b8a43a 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
@@ -129,7 +129,7 @@ public class RoomPanel extends BasePanel {
 					, cp.getRemoteAddress()
 					, "" + r.getId());
 			Client _c = getClient();
-			JSONObject options = VideoSettings.getInitJson(cp, r.getId(), _c.getSid())
+			JSONObject options = VideoSettings.getInitJson(_c.getSid())
 					.put("uid", _c.getUid())
 					.put("rights", _c.toJson(true).getJSONArray("rights"))
 					.put("interview", interview)
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/VideoSettings.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/VideoSettings.java
index afcc981..6278e5a 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/VideoSettings.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/VideoSettings.java
@@ -18,27 +18,21 @@
  */
 package org.apache.openmeetings.web.room;
 
+import static org.apache.openmeetings.util.OpenmeetingsVariables.getRoomSettings;
 import static org.apache.wicket.RuntimeConfigurationType.DEVELOPMENT;
 
-import java.net.URL;
-
-import org.apache.openmeetings.util.OmFileHelper;
 import org.apache.openmeetings.web.app.Application;
-import org.apache.openmeetings.web.util.ExtendedClientProperties;
 import org.apache.wicket.markup.head.IHeaderResponse;
 import org.apache.wicket.markup.head.JavaScriptHeaderItem;
 import org.apache.wicket.markup.head.PriorityHeaderItem;
 import org.apache.wicket.markup.html.panel.Panel;
 import org.apache.wicket.request.resource.JavaScriptResourceReference;
 import org.apache.wicket.request.resource.ResourceReference;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import com.github.openjson.JSONObject;
 
 public class VideoSettings extends Panel {
 	private static final long serialVersionUID = 1L;
-	private static final Logger log = LoggerFactory.getLogger(VideoSettings.class);
 	private static final ResourceReference SETTINGS_JS_REFERENCE = new JavaScriptResourceReference(VideoSettings.class, "settings.js");
 	public static final String URL = "url";
 	public static final String FALLBACK = "fallback";
@@ -53,71 +47,9 @@ public class VideoSettings extends Panel {
 		response.render(new PriorityHeaderItem(JavaScriptHeaderItem.forReference(SETTINGS_JS_REFERENCE)));
 	}
 
-	/* FIXME TODO
-	private static String getUri(String protocol, String host, Object port, String app) {
-		return String.format("%s://%s:%s/%s", protocol, host, port, app);
-	}
-	*/
-
-	public static JSONObject getInitJson(ExtendedClientProperties cp, Long roomId, String sid) {
-		String scope = roomId == null ? OmFileHelper.HIBERNATE : String.valueOf(roomId);
-		//FIXME TODO JSONObject gs = OpenmeetingsVariables.getRoomSettings();
-		JSONObject s = new JSONObject()//FIXME TODO new JSONObject(gs.toString())
+	public static JSONObject getInitJson(String sid) {
+		return new JSONObject(getRoomSettings().toString())
 				.put("sid", sid)
-				.put("debug", DEVELOPMENT == Application.get().getConfigurationType())
-				.put("wmode", cp.isBrowserInternetExplorer() && cp.getBrowserVersionMajor() == 11 ? "opaque" : "direct");
-		try {
-			URL url = new URL(cp.getCodebase());
-			String path = url.getPath();
-			path = path.substring(1, path.indexOf('/', 2) + 1) + scope;
-			/* FIXME TODO
-			String host = getHost(roomId, url.getHost());
-			int port = url.getPort() > -1 ? url.getPort() : url.getDefaultPort();
-			if (gs.getBoolean(FLASH_SECURE)) {
-				s.put(URL, getUri("rtmps", host, gs.getString(FLASH_SSL_PORT), path));
-				s.put(FALLBACK, getUri("rtmps", host, port, path));
-			} else {
-				s.put(URL, getUri("rtmp", host, gs.getString(FLASH_PORT), path));
-				s.put(FALLBACK, getUri("rtmpt", host, port, path));
-			}
-			*/
-		} catch (Exception e) {
-			log.error("Error while constructing video settings parameters", e);
-		}
-		return s;
-	}
-
-	/* FIXME TODO
-	private static String getHost(Long roomId, String _host) {
-		if (roomId == null) {
-			return _host;
-		}
-		long minimum = -1;
-		Member result = null;
-		Map<Member, Set<Long>> activeRoomsMap = new HashMap<>();
-		List<Member> servers = Application.get().getServers();
-		if (servers.size() > 1) {
-			for (Member m : servers) {
-				String serverId = m.getStringAttribute(NAME_ATTR_KEY);
-				Set<Long> roomIds = getBean(StreamClientManager.class).getActiveRoomIds(serverId);
-				if (roomIds.contains(roomId)) {
-					// if the room is already opened on a server, redirect the user to that one,
-					log.debug("Room is already opened on a server {}", m.getAddress());
-					return m.getAddress().getHost();
-				}
-				activeRoomsMap.put(m, roomIds);
-			}
-			for (Map.Entry<Member, Set<Long>> entry : activeRoomsMap.entrySet()) {
-				Set<Long> roomIds = entry.getValue();
-				long capacity = getBean(RoomDao.class).getRoomsCapacityByIds(roomIds);
-				if (minimum < 0 || capacity < minimum) {
-					minimum = capacity;
-					result = entry.getKey();
-				}
-				log.debug("Checking server: {} Number of rooms {} RoomIds: {} max(Sum): {}", entry.getKey(), roomIds.size(), roomIds, capacity);
-			}
-		}
-		return result == null ? _host : result.getAddress().getHost();
+				.put("debug", DEVELOPMENT == Application.get().getConfigurationType());
 	}
-	*/
 }
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/StartSharingButton.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/StartSharingButton.java
index 9870802..5b65676 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/StartSharingButton.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/StartSharingButton.java
@@ -99,7 +99,7 @@ public class StartSharingButton extends OmButton {
 			Client c = getBean(ClientManager.class).get(uid);
 			String sid = c.getSid();
 			Long roomId = c.getRoom().getId();
-			JSONObject s = VideoSettings.getInitJson(WebSession.get().getExtendedProperties(), roomId, sid);
+			JSONObject s = VideoSettings.getInitJson(sid);
 			String _url = s.getString(VideoSettings.URL);
 			Room room = getBean(RoomDao.class).get(roomId);
 			StreamClientManager streamClientManager = getBean(StreamClientManager.class);
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/settings.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/settings-base.js
similarity index 68%
rename from openmeetings-web/src/main/java/org/apache/openmeetings/web/room/settings.js
rename to openmeetings-web/src/main/java/org/apache/openmeetings/web/room/settings-base.js
index d858ea0..3a07d64 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/settings.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/settings-base.js
@@ -1,6 +1,6 @@
 /* Licensed under the Apache License, Version 2.0 (the "License") http://www.apache.org/licenses/LICENSE-2.0 */
 var VideoSettings = (function() {
-	let vs, lm, s, cam, mic, res, o
+	let vs, lm, s, cam, mic, res, o, rtcPeer, offerSdp
 		, vidScroll, vid, recBtn, playBtn, recAllowed = false;
 	function _load() {
 		s = Settings.load();
@@ -31,6 +31,11 @@ var VideoSettings = (function() {
 				vid[0].srcObject = null;
 			}
 		}
+		if (!!rtcPeer) {
+			rtcPeer.dispose();
+		}
+		offerSdp = null;
+		Wicket.Event.unsubscribe("/websocket/message", _onWsMessage);
 	}
 	function _init(options) {
 		o = JSON.parse(JSON.stringify(options));
@@ -43,7 +48,19 @@ var VideoSettings = (function() {
 		vid = vidScroll.find('video');
 		recBtn = vs.find('.rec-start').click(function() {
 			recBtn.prop('disabled', true).button('refresh'); //TODO disable drop-downs
-			//FIXME TODO swf.startRec();
+			cam.prop('disabled', true);
+			mic.prop('disabled', true);
+			res.prop('disabled', true);
+
+			console.info('Invoking SDP offer callback function');
+			const cnts = _constraints();
+			OmUtil.sendMessage({
+				id : 'testStart'
+				, type: 'kurento'
+				, sdpOffer: offerSdp
+				, video: cnts.video !== false
+				, audio: cnts.audio !== false
+			});
 		});
 		playBtn = vs.find('.play').click(function() {
 			//FIXME TODO swf.play();
@@ -98,49 +115,74 @@ var VideoSettings = (function() {
 	function _updateRec() {
 		recBtn.prop('disabled', !recAllowed && (s.video.cam > -1 || s.video.mic > -1)).button('refresh');
 	}
-	function _readValues() {
-		const v = cam.find('option:selected')
-			, m = mic.find('option:selected')
-			, o = res.find('option:selected').data();
-		s.video.cam = 1 * cam.val();
-		s.video.mic = 1 * mic.val();
-		s.video.width = o.width;
-		s.video.height = o.height;
-		vid.width(o.width).height(o.height);
-		vidScroll.scrollLeft(Math.max(0, s.video.width / 2 - 150))
-			.scrollTop(Math.max(0, s.video.height / 2 - 110));
-		_clear();
-		let enabled = false;
-		const constraints = {};
+	function _constraints() {
+		const cnts = {}
+			, v = cam.find('option:selected')
+			, m = mic.find('option:selected');
 		//TODO add check if constraint is supported
 		if (s.video.cam > -1) {
-			constraints.video = {
-				width: o.width
-				, height: o.height
+			cnts.video = {
+				width: s.video.width
+				, height: s.video.height
 				, deviceId: { exact: v.data('device-id')  }
 				, frameRate: { max: 30 }
 			};
-			enabled = true;
 		} else {
-			constraints.video = false;
+			cnts.video = false;
 		}
 		//TODO enable audio for recordings only
 		if (s.video.mic > -1) {
-			constraints.audio = {
+			//TODO remove hardcodings
+			cnts.audio = {
 				sampleSize: 22
+				, deviceId: { exact: m.data('device-id')  }
 				, echoCancellation: true
 			};
-			enabled = true;
 		} else {
-			constraints.audio = false;
+			cnts.audio = false;
 		}
-		if (enabled) {
-			navigator.mediaDevices.getUserMedia(constraints)
-				.then(function(stream) {
-					vid[0].srcObject = stream;
-				})
-				.catch(function(err) {
-					_error(err.name + ": " + err.message);
+		return cnts;
+	}
+	function _readValues() {
+		const v = cam.find('option:selected')
+			, m = mic.find('option:selected')
+			, o = res.find('option:selected').data();
+		s.video.cam = 1 * cam.val();
+		s.video.mic = 1 * mic.val();
+		s.video.width = o.width;
+		s.video.height = o.height;
+		vid.width(o.width).height(o.height);
+		vidScroll.scrollLeft(Math.max(0, s.video.width / 2 - 150))
+			.scrollTop(Math.max(0, s.video.height / 2 - 110));
+		_clear();
+		const cnts = _constraints();
+		if (cnts.video !== false || cnts.audio !== false) {
+			const options = {
+				localVideo: vid[0]
+				, mediaConstraints: cnts
+				, onicecandidate: function (candidate) {
+					console.log('Local candidate' + JSON.stringify(candidate));
+					OmUtil.sendMessage({
+						id : 'onTestIceCandidate'
+						, type: 'kurento'
+						, candidate: candidate
+					});
+				}
+
+			}
+			rtcPeer = new kurentoUtils.WebRtcPeer.WebRtcPeerSendonly(
+				options
+				, function(error) {
+					if (error) {
+						return _error(error);
+					}
+					rtcPeer.generateOffer(function(error, _offerSdp) {
+						if (error) {
+							return console.error('Error generating the offer');
+						}
+						offerSdp = _offerSdp;
+						_allowRec(true);
+					});
 				});
 		}
 		_updateRec();
@@ -159,7 +201,7 @@ var VideoSettings = (function() {
 	}
 	function _error(msg) {
 		//FIXME TODO status field
-		console.error(msg);
+		return console.error(msg);
 	}
 	function _initDevices() {
 		if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) {
@@ -222,17 +264,55 @@ var VideoSettings = (function() {
 			});
 	}
 	function _open() {
+		Wicket.Event.subscribe("/websocket/message", _onWsMessage);
 		recAllowed = false;
 		vs.dialog('open');
 		_load();
 		_initDevices();
 	}
+	//FIXME TODO, try to unify this
+	function _onWsMessage(jqEvent, msg) {
+		try {
+			if (msg instanceof Blob) {
+				return; //ping
+			}
+			const m = jQuery.parseJSON(msg);
+			if (m && 'kurento' === m.type) {
+				console.info('Received message: ' + m);
+				/* FIXME TODO
+				switch (m.id) {
+					case 'broadcast':
+						onBroadcast(m);
+						break;
+					case 'videoResponse':
+						onVideoResponse(m);
+						break;
+					case 'iceCandidate':
+						{
+							const w = $('#' + VideoUtil.getVid(m.uid))
+								, v = w.data()
+
+							v.getPeer().addIceCandidate(m.candidate, function (error) {
+								if (error) {
+									console.error("Error adding candidate: " + error);
+									return;
+								}
+							});
+						}
+						break;
+					default:
+						console.error('Unrecognized message', m);
+				}
+				*/
+			}
+		} catch (err) {
+			//no-op
+			console.error(err);
+		}
+	}
 	return {
 		init: _init
 		, open: _open
-		, allowRec: _allowRec
-		, allowPlay: _allowPlay
-		, micActivity: _micActivity
 		, close: function() { vs.dialog('close'); }
 		, load: _load
 		, save: _save
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/video.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/video.js
index 5f6af9e..af41d52 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/video.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/video.js
@@ -173,7 +173,9 @@ var Video = (function() {
 		}
 		v.on("remove", function () {
 			console.log('Disposing participant ' + c.uid);
-			rtcPeer.dispose();
+			if (!!rtcPeer) {
+				rtcPeer.dispose();
+			}
 		});
 		vc = v.find('.video');
 		vc.width(_w).height(_h);

-- 
To stop receiving notification emails like this one, please contact
solomax@apache.org.