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 2019/03/11 07:03:05 UTC
[openmeetings] branch master updated: [OPENMEETINGS-2029] camera
should work is Safari
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 8d8fac9 [OPENMEETINGS-2029] camera should work is Safari
8d8fac9 is described below
commit 8d8fac9ac567b167b2d91c48273dbb5666ae6d71
Author: Maxim Solodovnik <so...@gmail.com>
AuthorDate: Mon Mar 11 14:02:54 2019 +0700
[OPENMEETINGS-2029] camera should work is Safari
---
.../apache/openmeetings/web/room/kurento-utils.js | 906 +++++++++++++--------
.../apache/openmeetings/web/room/raw-settings.js | 22 +-
2 files changed, 604 insertions(+), 324 deletions(-)
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/kurento-utils.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/kurento-utils.js
index bfc983e..f4bad72 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/kurento-utils.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/kurento-utils.js
@@ -206,6 +206,24 @@ function WebRtcPeer(mode, options, callback) {
}
}
}
+ if (!pc.getLocalStreams && pc.getSenders) {
+ pc.getLocalStreams = function() {
+ var stream = new MediaStream();
+ pc.getSenders().forEach(function(sender) {
+ stream.addTrack(sender.track);
+ });
+ return [stream];
+ };
+ }
+ if (!pc.getRemoteStreams && pc.getReceivers) {
+ pc.getRemoteStreams = function() {
+ var stream = new MediaStream();
+ pc.getReceivers().forEach(function(sender) {
+ stream.addTrack(sender.track);
+ });
+ return [stream];
+ };
+ }
pc.addEventListener('icecandidate', function (event) {
var candidate = event.candidate;
if (EventEmitter.listenerCount(self, 'icecandidate') || EventEmitter.listenerCount(self, 'candidategatheringdone')) {
@@ -381,10 +399,14 @@ function WebRtcPeer(mode, options, callback) {
self.showLocalVideo();
}
if (videoStream) {
- pc.addStream(videoStream);
+ videoStream.getTracks().forEach(function(track) {
+ pc.addTrack(track);
+ });
}
if (audioStream) {
- pc.addStream(audioStream);
+ audioStream.getTracks().forEach(function(track) {
+ pc.addTrack(track);
+ });
}
var browser = parser.getBrowser();
if (mode === 'sendonly' && (browser.name === 'Chrome' || browser.name === 'Chromium') && browser.major === 39) {
@@ -537,317 +559,13 @@ exports.WebRtcPeerSendonly = WebRtcPeerSendonly;
exports.WebRtcPeerSendrecv = WebRtcPeerSendrecv;
exports.hark = harkUtils;
exports.browser = browser;
-},{"events":4,"freeice":5,"hark":8,"inherits":9,"kurento-browser-extensions":10,"merge":11,"sdp-translator":18,"ua-parser-js":21,"uuid":23}],2:[function(require,module,exports){
+},{"events":7,"freeice":4,"hark":8,"inherits":9,"kurento-browser-extensions":10,"merge":11,"sdp-translator":18,"ua-parser-js":21,"uuid":23}],2:[function(require,module,exports){
if (window.addEventListener)
module.exports = require('./index');
},{"./index":3}],3:[function(require,module,exports){
var WebRtcPeer = require('./WebRtcPeer');
exports.WebRtcPeer = WebRtcPeer;
},{"./WebRtcPeer":1}],4:[function(require,module,exports){
-// Copyright Joyent, Inc. and other Node contributors.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to permit
-// persons to whom the Software is furnished to do so, subject to the
-// following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-function EventEmitter() {
- this._events = this._events || {};
- this._maxListeners = this._maxListeners || undefined;
-}
-module.exports = EventEmitter;
-
-// Backwards-compat with node 0.10.x
-EventEmitter.EventEmitter = EventEmitter;
-
-EventEmitter.prototype._events = undefined;
-EventEmitter.prototype._maxListeners = undefined;
-
-// By default EventEmitters will print a warning if more than 10 listeners are
-// added to it. This is a useful default which helps finding memory leaks.
-EventEmitter.defaultMaxListeners = 10;
-
-// Obviously not all Emitters should be limited to 10. This function allows
-// that to be increased. Set to zero for unlimited.
-EventEmitter.prototype.setMaxListeners = function(n) {
- if (!isNumber(n) || n < 0 || isNaN(n))
- throw TypeError('n must be a positive number');
- this._maxListeners = n;
- return this;
-};
-
-EventEmitter.prototype.emit = function(type) {
- var er, handler, len, args, i, listeners;
-
- if (!this._events)
- this._events = {};
-
- // If there is no 'error' event listener then throw.
- if (type === 'error') {
- if (!this._events.error ||
- (isObject(this._events.error) && !this._events.error.length)) {
- er = arguments[1];
- if (er instanceof Error) {
- throw er; // Unhandled 'error' event
- } else {
- // At least give some kind of context to the user
- var err = new Error('Uncaught, unspecified "error" event. (' + er + ')');
- err.context = er;
- throw err;
- }
- }
- }
-
- handler = this._events[type];
-
- if (isUndefined(handler))
- return false;
-
- if (isFunction(handler)) {
- switch (arguments.length) {
- // fast cases
- case 1:
- handler.call(this);
- break;
- case 2:
- handler.call(this, arguments[1]);
- break;
- case 3:
- handler.call(this, arguments[1], arguments[2]);
- break;
- // slower
- default:
- args = Array.prototype.slice.call(arguments, 1);
- handler.apply(this, args);
- }
- } else if (isObject(handler)) {
- args = Array.prototype.slice.call(arguments, 1);
- listeners = handler.slice();
- len = listeners.length;
- for (i = 0; i < len; i++)
- listeners[i].apply(this, args);
- }
-
- return true;
-};
-
-EventEmitter.prototype.addListener = function(type, listener) {
- var m;
-
- if (!isFunction(listener))
- throw TypeError('listener must be a function');
-
- if (!this._events)
- this._events = {};
-
- // To avoid recursion in the case that type === "newListener"! Before
- // adding it to the listeners, first emit "newListener".
- if (this._events.newListener)
- this.emit('newListener', type,
- isFunction(listener.listener) ?
- listener.listener : listener);
-
- if (!this._events[type])
- // Optimize the case of one listener. Don't need the extra array object.
- this._events[type] = listener;
- else if (isObject(this._events[type]))
- // If we've already got an array, just append.
- this._events[type].push(listener);
- else
- // Adding the second element, need to change to array.
- this._events[type] = [this._events[type], listener];
-
- // Check for listener leak
- if (isObject(this._events[type]) && !this._events[type].warned) {
- if (!isUndefined(this._maxListeners)) {
- m = this._maxListeners;
- } else {
- m = EventEmitter.defaultMaxListeners;
- }
-
- if (m && m > 0 && this._events[type].length > m) {
- this._events[type].warned = true;
- console.error('(node) warning: possible EventEmitter memory ' +
- 'leak detected. %d listeners added. ' +
- 'Use emitter.setMaxListeners() to increase limit.',
- this._events[type].length);
- if (typeof console.trace === 'function') {
- // not supported in IE 10
- console.trace();
- }
- }
- }
-
- return this;
-};
-
-EventEmitter.prototype.on = EventEmitter.prototype.addListener;
-
-EventEmitter.prototype.once = function(type, listener) {
- if (!isFunction(listener))
- throw TypeError('listener must be a function');
-
- var fired = false;
-
- function g() {
- this.removeListener(type, g);
-
- if (!fired) {
- fired = true;
- listener.apply(this, arguments);
- }
- }
-
- g.listener = listener;
- this.on(type, g);
-
- return this;
-};
-
-// emits a 'removeListener' event iff the listener was removed
-EventEmitter.prototype.removeListener = function(type, listener) {
- var list, position, length, i;
-
- if (!isFunction(listener))
- throw TypeError('listener must be a function');
-
- if (!this._events || !this._events[type])
- return this;
-
- list = this._events[type];
- length = list.length;
- position = -1;
-
- if (list === listener ||
- (isFunction(list.listener) && list.listener === listener)) {
- delete this._events[type];
- if (this._events.removeListener)
- this.emit('removeListener', type, listener);
-
- } else if (isObject(list)) {
- for (i = length; i-- > 0;) {
- if (list[i] === listener ||
- (list[i].listener && list[i].listener === listener)) {
- position = i;
- break;
- }
- }
-
- if (position < 0)
- return this;
-
- if (list.length === 1) {
- list.length = 0;
- delete this._events[type];
- } else {
- list.splice(position, 1);
- }
-
- if (this._events.removeListener)
- this.emit('removeListener', type, listener);
- }
-
- return this;
-};
-
-EventEmitter.prototype.removeAllListeners = function(type) {
- var key, listeners;
-
- if (!this._events)
- return this;
-
- // not listening for removeListener, no need to emit
- if (!this._events.removeListener) {
- if (arguments.length === 0)
- this._events = {};
- else if (this._events[type])
- delete this._events[type];
- return this;
- }
-
- // emit removeListener for all listeners on all events
- if (arguments.length === 0) {
- for (key in this._events) {
- if (key === 'removeListener') continue;
- this.removeAllListeners(key);
- }
- this.removeAllListeners('removeListener');
- this._events = {};
- return this;
- }
-
- listeners = this._events[type];
-
- if (isFunction(listeners)) {
- this.removeListener(type, listeners);
- } else if (listeners) {
- // LIFO order
- while (listeners.length)
- this.removeListener(type, listeners[listeners.length - 1]);
- }
- delete this._events[type];
-
- return this;
-};
-
-EventEmitter.prototype.listeners = function(type) {
- var ret;
- if (!this._events || !this._events[type])
- ret = [];
- else if (isFunction(this._events[type]))
- ret = [this._events[type]];
- else
- ret = this._events[type].slice();
- return ret;
-};
-
-EventEmitter.prototype.listenerCount = function(type) {
- if (this._events) {
- var evlistener = this._events[type];
-
- if (isFunction(evlistener))
- return 1;
- else if (evlistener)
- return evlistener.length;
- }
- return 0;
-};
-
-EventEmitter.listenerCount = function(emitter, type) {
- return emitter.listenerCount(type);
-};
-
-function isFunction(arg) {
- return typeof arg === 'function';
-}
-
-function isNumber(arg) {
- return typeof arg === 'number';
-}
-
-function isObject(arg) {
- return typeof arg === 'object' && arg !== null;
-}
-
-function isUndefined(arg) {
- return arg === void 0;
-}
-
-},{}],5:[function(require,module,exports){
/* jshint node: true */
'use strict';
@@ -955,7 +673,7 @@ var freeice = function(opts) {
};
module.exports = freeice;
-},{"./stun.json":6,"./turn.json":7,"normalice":12}],6:[function(require,module,exports){
+},{"./stun.json":5,"./turn.json":6,"normalice":12}],5:[function(require,module,exports){
module.exports=[
"stun.l.google.com:19302",
"stun1.l.google.com:19302",
@@ -972,9 +690,534 @@ module.exports=[
"stun.voxgratia.org"
]
-},{}],7:[function(require,module,exports){
+},{}],6:[function(require,module,exports){
module.exports=[]
+},{}],7:[function(require,module,exports){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+var objectCreate = Object.create || objectCreatePolyfill
+var objectKeys = Object.keys || objectKeysPolyfill
+var bind = Function.prototype.bind || functionBindPolyfill
+
+function EventEmitter() {
+ if (!this._events || !Object.prototype.hasOwnProperty.call(this, '_events')) {
+ this._events = objectCreate(null);
+ this._eventsCount = 0;
+ }
+
+ this._maxListeners = this._maxListeners || undefined;
+}
+module.exports = EventEmitter;
+
+// Backwards-compat with node 0.10.x
+EventEmitter.EventEmitter = EventEmitter;
+
+EventEmitter.prototype._events = undefined;
+EventEmitter.prototype._maxListeners = undefined;
+
+// By default EventEmitters will print a warning if more than 10 listeners are
+// added to it. This is a useful default which helps finding memory leaks.
+var defaultMaxListeners = 10;
+
+var hasDefineProperty;
+try {
+ var o = {};
+ if (Object.defineProperty) Object.defineProperty(o, 'x', { value: 0 });
+ hasDefineProperty = o.x === 0;
+} catch (err) { hasDefineProperty = false }
+if (hasDefineProperty) {
+ Object.defineProperty(EventEmitter, 'defaultMaxListeners', {
+ enumerable: true,
+ get: function() {
+ return defaultMaxListeners;
+ },
+ set: function(arg) {
+ // check whether the input is a positive number (whose value is zero or
+ // greater and not a NaN).
+ if (typeof arg !== 'number' || arg < 0 || arg !== arg)
+ throw new TypeError('"defaultMaxListeners" must be a positive number');
+ defaultMaxListeners = arg;
+ }
+ });
+} else {
+ EventEmitter.defaultMaxListeners = defaultMaxListeners;
+}
+
+// Obviously not all Emitters should be limited to 10. This function allows
+// that to be increased. Set to zero for unlimited.
+EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {
+ if (typeof n !== 'number' || n < 0 || isNaN(n))
+ throw new TypeError('"n" argument must be a positive number');
+ this._maxListeners = n;
+ return this;
+};
+
+function $getMaxListeners(that) {
+ if (that._maxListeners === undefined)
+ return EventEmitter.defaultMaxListeners;
+ return that._maxListeners;
+}
+
+EventEmitter.prototype.getMaxListeners = function getMaxListeners() {
+ return $getMaxListeners(this);
+};
+
+// These standalone emit* functions are used to optimize calling of event
+// handlers for fast cases because emit() itself often has a variable number of
+// arguments and can be deoptimized because of that. These functions always have
+// the same number of arguments and thus do not get deoptimized, so the code
+// inside them can execute faster.
+function emitNone(handler, isFn, self) {
+ if (isFn)
+ handler.call(self);
+ else {
+ var len = handler.length;
+ var listeners = arrayClone(handler, len);
+ for (var i = 0; i < len; ++i)
+ listeners[i].call(self);
+ }
+}
+function emitOne(handler, isFn, self, arg1) {
+ if (isFn)
+ handler.call(self, arg1);
+ else {
+ var len = handler.length;
+ var listeners = arrayClone(handler, len);
+ for (var i = 0; i < len; ++i)
+ listeners[i].call(self, arg1);
+ }
+}
+function emitTwo(handler, isFn, self, arg1, arg2) {
+ if (isFn)
+ handler.call(self, arg1, arg2);
+ else {
+ var len = handler.length;
+ var listeners = arrayClone(handler, len);
+ for (var i = 0; i < len; ++i)
+ listeners[i].call(self, arg1, arg2);
+ }
+}
+function emitThree(handler, isFn, self, arg1, arg2, arg3) {
+ if (isFn)
+ handler.call(self, arg1, arg2, arg3);
+ else {
+ var len = handler.length;
+ var listeners = arrayClone(handler, len);
+ for (var i = 0; i < len; ++i)
+ listeners[i].call(self, arg1, arg2, arg3);
+ }
+}
+
+function emitMany(handler, isFn, self, args) {
+ if (isFn)
+ handler.apply(self, args);
+ else {
+ var len = handler.length;
+ var listeners = arrayClone(handler, len);
+ for (var i = 0; i < len; ++i)
+ listeners[i].apply(self, args);
+ }
+}
+
+EventEmitter.prototype.emit = function emit(type) {
+ var er, handler, len, args, i, events;
+ var doError = (type === 'error');
+
+ events = this._events;
+ if (events)
+ doError = (doError && events.error == null);
+ else if (!doError)
+ return false;
+
+ // If there is no 'error' event listener then throw.
+ if (doError) {
+ if (arguments.length > 1)
+ er = arguments[1];
+ if (er instanceof Error) {
+ throw er; // Unhandled 'error' event
+ } else {
+ // At least give some kind of context to the user
+ var err = new Error('Unhandled "error" event. (' + er + ')');
+ err.context = er;
+ throw err;
+ }
+ return false;
+ }
+
+ handler = events[type];
+
+ if (!handler)
+ return false;
+
+ var isFn = typeof handler === 'function';
+ len = arguments.length;
+ switch (len) {
+ // fast cases
+ case 1:
+ emitNone(handler, isFn, this);
+ break;
+ case 2:
+ emitOne(handler, isFn, this, arguments[1]);
+ break;
+ case 3:
+ emitTwo(handler, isFn, this, arguments[1], arguments[2]);
+ break;
+ case 4:
+ emitThree(handler, isFn, this, arguments[1], arguments[2], arguments[3]);
+ break;
+ // slower
+ default:
+ args = new Array(len - 1);
+ for (i = 1; i < len; i++)
+ args[i - 1] = arguments[i];
+ emitMany(handler, isFn, this, args);
+ }
+
+ return true;
+};
+
+function _addListener(target, type, listener, prepend) {
+ var m;
+ var events;
+ var existing;
+
+ if (typeof listener !== 'function')
+ throw new TypeError('"listener" argument must be a function');
+
+ events = target._events;
+ if (!events) {
+ events = target._events = objectCreate(null);
+ target._eventsCount = 0;
+ } else {
+ // To avoid recursion in the case that type === "newListener"! Before
+ // adding it to the listeners, first emit "newListener".
+ if (events.newListener) {
+ target.emit('newListener', type,
+ listener.listener ? listener.listener : listener);
+
+ // Re-assign `events` because a newListener handler could have caused the
+ // this._events to be assigned to a new object
+ events = target._events;
+ }
+ existing = events[type];
+ }
+
+ if (!existing) {
+ // Optimize the case of one listener. Don't need the extra array object.
+ existing = events[type] = listener;
+ ++target._eventsCount;
+ } else {
+ if (typeof existing === 'function') {
+ // Adding the second element, need to change to array.
+ existing = events[type] =
+ prepend ? [listener, existing] : [existing, listener];
+ } else {
+ // If we've already got an array, just append.
+ if (prepend) {
+ existing.unshift(listener);
+ } else {
+ existing.push(listener);
+ }
+ }
+
+ // Check for listener leak
+ if (!existing.warned) {
+ m = $getMaxListeners(target);
+ if (m && m > 0 && existing.length > m) {
+ existing.warned = true;
+ var w = new Error('Possible EventEmitter memory leak detected. ' +
+ existing.length + ' "' + String(type) + '" listeners ' +
+ 'added. Use emitter.setMaxListeners() to ' +
+ 'increase limit.');
+ w.name = 'MaxListenersExceededWarning';
+ w.emitter = target;
+ w.type = type;
+ w.count = existing.length;
+ if (typeof console === 'object' && console.warn) {
+ console.warn('%s: %s', w.name, w.message);
+ }
+ }
+ }
+ }
+
+ return target;
+}
+
+EventEmitter.prototype.addListener = function addListener(type, listener) {
+ return _addListener(this, type, listener, false);
+};
+
+EventEmitter.prototype.on = EventEmitter.prototype.addListener;
+
+EventEmitter.prototype.prependListener =
+ function prependListener(type, listener) {
+ return _addListener(this, type, listener, true);
+ };
+
+function onceWrapper() {
+ if (!this.fired) {
+ this.target.removeListener(this.type, this.wrapFn);
+ this.fired = true;
+ switch (arguments.length) {
+ case 0:
+ return this.listener.call(this.target);
+ case 1:
+ return this.listener.call(this.target, arguments[0]);
+ case 2:
+ return this.listener.call(this.target, arguments[0], arguments[1]);
+ case 3:
+ return this.listener.call(this.target, arguments[0], arguments[1],
+ arguments[2]);
+ default:
+ var args = new Array(arguments.length);
+ for (var i = 0; i < args.length; ++i)
+ args[i] = arguments[i];
+ this.listener.apply(this.target, args);
+ }
+ }
+}
+
+function _onceWrap(target, type, listener) {
+ var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener };
+ var wrapped = bind.call(onceWrapper, state);
+ wrapped.listener = listener;
+ state.wrapFn = wrapped;
+ return wrapped;
+}
+
+EventEmitter.prototype.once = function once(type, listener) {
+ if (typeof listener !== 'function')
+ throw new TypeError('"listener" argument must be a function');
+ this.on(type, _onceWrap(this, type, listener));
+ return this;
+};
+
+EventEmitter.prototype.prependOnceListener =
+ function prependOnceListener(type, listener) {
+ if (typeof listener !== 'function')
+ throw new TypeError('"listener" argument must be a function');
+ this.prependListener(type, _onceWrap(this, type, listener));
+ return this;
+ };
+
+// Emits a 'removeListener' event if and only if the listener was removed.
+EventEmitter.prototype.removeListener =
+ function removeListener(type, listener) {
+ var list, events, position, i, originalListener;
+
+ if (typeof listener !== 'function')
+ throw new TypeError('"listener" argument must be a function');
+
+ events = this._events;
+ if (!events)
+ return this;
+
+ list = events[type];
+ if (!list)
+ return this;
+
+ if (list === listener || list.listener === listener) {
+ if (--this._eventsCount === 0)
+ this._events = objectCreate(null);
+ else {
+ delete events[type];
+ if (events.removeListener)
+ this.emit('removeListener', type, list.listener || listener);
+ }
+ } else if (typeof list !== 'function') {
+ position = -1;
+
+ for (i = list.length - 1; i >= 0; i--) {
+ if (list[i] === listener || list[i].listener === listener) {
+ originalListener = list[i].listener;
+ position = i;
+ break;
+ }
+ }
+
+ if (position < 0)
+ return this;
+
+ if (position === 0)
+ list.shift();
+ else
+ spliceOne(list, position);
+
+ if (list.length === 1)
+ events[type] = list[0];
+
+ if (events.removeListener)
+ this.emit('removeListener', type, originalListener || listener);
+ }
+
+ return this;
+ };
+
+EventEmitter.prototype.removeAllListeners =
+ function removeAllListeners(type) {
+ var listeners, events, i;
+
+ events = this._events;
+ if (!events)
+ return this;
+
+ // not listening for removeListener, no need to emit
+ if (!events.removeListener) {
+ if (arguments.length === 0) {
+ this._events = objectCreate(null);
+ this._eventsCount = 0;
+ } else if (events[type]) {
+ if (--this._eventsCount === 0)
+ this._events = objectCreate(null);
+ else
+ delete events[type];
+ }
+ return this;
+ }
+
+ // emit removeListener for all listeners on all events
+ if (arguments.length === 0) {
+ var keys = objectKeys(events);
+ var key;
+ for (i = 0; i < keys.length; ++i) {
+ key = keys[i];
+ if (key === 'removeListener') continue;
+ this.removeAllListeners(key);
+ }
+ this.removeAllListeners('removeListener');
+ this._events = objectCreate(null);
+ this._eventsCount = 0;
+ return this;
+ }
+
+ listeners = events[type];
+
+ if (typeof listeners === 'function') {
+ this.removeListener(type, listeners);
+ } else if (listeners) {
+ // LIFO order
+ for (i = listeners.length - 1; i >= 0; i--) {
+ this.removeListener(type, listeners[i]);
+ }
+ }
+
+ return this;
+ };
+
+function _listeners(target, type, unwrap) {
+ var events = target._events;
+
+ if (!events)
+ return [];
+
+ var evlistener = events[type];
+ if (!evlistener)
+ return [];
+
+ if (typeof evlistener === 'function')
+ return unwrap ? [evlistener.listener || evlistener] : [evlistener];
+
+ return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);
+}
+
+EventEmitter.prototype.listeners = function listeners(type) {
+ return _listeners(this, type, true);
+};
+
+EventEmitter.prototype.rawListeners = function rawListeners(type) {
+ return _listeners(this, type, false);
+};
+
+EventEmitter.listenerCount = function(emitter, type) {
+ if (typeof emitter.listenerCount === 'function') {
+ return emitter.listenerCount(type);
+ } else {
+ return listenerCount.call(emitter, type);
+ }
+};
+
+EventEmitter.prototype.listenerCount = listenerCount;
+function listenerCount(type) {
+ var events = this._events;
+
+ if (events) {
+ var evlistener = events[type];
+
+ if (typeof evlistener === 'function') {
+ return 1;
+ } else if (evlistener) {
+ return evlistener.length;
+ }
+ }
+
+ return 0;
+}
+
+EventEmitter.prototype.eventNames = function eventNames() {
+ return this._eventsCount > 0 ? Reflect.ownKeys(this._events) : [];
+};
+
+// About 1.5x faster than the two-arg version of Array#splice().
+function spliceOne(list, index) {
+ for (var i = index, k = i + 1, n = list.length; k < n; i += 1, k += 1)
+ list[i] = list[k];
+ list.pop();
+}
+
+function arrayClone(arr, n) {
+ var copy = new Array(n);
+ for (var i = 0; i < n; ++i)
+ copy[i] = arr[i];
+ return copy;
+}
+
+function unwrapListeners(arr) {
+ var ret = new Array(arr.length);
+ for (var i = 0; i < ret.length; ++i) {
+ ret[i] = arr[i].listener || arr[i];
+ }
+ return ret;
+}
+
+function objectCreatePolyfill(proto) {
+ var F = function() {};
+ F.prototype = proto;
+ return new F;
+}
+function objectKeysPolyfill(obj) {
+ var keys = [];
+ for (var k in obj) if (Object.prototype.hasOwnProperty.call(obj, k)) {
+ keys.push(k);
+ }
+ return k;
+}
+function functionBindPolyfill(context) {
+ var fn = this;
+ return function () {
+ return fn.apply(context, arguments);
+ };
+}
+
},{}],8:[function(require,module,exports){
var WildEmitter = require('wildemitter');
@@ -1135,7 +1378,7 @@ if (typeof Object.create === 'function') {
},{}],11:[function(require,module,exports){
/*!
- * @name JavaScript/NodeJS Merge v1.2.0
+ * @name JavaScript/NodeJS Merge v1.2.1
* @author yeikos
* @repository https://github.com/yeikos/js.merge
@@ -1264,6 +1507,8 @@ if (typeof Object.create === 'function') {
for (var key in item) {
+ if (key === '__proto__') continue;
+
var sitem = clone ? Public.clone(item[key]) : item[key];
if (recursive) {
@@ -2911,7 +3156,7 @@ exports.parse = function(sdp) {
},{"sdp-transform":14}],21:[function(require,module,exports){
/*!
- * UAParser.js v0.7.18
+ * UAParser.js v0.7.19
* Lightweight JavaScript-based User-Agent string parser
* https://github.com/faisalman/ua-parser-js
*
@@ -2928,7 +3173,7 @@ exports.parse = function(sdp) {
/////////////
- var LIBVERSION = '0.7.18',
+ var LIBVERSION = '0.7.19',
EMPTY = '',
UNKNOWN = '?',
FUNC_TYPE = 'function',
@@ -3173,7 +3418,7 @@ exports.parse = function(sdp) {
/(trident).+rv[:\s]([\w\.]+).+like\sgecko/i // IE11
], [[NAME, 'IE'], VERSION], [
- /(edge|edgios|edgea)\/((\d+)?[\w\.]+)/i // Microsoft Edge
+ /(edge|edgios|edga)\/((\d+)?[\w\.]+)/i // Microsoft Edge
], [[NAME, 'Edge'], VERSION], [
/(yabrowser)\/([\w\.]+)/i // Yandex
@@ -3182,8 +3427,13 @@ exports.parse = function(sdp) {
/(puffin)\/([\w\.]+)/i // Puffin
], [[NAME, 'Puffin'], VERSION], [
- /((?:[\s\/])uc?\s?browser|(?:juc.+)ucweb)[\/\s]?([\w\.]+)/i
- // UCBrowser
+ /(focus)\/([\w\.]+)/i // Firefox Focus
+ ], [[NAME, 'Firefox Focus'], VERSION], [
+
+ /(opt)\/([\w\.]+)/i // Opera Touch
+ ], [[NAME, 'Opera Touch'], VERSION], [
+
+ /((?:[\s\/])uc?\s?browser|(?:juc.+)ucweb)[\/\s]?([\w\.]+)/i // UCBrowser
], [[NAME, 'UCBrowser'], VERSION], [
/(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon
@@ -3192,6 +3442,9 @@ exports.parse = function(sdp) {
/(micromessenger)\/([\w\.]+)/i // WeChat
], [[NAME, 'WeChat'], VERSION], [
+ /(brave)\/([\w\.]+)/i // Brave browser
+ ], [[NAME, 'Brave'], VERSION], [
+
/(qqbrowserlite)\/([\w\.]+)/i // QQBrowserLite
], [NAME, VERSION], [
@@ -3219,6 +3472,10 @@ exports.parse = function(sdp) {
/;fbav\/([\w\.]+);/i // Facebook App for iOS & Android
], [VERSION, [NAME, 'Facebook']], [
+ /safari\s(line)\/([\w\.]+)/i, // Line App for iOS
+ /android.+(line)\/([\w\.]+)\/iab/i // Line App for Android
+ ], [NAME, VERSION], [
+
/headlesschrome(?:\/([\w\.]+)|\s)/i // Chrome Headless
], [VERSION, [NAME, 'Chrome Headless']], [
@@ -3416,7 +3673,7 @@ exports.parse = function(sdp) {
/(sun4\w)[;\)]/i // SPARC
], [[ARCHITECTURE, 'sparc']], [
- /((?:avr32|ia64(?=;))|68k(?=\))|arm(?:64|(?=v\d+;))|(?=atmel\s)avr|(?:irix|mips|sparc)(?:64)?(?=;)|pa-risc)/i
+ /((?:avr32|ia64(?=;))|68k(?=\))|arm(?:64|(?=v\d+[;l]))|(?=atmel\s)avr|(?:irix|mips|sparc)(?:64)?(?=;)|pa-risc)/i
// IA64, 68K, ARM/64, AVR/32, IRIX/64, MIPS/64, SPARC/64, PA-RISC
], [[ARCHITECTURE, util.lowerize]]
],
@@ -3444,6 +3701,8 @@ exports.parse = function(sdp) {
], [MODEL, [VENDOR, 'Amazon'], [TYPE, TABLET]], [
/(sd|kf)[0349hijorstuw]+\sbuild\/.+silk\//i // Fire Phone
], [[MODEL, mapper.str, maps.device.amazon.model], [VENDOR, 'Amazon'], [TYPE, MOBILE]], [
+ /android.+aft([bms])\sbuild/i // Fire TV
+ ], [MODEL, [VENDOR, 'Amazon'], [TYPE, SMARTTV]], [
/\((ip[honed|\s\w*]+);.+(apple)/i // iPod/iPhone
], [MODEL, VENDOR, [TYPE, MOBILE]], [
@@ -3572,10 +3831,10 @@ exports.parse = function(sdp) {
/android.+;\s(glass)\s\d/i // Google Glass
], [MODEL, [VENDOR, 'Google'], [TYPE, WEARABLE]], [
- /android.+;\s(pixel c)\s/i // Google Pixel C
+ /android.+;\s(pixel c)[\s)]/i // Google Pixel C
], [MODEL, [VENDOR, 'Google'], [TYPE, TABLET]], [
- /android.+;\s(pixel xl|pixel)\s/i // Google Pixel
+ /android.+;\s(pixel( [23])?( xl)?)\s/i // Google Pixel
], [MODEL, [VENDOR, 'Google'], [TYPE, MOBILE]], [
/android.+;\s(\w+)\s+build\/hm\1/i, // Xiaomi Hongmi 'numeric' models
@@ -3587,6 +3846,8 @@ exports.parse = function(sdp) {
],[[MODEL, /_/g, ' '], [VENDOR, 'Xiaomi'], [TYPE, TABLET]], [
/android.+;\s(m[1-5]\snote)\sbuild/i // Meizu Tablet
], [MODEL, [VENDOR, 'Meizu'], [TYPE, TABLET]], [
+ /(mz)-([\w-]{2,})/i // Meizu Phone
+ ], [[VENDOR, 'Meizu'], MODEL, [TYPE, MOBILE]], [
/android.+a000(1)\s+build/i, // OnePlus
/android.+oneplus\s(a\d{4})\s+build/i
@@ -3635,6 +3896,9 @@ exports.parse = function(sdp) {
/android.+[;\/]\s*(LVTEL\-)?(V1[12])\s+build/i // LvTel Phones
], [[VENDOR, 'LvTel'], MODEL, [TYPE, MOBILE]], [
+ /android.+;\s(PH-1)\s/i
+ ], [MODEL, [VENDOR, 'Essential'], [TYPE, MOBILE]], [ // Essential PH-1
+
/android.+[;\/]\s*(V(100MD|700NA|7011|917G).*\b)\s+build/i // Envizen Tablets
], [MODEL, [VENDOR, 'Envizen'], [TYPE, TABLET]], [
@@ -3797,8 +4061,8 @@ exports.parse = function(sdp) {
// Other
/((?:open)?solaris)[\/\s-]?([\w\.]*)/i, // Solaris
/(aix)\s((\d)(?=\.|\)|\s)[\w\.])*/i, // AIX
- /(plan\s9|minix|beos|os\/2|amigaos|morphos|risc\sos|openvms)/i,
- // Plan9/Minix/BeOS/OS2/AmigaOS/MorphOS/RISCOS/OpenVMS
+ /(plan\s9|minix|beos|os\/2|amigaos|morphos|risc\sos|openvms|fuchsia)/i,
+ // Plan9/Minix/BeOS/OS2/AmigaOS/MorphOS/RISCOS/OpenVMS/Fuchsia
/(unix)\s?([\w\.]*)/i // UNIX
], [NAME, VERSION]
]
@@ -3983,7 +4247,7 @@ exports.parse = function(sdp) {
// jQuery always exports to global scope, unless jQuery.noConflict(true) is used,
// and we should catch that.
var $ = window && (window.jQuery || window.Zepto);
- if (typeof $ !== UNDEF_TYPE) {
+ if (typeof $ !== UNDEF_TYPE && !$.ua) {
var parser = new UAParser();
$.ua = parser.getResult();
$.ua.get = function () {
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 924977d..9474a52 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
@@ -224,6 +224,23 @@ var VideoSettings = (function() {
function _updateRec() {
recBtn.prop('disabled', !recAllowed || (s.video.cam < 0 && s.video.mic < 0)).button('refresh');
}
+ function _setCntsDimensions(cnts) {
+ const b = kurentoUtils.WebRtcPeer.browser;
+ let width = s.video.width;
+ if (b.name === 'Safari') {
+ //valid widths are 320, 640, 1280
+ [320, 640, 1280].some(function(w) {
+ if (width < w + 1) {
+ cnts.video.width = w;
+ return true;
+ }
+ return false;
+ });
+ } else {
+ cnts.video.width = s.video.width;
+ cnts.video.height = s.video.height;
+ }
+ }
//each bool OR https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints
// min/ideal/max/exact/mandatory can also be used
function _constraints(sd, callback) {
@@ -231,10 +248,9 @@ var VideoSettings = (function() {
const cnts = {};
if (devCnts.video && false === o.audioOnly && VideoUtil.hasVideo(sd) && s.video.cam > -1) {
cnts.video = {
- width: s.video.width
- , height: s.video.height
- , frameRate: o.camera.fps
+ frameRate: o.camera.fps
};
+ _setCntsDimensions(cnts)
if (!!s.video.camDevice) {
cnts.video.deviceId = {
ideal: s.video.camDevice