/******/ (() => { // webpackBootstrap /******/ var __webpack_modules__ = ({ /***/ "./node_modules/nosleep.js/src/index.js": /*!**********************************************!*\ !*** ./node_modules/nosleep.js/src/index.js ***! \**********************************************/ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const { webm, mp4 } = __webpack_require__(/*! ./media.js */ "./node_modules/nosleep.js/src/media.js"); // Detect iOS browsers < version 10 const oldIOS = () => typeof navigator !== "undefined" && parseFloat( ( "" + (/CPU.*OS ([0-9_]{3,4})[0-9_]{0,1}|(CPU like).*AppleWebKit.*Mobile/i.exec( navigator.userAgent ) || [0, ""])[1] ) .replace("undefined", "3_2") .replace("_", ".") .replace("_", "") ) < 10 && !window.MSStream; // Detect native Wake Lock API support const nativeWakeLock = () => "wakeLock" in navigator; class NoSleep { constructor() { this.enabled = false; if (nativeWakeLock()) { this._wakeLock = null; const handleVisibilityChange = () => { if (this._wakeLock !== null && document.visibilityState === "visible") { this.enable(); } }; document.addEventListener("visibilitychange", handleVisibilityChange); document.addEventListener("fullscreenchange", handleVisibilityChange); } else if (oldIOS()) { this.noSleepTimer = null; } else { // Set up no sleep video element this.noSleepVideo = document.createElement("video"); this.noSleepVideo.setAttribute("title", "No Sleep"); this.noSleepVideo.setAttribute("playsinline", ""); this._addSourceToVideo(this.noSleepVideo, "webm", webm); this._addSourceToVideo(this.noSleepVideo, "mp4", mp4); this.noSleepVideo.addEventListener("loadedmetadata", () => { if (this.noSleepVideo.duration <= 1) { // webm source this.noSleepVideo.setAttribute("loop", ""); } else { // mp4 source this.noSleepVideo.addEventListener("timeupdate", () => { if (this.noSleepVideo.currentTime > 0.5) { this.noSleepVideo.currentTime = Math.random(); } }); } }); } } _addSourceToVideo(element, type, dataURI) { var source = document.createElement("source"); source.src = dataURI; source.type = `video/${type}`; element.appendChild(source); } get isEnabled() { return this.enabled; } enable() { if (nativeWakeLock()) { return navigator.wakeLock .request("screen") .then((wakeLock) => { this._wakeLock = wakeLock; this.enabled = true; console.log("Wake Lock active."); this._wakeLock.addEventListener("release", () => { // ToDo: Potentially emit an event for the page to observe since // Wake Lock releases happen when page visibility changes. // (https://web.dev/wakelock/#wake-lock-lifecycle) console.log("Wake Lock released."); }); }) .catch((err) => { this.enabled = false; console.error(`${err.name}, ${err.message}`); throw err; }); } else if (oldIOS()) { this.disable(); console.warn(` NoSleep enabled for older iOS devices. This can interrupt active or long-running network requests from completing successfully. See https://github.com/richtr/NoSleep.js/issues/15 for more details. `); this.noSleepTimer = window.setInterval(() => { if (!document.hidden) { window.location.href = window.location.href.split("#")[0]; window.setTimeout(window.stop, 0); } }, 15000); this.enabled = true; return Promise.resolve(); } else { let playPromise = this.noSleepVideo.play(); return playPromise .then((res) => { this.enabled = true; return res; }) .catch((err) => { this.enabled = false; throw err; }); } } disable() { if (nativeWakeLock()) { if (this._wakeLock) { this._wakeLock.release(); } this._wakeLock = null; } else if (oldIOS()) { if (this.noSleepTimer) { console.warn(` NoSleep now disabled for older iOS devices. `); window.clearInterval(this.noSleepTimer); this.noSleepTimer = null; } } else { this.noSleepVideo.pause(); } this.enabled = false; } } module.exports = NoSleep; /***/ }), /***/ "./node_modules/nosleep.js/src/media.js": /*!**********************************************!*\ !*** ./node_modules/nosleep.js/src/media.js ***! \**********************************************/ /***/ ((module) => { module.exports = { webm: "data:video/webm;base64,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", mp4: "data:video/mp4;base64,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", }; /***/ }), /***/ "./src/room/activities.js": /*!********************************!*\ !*** ./src/room/activities.js ***! \********************************/ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { /* Licensed under the Apache License, Version 2.0 (the "License") http://www.apache.org/licenses/LICENSE-2.0 */ const OmUtil = __webpack_require__(/*! ../main/omutils */ "../main/omutils"); const Settings = __webpack_require__(/*! ../main/settings */ "../main/settings"); const closedHeight = 20, timeout = 10000; let activities, aclean, modArea, area, openedHeight = 345 , openedHeightPx = openedHeight + 'px', inited = false , newActNotification; function _load() { const s = Settings.load(); if (typeof(s.activity) === 'undefined') { s.activity = {}; } return s; } function _updateClean(s, a) { const clean = s.activity.clean === true; a.prop('checked', clean); if (clean) { activities.find('.auto-clean').each(function() { setTimeout(_clearItem.bind(null, $(this).data().id), timeout); }); } } function isClosed() { return activities.height() < 24; } function _updateHeightVar(h) { Room.setCssVar('--activities-height', h); } function _open() { if (isClosed()) { $('.control.block i', activities).removeClass('fa-angle-up').addClass('fa-angle-down'); $('.control.block', activities).removeClass('bg-warning'); activities.animate( { height: openedHeightPx , top: '-' + openedHeightPx } , 1000 , function() { activities.css({'top': ''}); _updateHeightVar(openedHeightPx); activities.resizable('option', 'disabled', false); } ); } } function _close() { if (!isClosed()) { $('.control.block i', activities).removeClass('fa-angle-down').addClass('fa-angle-up'); activities.animate( { height: closedHeight , top: (openedHeight - closedHeight) + 'px' } , 1000 , function() { activities.css({'top': ''}); _updateHeightVar(closedHeight + 'px'); } ); activities.resizable('option', 'disabled', true); } } function _findUser(uid) { const m = '5px', t = 50, u = $('#user' + uid); if (u.length === 1) { u[0].scrollIntoView(); u.addClass('bg-warning'); for(let i = 0; i < 10; i++) { u.animate({marginTop: '-='+m}, t) .animate({marginTop: '+='+m}, t); } u.removeClass('bg-warning', 1500); } } function _hightlight(notify) { if (!inited) { return; } if (isClosed()) { $('.control.block', activities).addClass('bg-warning'); if (notify) { OmUtil.notify(newActNotification, 'new_aa_item'); } } } function _getId(id) { return 'activity-' + id; } function _action(name, val) { activityAction($('.room-block .room-container').data('room-id'), name, val); } function _remove(ids) { for (let i = 0; i < ids.length; ++i) { $('#' + _getId(ids[i])).remove(); } _updateCount(); } function _clearItem(id) { if (aclean.prop('checked')) { _remove([id]); } } function _updateCount() { if (!inited) { return; } $('.control.block .badge', activities).text(modArea.find('.activity').length); } module.exports = { init: function() { if ($('#activities').resizable("instance") !== undefined) { return; } activities = $('#activities'); const ctrlBlk = activities.find('.control.block'); ctrlBlk.off().click(Activities.toggle); newActNotification = ctrlBlk.data('new-aa'); activities.resizable({ handles: 'n' , disabled: isClosed() , minHeight: 195 , stop: function(_, ui) { openedHeight = ui.size.height; openedHeightPx = openedHeight + 'px'; _updateHeightVar(openedHeightPx); activities.css({'top': ''}); } }); modArea = activities.find('.area .actions'); area = activities.find('.area .activities'); aclean = $('#activity-auto-clean'); aclean.change(function() { const s = _load(); s.activity.clean = $(this).prop('checked'); Settings.save(s); _updateClean(s, $(this)); }); _updateClean(_load(), aclean); inited = true; _updateCount(); } , toggle: function() { if (!inited) { return; } if (isClosed()) { _open(); } else { _close(); } } , findUser: _findUser , add: function(obj) { if (!inited) { return; } const _id = _getId(obj.id); (obj.action ? modArea : area).append(OmUtil.tmpl('#activity-stub', _id).data(obj)); const a = $('#' + _id).addClass(obj.cssClass); const acpt = a.find('.activity-accept'); if (obj.accept) { acpt.click(function() { _action('accept', obj.id); }); } else { acpt.remove(); } const dcln = a.find('.activity-decline'); if (obj.decline) { dcln.click(function() { _action('decline', obj.id); }); } else { dcln.remove(); } const fnd = a.find('.activity-find'); if (obj.find) { fnd.click(function() { _findUser(obj.uid); }); } else { fnd.remove(); } a.find('.activity-close').click(function() { _action('close', obj.id); }); a.find('.activity-text').text(obj.text); _hightlight(obj.action); if (aclean.prop('checked') && a.hasClass('auto-clean')) { setTimeout(_clearItem.bind(null, obj.id), timeout); } _updateCount(); } , remove: _remove }; /***/ }), /***/ "./src/room/quick-poll.js": /*!********************************!*\ !*** ./src/room/quick-poll.js ***! \********************************/ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { /* Licensed under the Apache License, Version 2.0 (the "License") http://www.apache.org/licenses/LICENSE-2.0 */ const OmUtil = __webpack_require__(/*! ../main/omutils */ "../main/omutils"); const UserListUtil = __webpack_require__(/*! ./user-list-util */ "./src/room/user-list-util.js"); function _setQuickPollRights() { const close = $('#quick-vote .close-btn'); if (close.length === 1) { if (UserListUtil.hasRight(['PRESENTER'])) { close.show(); if (typeof(close.data('bs.confirmation')) === 'object') { return; } close .confirmation({ confirmationEvent: 'bla' , onConfirm: () => quickPollAction('close') }); } else { close.hide(); } } } function _update(obj) { if (obj.started) { let qv = $('#quick-vote'); if (qv.length === 0) { const wbArea = $('.room-block .wb-block'); qv = OmUtil.tmpl('#quick-vote-template', 'quick-vote'); qv.attr('class', 'end-0'); wbArea.append(qv); } const pro = qv.find('.control.pro') , con = qv.find('.control.con'); if (obj.voted) { pro.removeClass('clickable').off(); con.removeClass('clickable').off(); } else { pro.addClass('clickable').off().click(function() { quickPollAction('vote', true); }); con.addClass('clickable').off().click(function() { quickPollAction('vote', false); }); } pro.find('.badge').text(obj.pros); con.find('.badge').text(obj.cons); _setQuickPollRights(); } else { const qv = $('#quick-vote'); if (qv.length === 1) { qv.remove(); } } OmUtil.tmpl('#quick-vote-template', 'quick-vote'); } module.exports = { update: _update , setRights: _setQuickPollRights }; /***/ }), /***/ "./src/room/room.js": /*!**************************!*\ !*** ./src/room/room.js ***! \**************************/ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { /* Licensed under the Apache License, Version 2.0 (the "License") http://www.apache.org/licenses/LICENSE-2.0 */ const Settings = __webpack_require__(/*! ../main/settings */ "../main/settings"); const VideoUtil = __webpack_require__(/*! ../settings/video-util */ "../settings/video-util"); const VideoSettings = __webpack_require__(/*! ../settings/settings */ "../settings/settings"); const InterviewWbArea = __webpack_require__(/*! ../wb/interview-area */ "../wb/interview-area"); const DrawWbArea = __webpack_require__(/*! ../wb/wb-area */ "../wb/wb-area") const NoSleep = __webpack_require__(/*! nosleep.js */ "./node_modules/nosleep.js/src/index.js"); const VideoManager = __webpack_require__(/*! ./video-manager */ "./src/room/video-manager.js"); const Sharer = __webpack_require__(/*! ./sharer */ "./src/room/sharer.js"); const Activities = __webpack_require__(/*! ./activities */ "./src/room/activities.js"); const SipDialer = __webpack_require__(/*! ./sip-dialer */ "./src/room/sip-dialer.js"); const UserListUtil = __webpack_require__(/*! ./user-list-util */ "./src/room/user-list-util.js"); const UserList = __webpack_require__(/*! ./user-list */ "./src/room/user-list.js"); const QuickPoll = __webpack_require__(/*! ./quick-poll */ "./src/room/quick-poll.js"); const sbSide = Settings.isRtl ? 'right' : 'left'; let options, menuHeight, sb, dock, noSleep; function _init(_options) { options = _options; window.WbArea = options.interview ? new InterviewWbArea() : new DrawWbArea(); const menu = $('.room-block .room-container .menu'); sb = $('.room-block .sidebar'); sb.width(sb.width()); // this is required to 'fix' the width so it will not depend on CSS var dock = sb.find('.btn-dock').click(function() { const offset = parseInt(sb.css(sbSide)); if (offset < 0) { sb.removeClass('closed'); } dock.prop('disabled', true); const props = {}; props[sbSide] = offset < 0 ? '0px' : (-sb.width() + 45) + 'px'; sb.animate(props, 1500 , function() { dock.prop('disabled', false); __dockSetMode(offset < 0); _setSize(); }); }); __dockSetMode(true); menuHeight = menu.length === 0 ? 0 : menu.height(); VideoManager.init(); Activities.init(); Sharer.init(); UserList.init(options); _setSize(); $(window).on('resize.omwb', window.WbArea.resize); } function __dockSetMode(mode) { const icon = dock.find('i').removeClass('icon-dock icon-undock'); if (mode) { icon.addClass('icon-undock'); dock.attr('title', dock.data('ttl-undock')) .find('.sr-only').text(dock.data('ttl-undock')); _sbAddResizable(); } else { icon.addClass('icon-dock'); dock.attr('title', dock.data('ttl-dock')) .find('.sr-only').text(dock.data('ttl-dock')); sb.addClass('closed').resizable('destroy'); } } function _getSelfAudioClient() { const vw = $('.video-container[data-client-type=WEBCAM][data-client-uid=' + Room.getOptions().uid + ']'); if (vw.length > 0) { const v = vw.first().data(); if (VideoUtil.hasMic(v.stream())) { return v; } } return null; } function _preventKeydown(e) { const base = $(e.target); if (e.target.isContentEditable === true || base.is('textarea, input:not([readonly]):not([type=radio]):not([type=checkbox])')) { return; } if (e.which === 8) { // backspace e.preventDefault(); e.stopImmediatePropagation(); return false; } } function __keyPressed(hotkey, e) { const code = e.code; return hotkey.alt === e.altKey && hotkey.ctrl === e.ctrlKey && hotkey.shift === e.shiftKey && hotkey.code.toUpperCase() === (code ? code.toUpperCase() : ''); } function _keyHandler(e) { if (__keyPressed(options.keycode.arrange, e)) { VideoUtil.arrange(); } else if (__keyPressed(options.keycode.arrangeresize, e)) { VideoUtil.arrangeResize(VideoSettings.load()); } else if (__keyPressed(options.keycode.muteothers, e)) { const v = _getSelfAudioClient(); if (v !== null) { VideoManager.clickMuteOthers(Room.getOptions().uid); } } else if (__keyPressed(options.keycode.mute, e)) { const v = _getSelfAudioClient(); if (v !== null) { v.mute(!v.isMuted()); } } else if (__keyPressed(options.keycode.quickpoll, e)) { quickPollAction('open'); } if (e.which === 27) { $('#wb-rename-menu').hide(); } } function _mouseHandler(e) { if (e.which === 1) { $('#wb-rename-menu').hide(); } } function _sbWidth() { if (sb === undefined) { sb = $('.room-block .sidebar'); } return sb === undefined ? 0 : sb.width() + parseInt(sb.css(sbSide)); } function _setSize() { const sbW = _sbWidth() , holder = $('.room-block'); ($('.main.room')[0]).style.setProperty('--sidebar-width', sbW + 'px'); if (sbW > 236) { holder.addClass('big').removeClass('narrow'); } else { holder.removeClass('big').addClass('narrow'); } } function _reload() { if (!!options && !!options.reloadUrl) { window.location.href = options.reloadUrl; } else { window.location.reload(); } } function _close() { _unload(); $(".room-block").remove(); $("#chatPanel").remove(); $('#disconnected-dlg') .modal('show') .off('hide.bs.modal') .on('hide.bs.modal', _reload); } function _sbAddResizable() { sb.resizable({ handles: Settings.isRtl ? 'w' : 'e' , stop: function() { _setSize(); } }); } function _load() { $('body').addClass('no-header'); Wicket.Event.subscribe("/websocket/closed", _close); Wicket.Event.subscribe("/websocket/error", _close); $(window).on('keydown.openmeetings', _preventKeydown); $(window).on('keyup.openmeetings', _keyHandler); $(window).on('keydown.om-sip', SipDialer.keyDown); $(window).on('keyup.om-sip', SipDialer.keyUp); $(document).click(_mouseHandler); document.addEventListener('click', _addNoSleep, false); SipDialer.init(); } function _addNoSleep() { _removeNoSleep(); noSleep = new NoSleep(); noSleep.enable(); } function _removeNoSleep() { document.removeEventListener('click', _addNoSleep, false); if (noSleep) { noSleep.disable(); noSleep = null; } } function _unload() { $('body').removeClass('no-header'); Wicket.Event.unsubscribe("/websocket/closed", _close); Wicket.Event.unsubscribe("/websocket/error", _close); if (typeof(WbArea) === 'object') { WbArea.destroy(); window.WbArea = undefined; } if (typeof(VideoSettings) === 'object') { VideoSettings.close(); } if (typeof(VideoManager) === 'object') { VideoManager.destroy(); } $('.ui-dialog.user-video').remove(); $(window).off('keyup.openmeetings'); $(window).off('keydown.openmeetings'); $(window).off('resize.omwb'); $(window).off('keydown.om-sip'); $(window).off('keyup.om-sip'); $(document).off('click', _mouseHandler); sb = undefined; Sharer.close(); _removeNoSleep(); } function _showClipboard(txt) { const dlg = $('#clipboard-dialog'); dlg.find('p .text').text(txt); dlg.dialog({ resizable: false , height: "auto" , width: 400 , modal: true , buttons: [ { text: dlg.data('btn-ok') , click: function() { $(this).dialog('close'); } } ] }); } module.exports = { init: _init , getMenuHeight: function() { return menuHeight; } , getOptions: function() { return typeof(options) === 'object' ? JSON.parse(JSON.stringify(options)) : {}; } , load: _load , unload: _unload , showClipboard: _showClipboard , quickPoll: QuickPoll.update , hasRight: UserListUtil.hasRight , setCssVar: function(key, val) { ($('.main.room')[0]).style.setProperty(key, val); } , addClient: UserList.addClient , updateClient: UserList.updateClient , removeClient: UserList.removeClient , removeOthers: UserList.removeOthers , getClient: UserList.getClient }; /***/ }), /***/ "./src/room/sharer.js": /*!****************************!*\ !*** ./src/room/sharer.js ***! \****************************/ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { /* Licensed under the Apache License, Version 2.0 (the "License") http://www.apache.org/licenses/LICENSE-2.0 */ const VideoUtil = __webpack_require__(/*! ../settings/video-util */ "../settings/video-util"); const VideoMgrUtil = __webpack_require__(/*! ./video-manager-util */ "./src/room/video-manager-util.js"); const SHARE_STARTING = 'starting' , SHARE_STARTED = 'started' , SHARE_STOPPED = 'stopped'; let sharer, type, fps, sbtn, rbtn , shareState = SHARE_STOPPED, recState = SHARE_STOPPED; /** * Re-entering the room should reset settings. */ function reset() { shareState = SHARE_STOPPED; recState = SHARE_STOPPED; } function _init() { reset(); sharer = $('#sharer').dialog({ appendTo: '.room-block .room-container' , classes: { 'ui-dialog': 'sharer' , 'ui-dialog-titlebar': '' } , width: 450 , autoOpen: false , resizable: false }); const ui = sharer.closest('.ui-dialog'); const parent = $('.room-block .room-container .sb-wb'); ui.draggable('option', 'containment', parent); fixJQueryUIDialogTouch(sharer); if (!VideoUtil.sharingSupported()) { sharer.find('.container').remove(); sharer.find('.alert').show(); } else { type = sharer.find('select.type'); fps = sharer.find('select.fps'); _disable(fps, VideoUtil.isEdge()); sbtn = sharer.find('.share-start-stop').off().click(function() { if (shareState === SHARE_STOPPED) { _setShareState(SHARE_STARTING); VideoMgrUtil.sendMessage({ id: 'wannaShare' , shareType: type.val() , fps: fps.val() }); } else { VideoMgrUtil.sendMessage({ id: 'pauseSharing' , uid: _getShareUid() }); } }); rbtn = sharer.find('.record-start-stop').off(); if (Room.getOptions().allowRecording) { rbtn.show().click(function() { if (recState === SHARE_STOPPED) { _setRecState(SHARE_STARTING); VideoMgrUtil.sendMessage({ id: 'wannaRecord' , shareType: type.val() , fps: fps.val() }); } else { VideoMgrUtil.sendMessage({ id: 'stopRecord' , uid: _getShareUid() }); } }); } else { rbtn.hide(); } } } function _disable(e, state) { e.prop('disabled', state); if (state) { e.addClass('disabled'); } else { e.removeClass('disabled'); } } function _typeDisabled() { return VideoUtil.isEdge() || VideoUtil.isChrome() || VideoUtil.isEdgeChromium(); } function _setBtnState(btn, state) { const dis = SHARE_STOPPED !== state , typeDis = _typeDisabled(); _disable(type, dis); _disable(fps, dis || typeDis); btn.find('span').text(btn.data(dis ? 'stop' : 'start')); if (dis) { btn.addClass('stop'); } else { btn.removeClass('stop'); } _disable(btn, state === SHARE_STARTING); _disable(btn, state === SHARE_STARTING); } function _setShareState(state) { shareState = state; _setBtnState(sbtn, state); } function _setRecState(state) { recState = state; _setBtnState(rbtn, state); } function _getShareUid() { const v = $('div[data-client-uid="' + Room.getOptions().uid + '"][data-client-type="SCREEN"]'); return v && v.data() && v.data().stream() ? v.data().stream().uid : ''; } module.exports = { SHARE_STARTING: SHARE_STARTING , SHARE_STARTED: SHARE_STARTED , SHARE_STOPPED: SHARE_STOPPED , init: _init , open: function() { if (sharer && sharer.dialog('instance')) { sharer.dialog('open'); } } , close: function() { if (sharer && sharer.dialog('instance')) { sharer.dialog('close'); } } , setShareState: _setShareState , setRecState: _setRecState , baseConstraints: function(sd) { return { video: { frameRate: { ideal: sd.fps } } , audio: false }; } }; /***/ }), /***/ "./src/room/sip-dialer.js": /*!********************************!*\ !*** ./src/room/sip-dialer.js ***! \********************************/ /***/ ((module) => { /* Licensed under the Apache License, Version 2.0 (the "License") http://www.apache.org/licenses/LICENSE-2.0 */ function __addSipText(v) { const txt = $('.sip-number'); txt.val(txt.val() + v); } function __eraseSipText() { const txt = $('.sip-number') , t = txt.val(); if (!!t) { txt.val(t.substring(0, t.length - 1)); } } function _sipGetKey(evt) { let k = -1; if (evt.keyCode > 47 && evt.keyCode < 58) { k = evt.keyCode - 48; } if (evt.keyCode > 95 && evt.keyCode < 106) { k = evt.keyCode - 96; } return k; } module.exports = { init: function() { $('.sip .button-row button').off().click(function() { __addSipText($(this).data('value')); }); $('#sip-dialer-btn-erase').off().click(__eraseSipText); } , keyDown: function(evt) { const k = _sipGetKey(evt); if (k > 0) { $('#sip-dialer-btn-' + k).addClass('bg-warning'); } } , keyUp: function(evt) { if (evt.key === 'Backspace') { __eraseSipText(); } else { const k = _sipGetKey(evt); if (k > 0) { $('#sip-dialer-btn-' + k).removeClass('bg-warning'); __addSipText(k); } } } }; /***/ }), /***/ "./src/room/user-list-util.js": /*!************************************!*\ !*** ./src/room/user-list-util.js ***! \************************************/ /***/ ((module) => { /* Licensed under the Apache License, Version 2.0 (the "License") http://www.apache.org/licenses/LICENSE-2.0 */ let options; function _hasRight(_inRights, _ref) { const ref = _ref || options.rights; let _rights; if (Array.isArray(_inRights)) { _rights = _inRights; } else { if ('SUPER_MODERATOR' === _inRights) { return ref.includes(_inRights); } _rights = [_inRights]; } const rights = ['SUPER_MODERATOR', 'MODERATOR', ..._rights]; for (let i = 0; i < rights.length; ++i) { if (ref.includes(rights[i])) { return true; } } return false; } module.exports = { init: function(opts) { options = opts; } , hasRight: _hasRight }; /***/ }), /***/ "./src/room/user-list.js": /*!*******************************!*\ !*** ./src/room/user-list.js ***! \*******************************/ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { /* Licensed under the Apache License, Version 2.0 (the "License") http://www.apache.org/licenses/LICENSE-2.0 */ const Settings = __webpack_require__(/*! ../main/settings */ "../main/settings"); const Chat = __webpack_require__(/*! ../chat/chat */ "../chat/chat"); const VideoUtil = __webpack_require__(/*! ../settings/video-util */ "../settings/video-util"); const VideoSettings = __webpack_require__(/*! ../settings/settings */ "../settings/settings"); const OmUtil = __webpack_require__(/*! ../main/omutils */ "../main/omutils"); const VideoManager = __webpack_require__(/*! ./video-manager */ "./src/room/video-manager.js"); const UserListUtil = __webpack_require__(/*! ./user-list-util */ "./src/room/user-list-util.js"); const QuickPoll = __webpack_require__(/*! ./quick-poll */ "./src/room/quick-poll.js"); let options; function __activityAVIcon(elem, selector, predicate, onfunc, disabledfunc) { const icon = elem.find(selector); if (predicate()) { icon.show(); const on = onfunc() , disabled = disabledfunc(); if (disabled) { icon.addClass('disabled'); } else { icon.removeClass('disabled'); if (on) { icon.addClass('enabled'); } else { icon.removeClass('enabled'); } } icon.attr('title', icon.data(on ? 'on' :'off')); } else { icon.hide(); } return icon; } function __activityIcon(elem, selector, predicate, action, confirm) { let icon = elem.find(selector); if (predicate()) { if (icon.length === 0) { icon = OmUtil.tmpl('#user-actions-stub ' + selector); elem.append(icon); } icon.off(); if (confirm) { icon.confirmation(confirm); } else { icon.click(action); } } else { icon.hide(); } } function __rightIcon(c, elem, rights, selector, predicate) { const self = c.uid === options.uid , hasRight = UserListUtil.hasRight(rights, c.rights); let icon = elem.find(selector); if (predicate() && !UserListUtil.hasRight('SUPER_MODERATOR', c.rights) && ( (self && options.questions && !hasRight) || (!self && UserListUtil.hasRight('MODERATOR')) )) { if (icon.length === 0) { icon = OmUtil.tmpl('#user-actions-stub ' + selector); elem.append(icon); } if (hasRight) { icon.addClass('granted'); } else { icon.removeClass('granted') } icon.attr('title', icon.data(self ? 'request' : (hasRight ? 'revoke' : 'grant'))); icon.off().click(function() { OmUtil.roomAction({action: 'toggleRight', right: rights[0], uid: c.uid}); }); } else { icon.remove(); } } function __rightAudioIcon(c, elem) { __rightIcon(c, elem, ['AUDIO'], '.right.audio', () => true); } function __rightVideoIcon(c, elem) { __rightIcon(c, elem, ['VIDEO'], '.right.camera', () => !options.audioOnly); } function __rightOtherIcons(c, elem) { __rightIcon(c, elem, ['PRESENTER'], '.right.presenter', () => !options.interview && $('.wb-area').is(':visible')); __rightIcon(c, elem, ['WHITEBOARD', 'PRESENTER'], '.right.wb', () => !options.interview && $('.wb-area').is(':visible')); __rightIcon(c, elem, ['SHARE'], '.right.screen-share', () => true); __rightIcon(c, elem, ['REMOTE_CONTROL'], '.right.remote-control', () => true); __rightIcon(c, elem, ['MODERATOR'], '.right.moderator', () => true); } function __setStatus(c, le) { const status = le.find('.user-status') , mode = c.level == 5 ? 'mod' : (c.level == 3 ? 'wb' : 'user'); status.removeClass('mod wb user'); status.attr('title', status.data(mode)).addClass(mode); le.data('level', c.level); } function __updateCount() { $('#room-sidebar-users-tab .user-count').text($('#room-sidebar-tab-users .user-list .users .user.entry').length); } function __sortUserList() { const container = $('#room-sidebar-tab-users .user-list .users'); container.find('.user.entry').sort((_u1, _u2) => { const u1 = $(_u1) , u2 = $(_u2); return u2.data('level') - u1.data('level') || u1.attr('title').localeCompare(u2.attr('title')); }).appendTo(container); } function _getClient(uid) { return $('#user' + uid); } function _addClient(_clients) { if (!options) { return; //too early } const clients = Array.isArray(_clients) ? _clients : [_clients]; clients.forEach(c => { const self = c.uid === options.uid; let le = _getClient(c.uid); if (le.length === 0) { le = OmUtil.tmpl('#user-entry-stub', 'user' + c.uid); le.attr('id', 'user' + c.uid) .attr('data-userid', c.user.id) .attr('data-uid', c.uid); if (self) { le.addClass('current'); } $('#room-sidebar-tab-users .user-list .users').append(le); } _updateClient(c); }); __updateCount(); __sortUserList(); } function _updateClient(c) { if (!options) { return; //too early } const self = c.uid === options.uid , le = _getClient(c.uid) , selfCamStream = c.streams.find(s => s.type === 'WEBCAM') , hasAudio = VideoUtil.hasMic(self && selfCamStream ? selfCamStream : c) , hasVideo = VideoUtil.hasCam(self && selfCamStream ? selfCamStream : c) , speaks = le.find('.audio-activity'); if (le.length === 0) { return; } __setStatus(c, le); if (hasVideo || hasAudio) { if (le.find('.restart').length === 0) { le.prepend(OmUtil.tmpl('#user-av-restart').click(function () { VideoManager.refresh(c.uid); })); } } else { le.find('.restart').remove(); } speaks.hide().removeClass('clickable').attr('title', speaks.data('speaks')).off(); if (hasAudio) { speaks.show(); if(UserListUtil.hasRight('MUTE_OTHERS')) { speaks.addClass('clickable').click(function () { VideoManager.clickMuteOthers(c.uid); }).attr('title', speaks.attr('title') + speaks.data('mute')); } } le.attr('title', c.user.displayName) .css('background-image', 'url(' + c.user.pictureUri + ')') .find('.user.name').text(c.user.displayName); if (c.user.id !== -1) { const actions = le.find('.user.actions'); __rightVideoIcon(c, actions); __rightAudioIcon(c, actions); __rightOtherIcons(c, actions); __activityIcon(actions, '.kick' , () => !self && UserListUtil.hasRight('MODERATOR') && !UserListUtil.hasRight('SUPER_MODERATOR', c.rights) , null , { confirmationEvent: 'om-kick' , placement: Settings.isRtl ? 'left' : 'right' , onConfirm: () => OmUtil.roomAction({action: 'kick', uid: c.uid}) }); __activityIcon(actions, '.private-chat' , () => options.userId !== c.user.id && $('#chatPanel').is(':visible') , function() { Chat.addTab('chatTab-u' + c.user.id, c.user.displayName); Chat.open(); $('#chatMessage .wysiwyg-editor').click(); }); } if (self) { options.rights = c.rights; QuickPoll.setRights(); options.activities = c.activities; const header = $('#room-sidebar-tab-users .header'); header.find('.om-icon.settings').off().click(VideoSettings.open); __rightVideoIcon(c, header); __activityAVIcon( header , '.activity.cam' , () => !options.audioOnly && UserListUtil.hasRight(VideoUtil.CAM_ACTIVITY) , () => hasVideo , () => Settings.load().video.cam < 0) .off().click(function() { VideoManager.toggleActivity(VideoUtil.CAM_ACTIVITY); });; __rightAudioIcon(c, header); __activityAVIcon( header , '.activity.mic', () => UserListUtil.hasRight(VideoUtil.MIC_ACTIVITY) , () => hasAudio , () => Settings.load().video.mic < 0) .off().click(function() { VideoManager.toggleActivity(VideoUtil.MIC_ACTIVITY); }); __rightOtherIcons(c, header); } VideoManager.update(c) } module.exports = { init: function(opts) { options = opts; UserListUtil.init(opts); } , addClient: _addClient , updateClient: function(c) { _updateClient(c); __sortUserList(); } , removeClient: function(uid) { _getClient(uid).remove(); __updateCount(); } , removeOthers: function() { const selfUid = options.uid; $('.user-list .user.entry').each(function() { const c = $(this); if (c.data('uid') !== selfUid) { c.remove(); } }); __updateCount(); } , getClient: _getClient }; /***/ }), /***/ "./src/room/user-settings.js": /*!***********************************!*\ !*** ./src/room/user-settings.js ***! \***********************************/ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { /* Licensed under the Apache License, Version 2.0 (the "License") http://www.apache.org/licenses/LICENSE-2.0 */ const Settings = __webpack_require__(/*! ../main/settings */ "../main/settings"); const Chat = __webpack_require__(/*! ../chat/chat */ "../chat/chat"); const VideoSettings = __webpack_require__(/*! ../settings/settings */ "../settings/settings"); function __initMuteOthers() { let s = VideoSettings.load(); $('#muteOthersAsk') .prop('checked', s.video.confirmMuteOthers) .off().click(function() { s = VideoSettings.load(); s.video.confirmMuteOthers = !$('#muteOthersAsk').prop('checked'); VideoSettings.save(); }); } function __initChat() { let s = Settings.load(); $('#chatNotify') .prop('checked', s.chat.muted) .off().click(function() { s = Settings.load(); s.chat.muted = !$('#chatNotify').prop('checked'); Settings.save(s); Chat.reload(); }); $('#sendOnCtrlEnter') .prop('checked', s.chat.sendOn === Chat.SEND_CTRL) .off().click(function() { s = Settings.load(); s.chat.sendOn = $('#sendOnCtrlEnter').prop('checked') ? Chat.SEND_CTRL : Chat.SEND_ENTER; Settings.save(s); Chat.reload(); }); } function __initVideo() { const resolutions = $('#video-settings .cam-resolution').clone(); let s = VideoSettings.load(); resolutions .change(function() { const o = resolutions.find('option:selected').data(); s.fixed.width = o.width; s.fixed.height = o.height; VideoSettings.save(); }) .find('option').each(function() { const o = $(this).data(); if (o.width === s.fixed.width && o.height === s.fixed.height) { $(this).prop('selected', true); return false; } }); $('#video-sizes-container') .html('') .append(resolutions.prop('disabled', !s.fixed.enabled)); $('#fixedVideoPod') .prop('checked', s.fixed.enabled) .off().click(function() { s = VideoSettings.load(); s.fixed.enabled = $('#fixedVideoPod').prop('checked'); resolutions.prop('disabled', !s.fixed.enabled) VideoSettings.save(); }); } function _open() { __initMuteOthers(); __initChat(); __initVideo(); $('#room-local-settings').modal('show'); } module.exports = { open: _open }; /***/ }), /***/ "./src/room/video-manager-util.js": /*!****************************************!*\ !*** ./src/room/video-manager-util.js ***! \****************************************/ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { /* Licensed under the Apache License, Version 2.0 (the "License") http://www.apache.org/licenses/LICENSE-2.0 */ const OmUtil = __webpack_require__(/*! ../main/omutils */ "../main/omutils"); const VideoUtil = __webpack_require__(/*! ../settings/video-util */ "../settings/video-util"); const VideoSettings = __webpack_require__(/*! ../settings/settings */ "../settings/settings"); let share; function __savePod(v) { const opts = Room.getOptions(); if (!opts.interview && v && v.find('video').length > 0 && v.data('clientType') === 'WEBCAM' && v.dialog('instance')) { const userUI = $(`#user${v.data('clientUid')}`) , widget = v.dialog('widget'); userUI.data('video-pod', { x: widget.css('left') , y: widget.css('top') , w: widget.css('width') , h: widget.css('height') }); } } function _closeV(v) { if (!v || v.length < 1) { return; } __savePod(v); if (v.dialog('instance') !== undefined) { v.dialog('destroy'); } v.parents('.pod').remove(); v.remove(); WbArea.updateAreaClass(); } function _clickMuteOthers(uid) { const s = VideoSettings.load(); if (false !== s.video.confirmMuteOthers) { const dlg = $('#muteothers-confirm'); dlg.dialog({ appendTo: ".room-container" , buttons: [ { text: dlg.data('btn-ok') , click: function() { s.video.confirmMuteOthers = !$('#muteothers-confirm-dont-show').prop('checked'); VideoSettings.save(); OmUtil.roomAction({action: 'muteOthers', uid: uid}); $(this).dialog('close'); } } , { text: dlg.data('btn-cancel') , click: function() { $(this).dialog('close'); } } ] }) } else { OmUtil.roomAction({action: 'muteOthers', uid: uid}); } } module.exports = { init: (_share) => { share = _share; } , sendMessage: (_m) => { OmUtil.sendMessage(_m, {type: 'kurento'}); } , savePod: __savePod , closeV: _closeV , close: (uid, showShareBtn) => { const v = $('#' + VideoUtil.getVid(uid)); if (v.length === 1) { _closeV(v); } if (!showShareBtn && uid === share.data('uid')) { share.off().hide(); } } , clickMuteOthers: _clickMuteOthers }; /***/ }), /***/ "./src/room/video-manager.js": /*!***********************************!*\ !*** ./src/room/video-manager.js ***! \***********************************/ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { /* Licensed under the Apache License, Version 2.0 (the "License") http://www.apache.org/licenses/LICENSE-2.0 */ const OmUtil = __webpack_require__(/*! ../main/omutils */ "../main/omutils"); const VideoUtil = __webpack_require__(/*! ../settings/video-util */ "../settings/video-util"); const VideoSettings = __webpack_require__(/*! ../settings/settings */ "../settings/settings"); let share, inited = false; const VideoMgrUtil = __webpack_require__(/*! ./video-manager-util */ "./src/room/video-manager-util.js"); const Video = __webpack_require__(/*! ./video */ "./src/room/video.js"); const Sharer = __webpack_require__(/*! ./sharer */ "./src/room/sharer.js"); function _onVideoResponse(m) { const w = $('#' + VideoUtil.getVid(m.uid)) , v = w.data(); if (v) { v.processSdpAnswer(m.sdpAnswer); } } function _onBroadcast(msg) { const sd = msg.stream , uid = sd.uid; if (Array.isArray(msg.cleanup)) { msg.cleanup.forEach(function(_cuid) { VideoMgrUtil.close(_cuid); }); } $('#' + VideoUtil.getVid(uid)).remove(); new Video(msg); OmUtil.log(uid + ' registered in room'); } function _onShareUpdated(msg) { const sd = msg.stream , uid = sd.uid , w = $('#' + VideoUtil.getVid(uid)) , v = w.data(); if (v && (VideoUtil.isSharing(sd) || VideoUtil.isRecording(sd))) { // Update activities in the current data object v.stream().activities = sd.activities; } Sharer.setShareState(VideoUtil.isSharing(sd) ? Sharer.SHARE_STARTED : Sharer.SHARE_STOPPED); Sharer.setRecState(VideoUtil.isRecording(sd) ? Sharer.SHARE_STARTED : Sharer.SHARE_STOPPED); } function _onReceive(msg) { const uid = msg.stream.uid; VideoMgrUtil.closeV($('#' + VideoUtil.getVid(uid))); new Video(msg); OmUtil.log(uid + ' receiving video'); } function _onKMessage(m) { switch (m.id) { case 'clientLeave': $(`${VideoUtil.VID_SEL}[data-client-uid="${m.uid}"]`).each(function() { VideoMgrUtil.closeV($(this)); }); if (share.data('cuid') === m.uid) { share.off().hide(); } break; case 'broadcastStopped': VideoMgrUtil.close(m.uid, false); break; case 'broadcast': _onBroadcast(m); break; case 'videoResponse': _onVideoResponse(m); break; case 'iceCandidate': { const w = $('#' + VideoUtil.getVid(m.uid)) , v = w.data(); if (v) { v.processIceCandidate(m.candidate); } } break; case 'newStream': _play([m.stream], m.iceServers); break; case 'shareUpdated': _onShareUpdated(m); break; case 'error': OmUtil.error(m.message); break; default: //no-op } } function _onWsMessage(_, msg) { try { if (msg instanceof Blob) { return; //ping } const m = JSON.parse(msg); if (!m) { return; } if ('kurento' === m.type && 'test' !== m.mode) { OmUtil.info('Received message: ' + msg); _onKMessage(m); } else if ('mic' === m.type) { switch (m.id) { case 'activity': _userSpeaks(m.uid, m.active); break; default: //no-op } } } catch (err) { OmUtil.error(err); } } function _init() { Wicket.Event.subscribe('/websocket/message', _onWsMessage); VideoSettings.init(Room.getOptions()); share = $('.room-block .room-container').find('.btn.shared'); VideoMgrUtil.init(share); inited = true; $(window).on('keydown.push-to-talk', {enable: true}, _onPtt); $(window).on('keyup.push-to-talk', {enable: false}, _onPtt); } function _update(c) { if (!inited) { return; } const streamMap = {}; c.streams.forEach(function(sd) { streamMap[sd.uid] = sd.uid; sd.self = c.self; sd.cam = c.cam; sd.mic = c.mic; if (VideoUtil.isSharing(sd) || VideoUtil.isRecording(sd)) { return; } const _id = VideoUtil.getVid(sd.uid) , av = VideoUtil.hasMic(sd) || VideoUtil.hasCam(sd) , v = $('#' + _id); if (av && v.length === 1) { v.data().update(sd); } else if (!av && v.length === 1) { VideoMgrUtil.closeV(v); } }); if (c.uid === Room.getOptions().uid) { $(VideoUtil.VID_SEL).each(function() { $(this).data().setRights(c.rights); }); } $(`[data-client-uid="${c.cuid}"]`).each(function() { const sd = $(this).data().stream(); if (!streamMap[sd.uid]) { //not-inited/invalid video window VideoMgrUtil.closeV($(this)); } }); } function _playSharing(sd, iceServers) { const m = {stream: sd, iceServers: iceServers} , v = $('#' + VideoUtil.getVid(sd.uid)) if (v.length === 1) { v.remove(); } new Video(m); VideoUtil.setPos(v, {left: 0, top: 35}); } function _play(streams, iceServers) { if (!inited) { return; } streams.forEach(function(sd) { const m = {stream: sd, iceServers: iceServers}; if (VideoUtil.isSharing(sd)) { VideoUtil.highlight(share .attr('title', share.data('user') + ' ' + sd.user.firstName + ' ' + sd.user.lastName + ' ' + share.data('text')) .data('uid', sd.uid) .data('cuid', sd.cuid) .show() , 'btn-outline-warning', 10); share.tooltip().off().click(function() { _playSharing(sd, iceServers); }); if (Room.getOptions().autoOpenSharing === true) { _playSharing(sd, iceServers); } } else if (VideoUtil.isRecording(sd)) { return; } else { _onReceive(m); } }); } function _find(uid) { return $(`${VideoUtil.VID_SEL}[data-client-uid="${uid}"][data-client-type="WEBCAM"]`); } function _userSpeaks(uid, active) { const u = $(`#user${uid} .audio-activity`) , v = _find(uid).parent(); if (active) { u.addClass('speaking'); v.addClass('user-speaks') } else { u.removeClass('speaking'); v.removeClass('user-speaks') } } function _refresh(uid, opts) { const v = _find(uid); if (v.length > 0) { v.data().refresh(opts); } } function _mute(uid, mute) { const v = _find(uid); if (v.length > 0) { v.data().mute(mute); } } function _muteOthers(uid) { $(VideoUtil.VID_SEL).each(function() { const w = $(this), v = w.data(), v2 = w.data('client-uid'); if (v && v2) { v.mute(uid !== v2); } }); } function _toggleActivity(activity) { VideoMgrUtil.sendMessage({ id: 'toggleActivity' , activity: activity }); } function _onPtt(e) { if ((e.ctrlKey || e.metaKey) && 'Space' === e.code) { const v = _find(Room.getOptions().uid); if (v.length > 0 && v.data()) { v.data().pushToTalk(e.data.enable); } } } module.exports = { init: _init , update: _update , play: _play , refresh: _refresh , mute: _mute , muteOthers: _muteOthers , toggleActivity: _toggleActivity , destroy: function() { $(window).off('keydown.push-to-talk'); $(window).off('keyup.push-to-talk'); Wicket.Event.unsubscribe('/websocket/message', _onWsMessage); } }; /***/ }), /***/ "./src/room/video.js": /*!***************************!*\ !*** ./src/room/video.js ***! \***************************/ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { /* Licensed under the Apache License, Version 2.0 (the "License") http://www.apache.org/licenses/LICENSE-2.0 */ const OmUtil = __webpack_require__(/*! ../main/omutils */ "../main/omutils"); const VideoUtil = __webpack_require__(/*! ../settings/video-util */ "../settings/video-util"); const MicLevel = __webpack_require__(/*! ../settings/mic-level */ "../settings/mic-level"); const WebRtcPeer = __webpack_require__(/*! ../settings/WebRtcPeer */ "../settings/WebRtcPeer"); const VideoSettings = __webpack_require__(/*! ../settings/settings */ "../settings/settings"); const AudioCtx = window.AudioContext || window.webkitAudioContext; const VideoMgrUtil = __webpack_require__(/*! ./video-manager-util */ "./src/room/video-manager-util.js"); const Sharer = __webpack_require__(/*! ./sharer */ "./src/room/sharer.js"); const Volume = __webpack_require__(/*! ./volume */ "./src/room/volume.js"); module.exports = class Video { constructor(msg) { const states = [], self = this, vidSize = {}; let sd, v, vc, t, footer, size, vol, iceServers , lm, level, userSpeaks = false, muteOthers , hasVideo, isSharing, isRecording; function __getState() { const state = states.length > 0 ? states[0] : null; if (!state || state.disposed) { return null; } return state; } function __getVideo(_state) { const vid = self.video(_state); return vid && vid.length > 0 ? vid[0] : null; } function _resizeDlgArea(_w, _h) { if (Room.getOptions().interview) { VideoUtil.setPos(v, VideoUtil.getPos()); } else if (v.dialog('instance')) { v.dialog('option', 'width', _w).dialog('option', 'height', _h); } } function _micActivity(speaks) { if (speaks !== userSpeaks) { userSpeaks = speaks; OmUtil.sendMessage({type: 'mic', id: 'activity', active: speaks}); } } function _getScreenStream(msg, state, callback) { function __handleScreenError(err) { VideoMgrUtil.sendMessage({id: 'errorSharing'}); Sharer.setShareState(Sharer.SHARE_STOPPED); Sharer.setRecState(Sharer.SHARE_STOPPED); OmUtil.error(err); } const b = VideoUtil.browser; let promise, cnts; if (VideoUtil.isEdge() && b.major > 16) { cnts = { video: true }; promise = navigator.getDisplayMedia(cnts); } else if (VideoUtil.sharingSupported()) { cnts = { video: true }; if (VideoUtil.isSafari()) { promise = new Promise((resolve) => { VideoUtil.askPermission(resolve); }).then(() => navigator.mediaDevices.getDisplayMedia(cnts)); } else { promise = navigator.mediaDevices.getDisplayMedia(cnts); } } else { promise = new Promise(() => { Sharer.close(); throw 'Screen-sharing is not supported in ' + b.name + '[' + b.major + ']'; }); } promise.then(stream => { if (!state.disposed) { __createVideo(state); state.stream = stream; callback(msg, state, cnts); } }).catch(__handleScreenError); } function _getVideoStream(msg, state, callback) { VideoSettings.constraints(sd, function(cnts) { if (VideoUtil.hasCam(sd) !== cnts.videoEnabled || VideoUtil.hasMic(sd) !== cnts.audioEnabled) { VideoMgrUtil.sendMessage({ id : 'devicesAltered' , uid: sd.uid , audio: cnts.audioEnabled , video: cnts.videoEnabled }); } if (!cnts.audio && !cnts.video) { OmUtil.error('Requested devices are not available'); VideoMgrUtil.close(sd.uid) return; } navigator.mediaDevices.getUserMedia(cnts) .then(stream => { if (state.disposed || msg.instanceUid !== v.data('instance-uid')) { return; } stream.getVideoTracks().forEach(track => track.enabled = cnts.videoEnabled); stream.getAudioTracks().forEach(track => track.enabled = cnts.audioEnabled); state.localStream = stream; if (__pttEnabled(state)) { OmUtil.alert('warning', $('#user-video').data('ptt-info'), 10000); } let _stream = stream; const data = {}; if (stream.getAudioTracks().length !== 0) { lm = vc.find('.level-meter'); lm.show(); data.aCtx = new AudioCtx(); data.gainNode = data.aCtx.createGain(); data.analyser = data.aCtx.createAnalyser(); data.aSrc = data.aCtx.createMediaStreamSource(stream); data.aSrc.connect(data.gainNode); data.gainNode.connect(data.analyser); if (VideoUtil.isEdge()) { data.analyser.connect(data.aCtx.destination); } else { data.aDest = data.aCtx.createMediaStreamDestination(); data.analyser.connect(data.aDest); _stream = data.aDest.stream; stream.getVideoTracks().forEach(track => _stream.addTrack(track)); } } state.data = data; __createVideo(state); state.stream = _stream; callback(msg, state, cnts); }) .catch(function(err) { VideoMgrUtil.sendMessage({ id : 'devicesAltered' , uid: sd.uid , audio: false , video: false }); VideoMgrUtil.close(sd.uid); if ('NotReadableError' === err.name) { OmUtil.error('Camera/Microphone is busy and can\'t be used'); } else { OmUtil.error(err); } }); }); } function __connectionStateChangeListener(state) { const pc = state.data.rtcPeer.pc; console.warn(`!!RTCPeerConnection state changed: ${pc.connectionState}, user: ${sd.user.displayName}, uid: ${sd.uid}`); switch(pc.connectionState) { case "connected": if (sd.self) { // The connection has become fully connected OmUtil.alert('info', `Connection to Media server has been established`, 3000);//notify user } break; case "disconnected": case "failed": //connection has been dropped OmUtil.alert('warning', `Media server connection for user ${sd.user.displayName} is ${pc.connectionState}, will try to re-connect`, 3000);//notify user _refresh(); break; case "closed": // The connection has been closed break; } } function __createSendPeer(msg, state, cnts) { state.options = { mediaStream: state.stream , mediaConstraints: cnts , onIceCandidate: self.onIceCandidate , onConnectionStateChange: () => __connectionStateChangeListener(state) }; const vid = __getVideo(state); VideoUtil.playSrc(vid, state.stream, true); const data = state.data; data.rtcPeer = new WebRtcPeer.Sendonly(VideoUtil.addIceServers(state.options, msg)); if (data.analyser) { level = new MicLevel(); level.meter(data.analyser, lm, _micActivity, OmUtil.error); } data.rtcPeer.createOffer() .then(sdpOffer => { data.rtcPeer.processLocalOffer(sdpOffer); OmUtil.log('Invoking Sender SDP offer callback function'); const bmsg = { id : 'broadcastStarted' , uid: sd.uid , sdpOffer: sdpOffer.sdp }, vtracks = state.stream.getVideoTracks(); if (vtracks && vtracks.length > 0) { const vts = vtracks[0].getSettings(); vidSize.width = vts.width; vidSize.height = vts.height; bmsg.width = vts.width; bmsg.height = vts.height; bmsg.fps = vts.frameRate; } VideoMgrUtil.sendMessage(bmsg); if (isSharing) { Sharer.setShareState(Sharer.SHARE_STARTED); } if (isRecording) { Sharer.setRecState(Sharer.SHARE_STARTED); } }) .catch(error => OmUtil.error(error)); } function _createSendPeer(msg, state) { if (isSharing || isRecording) { _getScreenStream(msg, state, __createSendPeer); } else { _getVideoStream(msg, state, __createSendPeer); } } function _createResvPeer(msg, state) { __createVideo(state); const options = VideoUtil.addIceServers({ mediaConstraints: {audio: true, video: true} , onIceCandidate : self.onIceCandidate , onConnectionStateChange: () => __connectionStateChangeListener(state) }, msg); const data = state.data; data.rtcPeer = new WebRtcPeer.Recvonly(options); data.rtcPeer.createOffer() .then(sdpOffer => { data.rtcPeer.processLocalOffer(sdpOffer); OmUtil.log('Invoking Receiver SDP offer callback function'); VideoMgrUtil.sendMessage({ id : 'addListener' , sender: sd.uid , sdpOffer: sdpOffer.sdp }); }) .catch(genErr => OmUtil.error('Receiver sdp offer error ' + genErr)); } function _handleMicStatus(state) { if (!footer || !footer.is(':visible')) { return; } if (state) { footer.text(footer.data('on')); footer.addClass('mic-on'); t.addClass('mic-on'); } else { footer.text(footer.data('off')); footer.removeClass('mic-on'); t.removeClass('mic-on'); } } function _initContainer(_id, name, opts, instanceUid) { let contSel = '#user' + sd.cuid; const _hasVideo = VideoUtil.hasVideo(sd) if (_hasVideo) { const s = VideoSettings.load(); if (s.fixed.enabled && !opts.interview && !isSharing) { size = { width: s.fixed.width , height: s.fixed.height }; } else { size = { width: sd.width , height: sd.height }; } } else { size = { width: 120 , height: 90 }; } hasVideo = _hasVideo || $(contSel).length < 1; if (hasVideo) { if (opts.interview) { const area = $('.pod-area'); const contId = crypto.randomUUID(); contSel = '#' + contId; area.append($('
').attr('id', contId)); WbArea.updateAreaClass(); } else { contSel = '.room-block .room-container'; } } $(contSel).append(OmUtil.tmpl('#user-video', _id) .attr('title', name) .attr('data-client-uid', sd.cuid) .attr('data-client-type', sd.type) .attr('data-instance-uid', instanceUid) .data(self)); v = $('#' + _id); vc = v.find('.video'); muteOthers = vc.find('.mute-others'); _setRights(); return contSel; } function _initDialog(v, opts) { if (opts.interview) { v.dialog('option', 'draggable', false); v.dialog('option', 'resizable', false); $('.pod-area').sortable('refresh'); } else { v.dialog('option', 'draggable', true); v.dialog('option', 'resizable', true); if (isSharing) { v.on('dialogclose', function() { VideoMgrUtil.close(sd.uid, true); }); } const ui = v.closest('.ui-dialog'); const parent = $('.room-block .room-container .sb-wb'); ui.draggable('option', 'containment', parent); ui.resizable('option', 'containment', parent); } _initDialogBtns(opts); } function _initDialogBtns(opts) { function noDblClick(elem) { elem.dblclick(function(e) { e.stopImmediatePropagation(); return false; }); } v.parent().find('.ui-dialog-titlebar-close').remove(); v.parent().append(OmUtil.tmpl('#video-button-bar')); const refresh = v.parent().find('.btn-refresh') , tgl = v.parent().find('.btn-toggle') , cls = v.parent().find('.btn-wclose'); if (isSharing) { cls.click(function (_) { v.dialog('close'); return false; }); noDblClick(cls); refresh.remove(); } else { cls.remove(); refresh.click(function(e) { e.stopImmediatePropagation(); _refresh(); return false; }); } if (opts.interview) { tgl.remove(); } else { tgl.click(function (e) { e.stopImmediatePropagation(); $(this).toggleClass('minimized'); v.toggle(); return false; }); noDblClick(tgl); } } function _update(_c) { const prevA = sd.activities , prevW = vidSize.width || sd.width // try to check actual size of video first , prevH = vidSize.height || sd.height // try to check actual size of video first , prevCam = sd.cam , prevMic = sd.mic; sd.activities = _c.activities.sort(); sd.level = _c.level; sd.user.firstName = _c.user.firstName; sd.user.lastName = _c.user.lastName; sd.user.displayName = _c.user.displayName; sd.width = _c.width; sd.height = _c.height; sd.cam = _c.cam; sd.mic = _c.mic; const name = sd.user.displayName; if (hasVideo) { v.dialog('option', 'title', name).parent().find('.ui-dialog-titlebar').attr('title', name); } const same = prevA.length === sd.activities.length && prevA.every(function(value, index) { return value === sd.activities[index]}) && prevW === sd.width && prevH === sd.height && prevCam == sd.cam && prevMic === sd.mic; const camChanged = sd.camEnabled !== _c.camEnabled , micChanged = sd.micEnabled !== _c.micEnabled if (sd.self && !same) { _cleanup(); v.remove(); _init({stream: sd, iceServers: iceServers}); } else if (camChanged || micChanged) { sd.micEnabled = _c.micEnabled; sd.camEnabled = _c.camEnabled; const state = __getState(); if (camChanged) { VideoMgrUtil.savePod(v); v.off(); if (v.dialog('instance')) { v.dialog('destroy'); } v.remove(); __initUI(v.data('instance-uid')); __createVideo(state); VideoUtil.playSrc(state.video[0], state.stream || state.rStream, sd.self); if (state.data.analyser) { lm = vc.find('.level-meter'); level.setCanvas(lm); } } if (micChanged) { __updateVideo(state); } if (sd.self) { state.localStream.getVideoTracks().forEach(track => track.enabled = sd.camEnabled); state.localStream.getAudioTracks().forEach(track => track.enabled = sd.micEnabled); } } } function __createVideo(state) { const _id = VideoUtil.getVid(sd.uid); _resizeDlgArea(size.width, size.height); if (hasVideo && !isSharing && !isRecording) { // let's try to restore size+position const opts = Room.getOptions() , stored = $(`#user${sd.cuid}`).data('video-pod'); if (!opts.interview && stored) { const widget = v.dialog('widget'); widget.css('left', stored.x); widget.css('top', stored.y) widget.css('width', stored.w); widget.css('height', stored.h) } else { VideoUtil.setPos(v, VideoUtil.getPos(VideoUtil.getRects(VideoUtil.VIDWIN_SEL, _id), sd.width, sd.height + 25)); } } state.video = $(hasVideo ? '