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/10/11 10:31:56 UTC

[openmeetings] branch master updated: [OPENMEETINGS-1649] settings dialog made more user friendly

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 4cbb622  [OPENMEETINGS-1649] settings dialog made more user friendly
4cbb622 is described below

commit 4cbb622b9743dbce69ac7b069360e6e6274b07e1
Author: Maxim Solodovnik <so...@gmail.com>
AuthorDate: Thu Oct 11 17:31:40 2018 +0700

    [OPENMEETINGS-1649] settings dialog made more user friendly
---
 .../openmeetings/core/remote/KurentoHandler.java   |   9 +
 .../apache/openmeetings/web/room/raw-settings.js   | 240 ++++++++++++---------
 .../apache/openmeetings/web/room/raw-video-util.js |   2 +-
 .../org/apache/openmeetings/web/room/raw-video.js  |  72 ++++---
 4 files changed, 191 insertions(+), 132 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 616b12b..e25f80b 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
@@ -184,6 +184,15 @@ public class KurentoHandler {
 			}
 			log.debug("Incoming message from user with ID '{}': {}", c.getUserId(), msg);
 			switch (cmdId) {
+				case "devicesAltered":
+					if (!msg.getBoolean("audio") && c.hasActivity(Client.Activity.broadcastA)) {
+						c.remove(Client.Activity.broadcastA);
+					}
+					if (!msg.getBoolean("video") && c.hasActivity(Client.Activity.broadcastV)) {
+						c.remove(Client.Activity.broadcastV);
+					}
+					WebSocketHelper.sendRoom(new TextRoomMessage(c.getRoomId(), cm.update(c), RoomMessage.Type.rightUpdated, c.getUid()));
+					break;
 				case "toggleActivity":
 					toggleActivity(c, Client.Activity.valueOf(msg.getString("activity")));
 					break;
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/raw-settings.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/raw-settings.js
index 0c43819..ead26ca 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/raw-settings.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/raw-settings.js
@@ -53,9 +53,12 @@ var MicLevel = (function() {
 	}
 	function _dispose() {
 		if (!!ctx) {
-			mic.disconnect(script);
-			script.disconnect(ctx.destination);
+			VideoUtil.cleanStream(mic.mediaStream);
+			mic.disconnect();
+			ctx.destination.disconnect();
+			script.disconnect();
 			script.onaudioprocess = null;
+			ctx.close();
 			ctx = null;
 		}
 	}
@@ -65,6 +68,7 @@ var MicLevel = (function() {
 	};
 });
 var VideoSettings = (function() {
+	const DEV_AUDIO = 'audioinput', DEV_VIDEO = 'videoinput';
 	let vs, lm, s, cam, mic, res, o, rtcPeer, timer
 		, vidScroll, vid, recBtn, playBtn, recAllowed = false
 		, level;
@@ -222,38 +226,39 @@ var VideoSettings = (function() {
 	}
 	//each bool OR https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints
 	// min/ideal/max/exact/mandatory can also be used
-	function _constraints(c) {
-		const cnts = {};
-		//TODO add check if constraint is supported
-		if (false === o.audioOnly && VideoUtil.hasVideo(c) && s.video.cam > -1) {
-			cnts.video = {
-				width: s.video.width
-				, height: s.video.height
-				, frameRate: o.camera.fps
-			};
-			if (!!s.video.camDevice) {
-				cnts.video.deviceId = {
-					ideal: s.video.camDevice
+	function _constraints(c, callback) {
+		_getDevConstraints(function(devCnts){
+			const cnts = {};
+			if (devCnts.video && false === o.audioOnly && VideoUtil.hasVideo(c) && s.video.cam > -1) {
+				cnts.video = {
+					width: s.video.width
+					, height: s.video.height
+					, frameRate: o.camera.fps
 				};
+				if (!!s.video.camDevice) {
+					cnts.video.deviceId = {
+						ideal: s.video.camDevice
+					};
+				}
+			} else {
+				cnts.video = false;
 			}
-		} else {
-			cnts.video = false;
-		}
-		if (VideoUtil.hasAudio(c) && s.video.mic > -1) {
-			cnts.audio = {
-				sampleRate: o.microphone.rate
-				, echoCancellation: o.microphone.echo
-				, noiseSuppression: o.microphone.noise
-			};
-			if (!!s.video.micDevice) {
-				cnts.audio.deviceId = {
-					ideal: s.video.micDevice
+			if (devCnts.audio && VideoUtil.hasAudio(c) && s.video.mic > -1) {
+				cnts.audio = {
+					sampleRate: o.microphone.rate
+					, echoCancellation: o.microphone.echo
+					, noiseSuppression: o.microphone.noise
 				};
+				if (!!s.video.micDevice) {
+					cnts.audio.deviceId = {
+						ideal: s.video.micDevice
+					};
+				}
+			} else {
+				cnts.audio = false;
 			}
-		} else {
-			cnts.audio = false;
-		}
-		return cnts;
+			callback(cnts);
+		});
 	}
 	function _readValues(msg, func) {
 		const v = cam.find('option:selected')
@@ -269,35 +274,36 @@ var VideoSettings = (function() {
 		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 = VideoUtil.addIceServers({
-				localVideo: vid[0]
-				, mediaConstraints: cnts
-			}, msg);
-			rtcPeer = new kurentoUtils.WebRtcPeer.WebRtcPeerSendonly(
-				options
-				, function(error) {
-					if (error) {
-						return OmUtil.error(error);
-					}
-					level = MicLevel();
-					level.meter(rtcPeer, _micActivity, OmUtil.error);
-					rtcPeer.generateOffer(function(error, _offerSdp) {
+		_constraints(null, function(cnts) {
+			if (cnts.video !== false || cnts.audio !== false) {
+				const options = VideoUtil.addIceServers({
+					localVideo: vid[0]
+					, mediaConstraints: cnts
+				}, msg);
+				rtcPeer = new kurentoUtils.WebRtcPeer.WebRtcPeerSendonly(
+					options
+					, function(error) {
 						if (error) {
-							return OmUtil.error('Error generating the offer');
-						}
-						if (typeof(func) === 'function') {
-							func(_offerSdp, cnts);
-						} else {
-							_allowRec(true);
+							return OmUtil.error(error);
 						}
+						level = MicLevel();
+						level.meter(rtcPeer, _micActivity, OmUtil.error);
+						rtcPeer.generateOffer(function(error, _offerSdp) {
+							if (error) {
+								return OmUtil.error('Error generating the offer');
+							}
+							if (typeof(func) === 'function') {
+								func(_offerSdp, cnts);
+							} else {
+								_allowRec(true);
+							}
+						});
 					});
-				});
-		}
-		if (!msg) {
-			_updateRec();
-		}
+			}
+			if (!msg) {
+				_updateRec();
+			}
+		});
 	}
 
 	function _allowRec(allow) {
@@ -313,7 +319,12 @@ var VideoSettings = (function() {
 	}
 	function _setLoading(el) {
 		el.find('option').remove();
-		el.append(OmUtil.tmpl('#settings-option-loading'));//!settings-option-disabled
+		el.append(OmUtil.tmpl('#settings-option-loading'));
+		el.iconselectmenu('refresh');
+	}
+	function _setDisabled(el) {
+		el.find('option').remove();
+		el.append(OmUtil.tmpl('#settings-option-disabled'));
 		el.iconselectmenu('refresh');
 	}
 	function _setSelectedDevice(dev, devIdx) {
@@ -323,6 +334,20 @@ var VideoSettings = (function() {
 		}
 		o.prop('selected', true);
 	}
+	function _getDevConstraints(callback) {
+		navigator.mediaDevices.enumerateDevices()
+			.then(function(devices) {
+				const devCnts = {audio: false, video: false};
+				devices.forEach(function(device) {
+					if (DEV_AUDIO === device.kind) {
+						devCnts.audio = true;
+					} else if (DEV_VIDEO === device.kind) {
+						devCnts.video = true;
+					}
+				});
+				callback(devCnts);
+			})
+	}
 	function _initDevices() {
 		if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) {
 			OmUtil.error('enumerateDevices() not supported.');
@@ -330,55 +355,62 @@ var VideoSettings = (function() {
 		}
 		_setLoading(cam);
 		_setLoading(mic);
-		navigator.mediaDevices.getUserMedia({video:true, audio:true})
-			.then(function(stream) {
-				const devices = navigator.mediaDevices.enumerateDevices()
-					.then(function(devices) {
-						_clear(stream);
-						return devices;
-					})
-					.catch(function(err) {
-						_clear(stream);
-						throw err;
+		_getDevConstraints(function(devCnts) {
+			if (!devCnts.audio && !devCnts.video) {
+				_setDisabled(cam);
+				_setDisabled(mic);
+				return;
+			}
+			navigator.mediaDevices.getUserMedia(devCnts)
+				.then(function(stream) {
+					const devices = navigator.mediaDevices.enumerateDevices()
+						.then(function(devices) {
+							_clear(stream);
+							return devices;
+						})
+						.catch(function(err) {
+							_clear(stream);
+							throw err;
+						});
+					return devices;
+				})
+				.then(function(devices) {
+					let cCount = 0, mCount = 0;
+					_load();
+					_setDisabled(cam);
+					_setDisabled(mic);
+					devices.forEach(function(device) {
+						if (DEV_AUDIO === device.kind) {
+							const o = $('<option></option>').attr('value', mCount).text(device.label)
+								.data('device-id', device.deviceId);
+							mic.append(o);
+							mCount++;
+						} else if (DEV_VIDEO === device.kind) {
+							const o = $('<option></option>').attr('value', cCount).text(device.label)
+								.data('device-id', device.deviceId);
+							cam.append(o);
+							cCount++;
+						}
 					});
-				return devices;
-			})
-			.then(function(devices) {
-				let cCount = 0, mCount = 0;
-				_load();
-				cam.find('option').remove();
-				cam.append(OmUtil.tmpl('#settings-option-disabled'));
-				mic.find('option').remove();
-				mic.append(OmUtil.tmpl('#settings-option-disabled'));
-				devices.forEach(function(device) {
-					if ('audioinput' === device.kind) {
-						const o = $('<option></option>').attr('value', mCount).text(device.label)
-							.data('device-id', device.deviceId);
-						mic.append(o);
-						mCount++;
-					} else if ('videoinput' === device.kind) {
-						const o = $('<option></option>').attr('value', cCount).text(device.label)
-							.data('device-id', device.deviceId);
-						cam.append(o);
-						cCount++;
-					}
-				});
-				_setSelectedDevice(cam, s.video.cam);
-				_setSelectedDevice(mic, s.video.mic);
-				cam.iconselectmenu('refresh');
-				mic.iconselectmenu('refresh');
-				res.find('option').each(function() {
-					const o = $(this).data();
-					if (o.width === s.video.width && o.height === s.video.height) {
-						$(this).prop('selected', true);
-						return false;
-					}
+					_setSelectedDevice(cam, s.video.cam);
+					_setSelectedDevice(mic, s.video.mic);
+					cam.iconselectmenu('refresh');
+					mic.iconselectmenu('refresh');
+					res.find('option').each(function() {
+						const o = $(this).data();
+						if (o.width === s.video.width && o.height === s.video.height) {
+							$(this).prop('selected', true);
+							return false;
+						}
+					});
+					_readValues();
+				})
+				.catch(function(err) {
+					_setDisabled(cam);
+					_setDisabled(mic);
+					OmUtil.error(err);
 				});
-				_readValues();
-			})
-			.catch(function(err) {
-				OmUtil.error(err);
-			});
+		});
 	}
 	function _open() {
 		Wicket.Event.subscribe('/websocket/message', _onWsMessage);
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/raw-video-util.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/raw-video-util.js
index 18b740f..35bed4e 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/raw-video-util.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/raw-video-util.js
@@ -114,7 +114,7 @@ var VideoUtil = (function() {
 	function _cleanPeer(peer) {
 		if (!!peer) {
 			const pc = peer.peerConnection;
-			if (!!pc) {
+			if (!!pc && !!pc.getLocalStreams()) {
 				pc.getLocalStreams().forEach(function(stream) {
 					_cleanStream(stream);
 				});
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/raw-video.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/raw-video.js
index 1a14d3c..b05b680 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/raw-video.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/raw-video.js
@@ -45,28 +45,40 @@ var Video = (function() {
 		}
 	}
 	function _createSendPeer(msg) {
-		const constraints = VideoSettings.constraints(c);
-		navigator.mediaDevices.getUserMedia(constraints)
-			.then(function(stream) {
-				if (stream.getAudioTracks().length !== 0) {
-					vol.show();
-					lm = vc.find('.level-meter')
-						.kendoProgressBar({ value: 0, showStatus: false, orientation: 'vertical' });
-					lm.height(vc.height() - 10);
-					aCtx = new AudioContext();
-					gainNode = aCtx.createGain();
-					aSrc = aCtx.createMediaStreamSource(stream);
-					aSrc.connect(gainNode);
-					gainNode.connect(aCtx.destination);
-					_handleVolume(lastVolume);
-				}
-				const options = VideoUtil.addIceServers({
-					localVideo: video[0]
-					, videoStream: stream
-					, mediaConstraints: constraints
-					, onicecandidate: self.onIceCandidate
-				}, msg);
-				rtcPeer = new kurentoUtils.WebRtcPeer.WebRtcPeerSendonly(
+		VideoSettings.constraints(c, function(cnts) {
+			if ((VideoUtil.hasVideo(c) && !cnts.video) || (VideoUtil.hasAudio(c) && !cnts.audio)) {
+				VideoManager.sendMessage({
+					id : 'devicesAltered'
+					, audio: !!cnts.audio
+					, video: !!cnts.video
+				});
+			}
+			if (!cnts.audio && !cnts.video) {
+				OmUtil.error("Requested devices are not available");
+				VideoManager.close(c.uid)
+				return;
+			}
+			navigator.mediaDevices.getUserMedia(cnts)
+				.then(function(stream) {
+					if (stream.getAudioTracks().length !== 0) {
+						vol.show();
+						lm = vc.find('.level-meter')
+							.kendoProgressBar({ value: 0, showStatus: false, orientation: 'vertical' });
+						lm.height(vc.height() - 10);
+						aCtx = new AudioContext();
+						gainNode = aCtx.createGain();
+						aSrc = aCtx.createMediaStreamSource(stream);
+						aSrc.connect(gainNode);
+						gainNode.connect(aCtx.destination);
+						_handleVolume(lastVolume);
+					}
+					const options = VideoUtil.addIceServers({
+						localVideo: video[0]
+						, videoStream: stream
+						, mediaConstraints: cnts
+						, onicecandidate: self.onIceCandidate
+					}, msg);
+					rtcPeer = new kurentoUtils.WebRtcPeer.WebRtcPeerSendonly(
 						options
 						, function (error) {
 							if (error) {
@@ -85,10 +97,11 @@ var Video = (function() {
 								});
 							});
 						});
-			})
-			.catch(function(err) {
-				OmUtil.error(err);
-			});
+				})
+				.catch(function(err) {
+					OmUtil.error(err);
+				});
+		});
 	}
 	function _createResvPeer(msg) {
 		const options = VideoUtil.addIceServers({
@@ -348,13 +361,14 @@ var Video = (function() {
 	}
 	function _cleanup() {
 		OmUtil.log('Disposing participant ' + c.uid);
-		VideoUtil.cleanPeer(rtcPeer);
 		if (!!gainNode) {
 			gainNode.disconnect();
+			gainNode = null;
 		}
 		if (!!aSrc) {
 			VideoUtil.cleanStream(aSrc.mediaStream);
 			aSrc.disconnect();
+			aSrc = null;
 		}
 		if (!!aCtx) {
 			if (!!aCtx.destination) {
@@ -364,7 +378,10 @@ var Video = (function() {
 			aCtx = null;
 		}
 		if (!!video && video.length > 0) {
+			VideoUtil.cleanStream(video[0].srcObject);
 			video[0].srcObject = null;
+			video.remove();
+			video = null;
 		}
 		if (!!lm && lm.length > 0) {
 			_micActivity(0);
@@ -374,6 +391,7 @@ var Video = (function() {
 			level.dispose();
 			level = null;
 		}
+		VideoUtil.cleanPeer(rtcPeer);
 		vc.find('audio,video').remove();
 	}