@reactoo/watchtogether-sdk-js 2.6.99 → 2.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* @reactoo/watchtogether-sdk-js
|
|
3
|
-
* @version 2.
|
|
3
|
+
* @version 2.7.2
|
|
4
4
|
*/
|
|
5
5
|
(function webpackUniversalModuleDefinition(root, factory) {
|
|
6
6
|
if(typeof exports === 'object' && typeof module === 'object')
|
|
@@ -8640,7 +8640,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n\n\nlet iot = function () {\n
|
|
|
8640
8640
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
8641
8641
|
|
|
8642
8642
|
"use strict";
|
|
8643
|
-
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _modules_wt_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../modules/wt-utils */ \"./src/modules/wt-utils.js\");\n/* harmony import */ var _modules_wt_emitter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../modules/wt-emitter */ \"./src/modules/wt-emitter.js\");\n/* harmony import */ var _modules_sync_modules_sync_hls__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../modules/sync-modules/sync-hls */ \"./src/modules/sync-modules/sync-hls.js\");\n/* harmony import */ var _modules_sync_modules_sync_hls_vod__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../modules/sync-modules/sync-hls-vod */ \"./src/modules/sync-modules/sync-hls-vod.js\");\n/* harmony import */ var _modules_sync_modules_sync_native_hls_vod__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../modules/sync-modules/sync-native-hls-vod */ \"./src/modules/sync-modules/sync-native-hls-vod.js\");\n/* harmony import */ var _modules_sync_modules_sync_native_hls__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../modules/sync-modules/sync-native-hls */ \"./src/modules/sync-modules/sync-native-hls.js\");\n/* harmony import */ var _modules_sync_modules_sync_shaka_dash__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../modules/sync-modules/sync-shaka-dash */ \"./src/modules/sync-modules/sync-shaka-dash.js\");\n/* harmony import */ var _modules_sync_modules_sync_shaka_dash_vod__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../modules/sync-modules/sync-shaka-dash-vod */ \"./src/modules/sync-modules/sync-shaka-dash-vod.js\");\n/* harmony import */ var _modules_sync_modules_sync_dash__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../modules/sync-modules/sync-dash */ \"./src/modules/sync-modules/sync-dash.js\");\n/* harmony import */ var _modules_sync_modules_sync_dash_vod__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../modules/sync-modules/sync-dash-vod */ \"./src/modules/sync-modules/sync-dash-vod.js\");\n/* harmony import */ var _modules_sync_modules_sync_doris__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../modules/sync-modules/sync-doris */ \"./src/modules/sync-modules/sync-doris.js\");\n/* harmony import */ var _modules_sync_modules_sync_disabled__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../modules/sync-modules/sync-disabled */ \"./src/modules/sync-modules/sync-disabled.js\");\n/* harmony import */ var _modules_sync_modules_sync_dazn_dash__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../modules/sync-modules/sync-dazn-dash */ \"./src/modules/sync-modules/sync-dazn-dash.js\");\n/* harmony import */ var _modules_sync_modules_sync_dazn__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../modules/sync-modules/sync-dazn */ \"./src/modules/sync-modules/sync-dazn.js\");\n/* harmony import */ var _modules_sync_modules_sync_module__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../modules/sync-modules/sync-module */ \"./src/modules/sync-modules/sync-module.js\");\n\n\n\n\n\n// SYNCHRONISATION MODULES\n\n\n\n\n\n\n\n\n\n\n\n\n\nlet roomSession = function (_ref, room, wt) {\n let {\n roomId,\n pinHash,\n role,\n options = {}\n } = _ref;\n let primaryRoomId = roomId;\n let {\n simulcast = null,\n simulcastBitrates = null,\n simulcastMode = null,\n simulcastDefaultManualSubstream = null\n } = options;\n let publicCustomEvents = ['changePlayerSource', 'chatMessage', 'userUpdate', 'reconnecting', 'connecting', 'remoteMuted', 'scaling'];\n const addEvents = events => {\n publicCustomEvents = [...publicCustomEvents, ...events];\n };\n const removeEvents = events => {\n publicCustomEvents = publicCustomEvents.filter(ev => events.indexOf(ev) === -1);\n };\n const emitter = Object(_modules_wt_emitter__WEBPACK_IMPORTED_MODULE_1__[\"default\"])();\n let alpTimeoutId = null;\n let abortController = null;\n let ___; // return object\n\n room.on('addLocalParticipant', () => {\n // TODO: this doesnt seem to be fixable until we switch to different type of messaging\n // At some random case we don't get message back if we don't wait\n\n clearTimeout(alpTimeoutId);\n alpTimeoutId = setTimeout(() => {\n ___.__requestMuteStatus();\n }, 2000);\n });\n room.on('localMuted', _ref2 => {\n let {\n type,\n value,\n source,\n mid\n } = _ref2;\n ___.sendSystemMessage('remote_muted', {\n type,\n value,\n source,\n mid\n });\n });\n room.on('data', data => {\n ___.__parseDataEvents(data);\n });\n return ___ = {\n syncModule: null,\n playerInterface: null,\n get userId() {\n return room.userId;\n },\n get roomId() {\n return roomId;\n },\n get sessionId() {\n return room.sessionId;\n },\n get constructId() {\n return room.constructId;\n },\n // needs to be called before connect or it doesn't have any effect\n changeUserRole: function (newRole) {\n role = newRole;\n },\n kill: function () {\n clearTimeout(alpTimeoutId);\n this.detachPlayer();\n return room.destroy().finally(() => {\n this.$clear();\n return true;\n });\n },\n destroy: function () {\n return wt.room.destroySession(room.constructId);\n },\n connect: function () {\n var _abortController;\n let {\n reactooRoomId = null\n } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n emitter.emit('connecting', true);\n clearTimeout(alpTimeoutId);\n abortController = new AbortController();\n return wt.room.__joinRoom({\n roomId: reactooRoomId || primaryRoomId,\n pinHash,\n role\n }, (_abortController = abortController) === null || _abortController === void 0 ? void 0 : _abortController.signal).then(roomData => {\n var _roomData$data, _roomData$data2, _roomData$data3, _roomData$data3$simul, _roomData$data4, _roomData$data4$simul, _roomData$data5, _roomData$data5$simul;\n // Happens when we reroute user to a different room\n if ((roomData === null || roomData === void 0 ? void 0 : (_roomData$data = roomData.data) === null || _roomData$data === void 0 ? void 0 : _roomData$data.reactooRoomId) !== roomId) {\n roomId = roomData.data.reactooRoomId;\n emitter.emit('changeRoomId', roomId);\n }\n room.setRoomType(roomData.data.roomType);\n return room.connect(roomData.data.roomId, roomData.data.pin, roomData.data.href, roomData.data.iceServers, roomData.data.accessToken, roomData.data.display, roomData.data.userId, roomData.data.webrtcVersion, roomData.data.bitrate ? parseInt(roomData.data.bitrate) : 0, roomData.data.recordingFilename, simulcast !== null ? simulcast : roomData === null || roomData === void 0 ? void 0 : (_roomData$data2 = roomData.data) === null || _roomData$data2 === void 0 ? void 0 : _roomData$data2.simulcast, simulcastBitrates !== null ? simulcastBitrates : roomData === null || roomData === void 0 ? void 0 : (_roomData$data3 = roomData.data) === null || _roomData$data3 === void 0 ? void 0 : (_roomData$data3$simul = _roomData$data3.simulcast) === null || _roomData$data3$simul === void 0 ? void 0 : _roomData$data3$simul.bitrates, simulcastMode !== null ? simulcastMode : roomData === null || roomData === void 0 ? void 0 : (_roomData$data4 = roomData.data) === null || _roomData$data4 === void 0 ? void 0 : (_roomData$data4$simul = _roomData$data4.simulcast) === null || _roomData$data4$simul === void 0 ? void 0 : _roomData$data4$simul.mode, simulcastDefaultManualSubstream !== null ? simulcastDefaultManualSubstream : roomData === null || roomData === void 0 ? void 0 : (_roomData$data5 = roomData.data) === null || _roomData$data5 === void 0 ? void 0 : (_roomData$data5$simul = _roomData$data5.simulcast) === null || _roomData$data5$simul === void 0 ? void 0 : _roomData$data5$simul.defaultManualSubstream);\n }).finally(() => {\n emitter.emit('connecting', false);\n });\n },\n disconnect: function (dontWaitForResponses) {\n var _abortController2, _abortController2$abo;\n clearTimeout(alpTimeoutId);\n (_abortController2 = abortController) === null || _abortController2 === void 0 ? void 0 : (_abortController2$abo = _abortController2.abort) === null || _abortController2$abo === void 0 ? void 0 : _abortController2$abo.call(_abortController2);\n return room.disconnect(dontWaitForResponses);\n },\n //TODO: refactor restart method\n restart: function () {\n var _handle$webrtcStuff;\n let {\n isObserver = false,\n reactooRoomId = null\n } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n emitter.emit('reconnecting', true);\n room.isRestarting = true;\n let wasPublished = room.isPublished;\n let handle = room._getHandle(room.handleId);\n let stream = null;\n if (handle !== null && handle !== void 0 && (_handle$webrtcStuff = handle.webrtcStuff) !== null && _handle$webrtcStuff !== void 0 && _handle$webrtcStuff.stream && wasPublished) {\n stream = handle.webrtcStuff.stream;\n }\n return this.disconnect().then(() => Object(_modules_wt_utils__WEBPACK_IMPORTED_MODULE_0__[\"wait\"])(1000)) //TODO: remove 1000ms wait by waiting for proper events from janus\n .then(() => this.connect({\n reactooRoomId\n })).then(() => {\n if (isObserver) {\n return this.publishLocal(null);\n } else if (stream) {\n return this.publishLocal(stream);\n } else return Promise.resolve();\n }).then(() => {\n room.isRestarting = false;\n emitter.emit('reconnecting', false);\n return 1;\n }).catch(error => {\n room.isRestarting = false;\n emitter.emit('reconnecting', false);\n emitter.emit('error', {\n type: 'error',\n id: 26,\n message: 'reconnecting failed',\n data: error\n });\n return Promise.reject(0);\n });\n },\n getStats: function () {\n let type = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;\n return room._getStats(type);\n },\n getRoomParticipants: function () {\n return room._participants;\n },\n __parseDataEvents: function () {\n let msg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n if (msg.videoroom === 'message') {\n if (msg.action === 'pending_shutdown' || msg.action === 'shutting_down') {\n emitter.emit('scaling');\n this.restart(); // current videoroom was reassigned to a different WebRTC instance\n } else if (msg.action === 'force_restart') {\n this.restart();\n } else if (msg.action === 'user_update_displayname' || msg.action === 'user_update_avatar' || msg.action === 'user_update_customattributes' || msg.action === 'user_update_privateattributes') {\n emitter.emit('userUpdate', msg.text);\n } else if (msg.action === 'bitrate_changed') {\n this.setBitrateCap(msg.text);\n } else if (msg.user_action === 'chat_message') {\n emitter.emit('chatMessage', msg);\n } else if (msg.user_action === 'remote_muted') {\n var _decodeJanusDisplay, _decodeJanusDisplay2;\n const fromUserId = (_decodeJanusDisplay = Object(_modules_wt_utils__WEBPACK_IMPORTED_MODULE_0__[\"decodeJanusDisplay\"])(msg.from)) === null || _decodeJanusDisplay === void 0 ? void 0 : _decodeJanusDisplay.userId;\n const ownUserId = (_decodeJanusDisplay2 = Object(_modules_wt_utils__WEBPACK_IMPORTED_MODULE_0__[\"decodeJanusDisplay\"])(room.userId)) === null || _decodeJanusDisplay2 === void 0 ? void 0 : _decodeJanusDisplay2.userId;\n if (fromUserId !== ownUserId) {\n var _decodeJanusDisplay3, _decodeJanusDisplay4;\n emitter.emit('remoteMuted', {\n role: (_decodeJanusDisplay3 = Object(_modules_wt_utils__WEBPACK_IMPORTED_MODULE_0__[\"decodeJanusDisplay\"])(msg.from)) === null || _decodeJanusDisplay3 === void 0 ? void 0 : _decodeJanusDisplay3.role,\n userId: (_decodeJanusDisplay4 = Object(_modules_wt_utils__WEBPACK_IMPORTED_MODULE_0__[\"decodeJanusDisplay\"])(msg.from)) === null || _decodeJanusDisplay4 === void 0 ? void 0 : _decodeJanusDisplay4.userId,\n ...(msg.text && JSON.parse(msg.text))\n });\n }\n } else if (msg.user_action === 'remote_muted_request') {\n var _decodeJanusDisplay5, _decodeJanusDisplay6;\n const fromUserId = (_decodeJanusDisplay5 = Object(_modules_wt_utils__WEBPACK_IMPORTED_MODULE_0__[\"decodeJanusDisplay\"])(msg.from)) === null || _decodeJanusDisplay5 === void 0 ? void 0 : _decodeJanusDisplay5.userId;\n const ownUserId = (_decodeJanusDisplay6 = Object(_modules_wt_utils__WEBPACK_IMPORTED_MODULE_0__[\"decodeJanusDisplay\"])(room.userId)) === null || _decodeJanusDisplay6 === void 0 ? void 0 : _decodeJanusDisplay6.userId;\n if (fromUserId !== ownUserId) {\n this.__sendMuteStatus();\n }\n }\n }\n },\n // DAZN interface\n renderPlayer: function (playerWrapper, fullscreenElement, roomId) {\n try {\n this.syncModule = Object(_modules_sync_modules_sync_dazn__WEBPACK_IMPORTED_MODULE_13__[\"default\"])({\n room,\n wt,\n roomSession: this,\n emitter\n });\n this.playerInterface = wt.__privates.playerFactory(playerWrapper, fullscreenElement, this.syncModule.getHandlers(), {\n roomId\n });\n this.syncModule.initialize({\n playerInterface: this.playerInterface\n });\n return true;\n } catch (e) {\n return false;\n }\n },\n attachPlayer: function (type, inputs) {\n this.detachPlayer();\n if (type === 'universal') {\n this.syncModule = Object(_modules_sync_modules_sync_module__WEBPACK_IMPORTED_MODULE_14__[\"default\"])({\n room,\n emitter\n });\n if (this.syncModule.__events) {\n addEvents(this.syncModule.__events);\n }\n this.syncModule.initialize(inputs);\n }\n\n // Everything below is for legacy player and will be removed in the future\n else if (type === 'hlsjs') {\n this.syncModule = Object(_modules_sync_modules_sync_hls__WEBPACK_IMPORTED_MODULE_2__[\"default\"])({\n room,\n wt,\n roomSession: this,\n emitter\n });\n if (this.syncModule.__events) {\n addEvents(this.syncModule.__events);\n }\n this.syncModule.initialize(inputs);\n } else if (type === 'hlsjs-vod') {\n this.syncModule = Object(_modules_sync_modules_sync_hls_vod__WEBPACK_IMPORTED_MODULE_3__[\"default\"])({\n room,\n wt,\n roomSession: this,\n emitter\n });\n if (this.syncModule.__events) {\n addEvents(this.syncModule.__events);\n }\n this.syncModule.initialize(inputs);\n } else if (type === 'hlsnative-vod') {\n this.syncModule = Object(_modules_sync_modules_sync_native_hls_vod__WEBPACK_IMPORTED_MODULE_4__[\"default\"])({\n room,\n wt,\n roomSession: this,\n emitter\n });\n if (this.syncModule.__events) {\n addEvents(this.syncModule.__events);\n }\n this.syncModule.initialize(inputs);\n } else if (type === 'hlsnative') {\n this.syncModule = Object(_modules_sync_modules_sync_native_hls__WEBPACK_IMPORTED_MODULE_5__[\"default\"])({\n room,\n wt,\n roomSession: this,\n emitter\n });\n if (this.syncModule.__events) {\n addEvents(this.syncModule.__events);\n }\n this.syncModule.initialize(inputs);\n } else if (type === 'shaka-dash-vod') {\n this.syncModule = Object(_modules_sync_modules_sync_shaka_dash_vod__WEBPACK_IMPORTED_MODULE_7__[\"default\"])({\n room,\n wt,\n roomSession: this,\n emitter\n });\n if (this.syncModule.__events) {\n addEvents(this.syncModule.__events);\n }\n this.syncModule.initialize(inputs);\n } else if (type === 'shaka-dash') {\n this.syncModule = Object(_modules_sync_modules_sync_shaka_dash__WEBPACK_IMPORTED_MODULE_6__[\"default\"])({\n room,\n wt,\n roomSession: this,\n emitter\n });\n if (this.syncModule.__events) {\n addEvents(this.syncModule.__events);\n }\n this.syncModule.initialize(inputs);\n } else if (type === 'dashjs') {\n this.syncModule = Object(_modules_sync_modules_sync_dash__WEBPACK_IMPORTED_MODULE_8__[\"default\"])({\n room,\n wt,\n roomSession: this,\n emitter\n });\n if (this.syncModule.__events) {\n addEvents(this.syncModule.__events);\n }\n this.syncModule.initialize(inputs);\n } else if (type === 'dashjs-vod') {\n this.syncModule = Object(_modules_sync_modules_sync_dash_vod__WEBPACK_IMPORTED_MODULE_9__[\"default\"])({\n room,\n wt,\n roomSession: this,\n emitter\n });\n if (this.syncModule.__events) {\n addEvents(this.syncModule.__events);\n }\n this.syncModule.initialize(inputs);\n } else if (type === 'doris') {\n this.syncModule = Object(_modules_sync_modules_sync_doris__WEBPACK_IMPORTED_MODULE_10__[\"default\"])({\n room,\n wt,\n roomSession: this,\n emitter\n });\n if (this.syncModule.__events) {\n addEvents(this.syncModule.__events);\n }\n this.syncModule.initialize(inputs);\n } else if (type === 'dazn-dash') {\n this.syncModule = Object(_modules_sync_modules_sync_dazn_dash__WEBPACK_IMPORTED_MODULE_12__[\"default\"])({\n room,\n wt,\n roomSession: this,\n emitter\n });\n if (this.syncModule.__events) {\n addEvents(this.syncModule.__events);\n }\n this.syncModule.initialize(inputs);\n } else if (type === 'disabled') {\n this.syncModule = Object(_modules_sync_modules_sync_disabled__WEBPACK_IMPORTED_MODULE_11__[\"default\"])({\n room,\n wt,\n roomSession: this,\n emitter\n });\n if (this.syncModule.__events) {\n addEvents(this.syncModule.__events);\n }\n this.syncModule.initialize(inputs);\n } else {\n room._log('Synchronisation type not recognised');\n }\n },\n detachPlayer: function () {\n if (this.syncModule) {\n this.playerInterface = null;\n this.syncModule.destroy();\n if (this.syncModule.__events) {\n removeEvents(this.syncModule.__events);\n }\n this.syncModule = null;\n }\n },\n publishLocal: function () {\n let stream = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;\n let source = arguments.length > 1 ? arguments[1] : undefined;\n return room.publishLocal(stream, source);\n },\n unpublishLocal: () => {\n return room.unpublishLocal();\n },\n toggleAudio: (value, source) => {\n return room.toggleAudio(value, source);\n },\n toggleVideo: (value, source) => {\n return room.toggleVideo(value, source);\n },\n setTalkIntercomChannels: groups => {\n return room.setTalkIntercomChannels(groups);\n },\n getTalkIntercomChannels: () => {\n return room._talkIntercomChannels;\n },\n getUserTalkIntercomChannels: userId => {\n return room.getUserTalkIntercomChannels(userId);\n },\n setListenIntercomChannels: groups => {\n return room.setListenIntercomChannels(groups);\n },\n getListenIntercomChannels: () => {\n return room._listenIntercomChannels;\n },\n requestKeyFrame: (handleId, mid) => {\n return room.requestKeyFrame(handleId, mid);\n },\n selectSubStream: (handleId, substream, source, mid) => {\n return room.selectSubStream(handleId, substream, source, mid, true);\n },\n setBitrateCap: bitrate => {\n if (role === 'host') {\n return;\n }\n return room.sendMessage(room.handleId, {\n \"body\": {\n \"request\": \"configure\",\n \"bitrate\": parseInt(bitrate)\n }\n }).catch(() => null);\n },\n sendSystemMessage: function (action) {\n let value = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n let to = arguments.length > 2 ? arguments[2] : undefined;\n let set_master = arguments.length > 3 ? arguments[3] : undefined;\n return room.sendMessage(room.handleId, {\n body: {\n action,\n request: \"message\",\n room: room.roomId,\n timestamp: new Date().getTime(),\n text: JSON.stringify(value),\n ...(to && Array.isArray(to) ? {\n tos: to\n } : {\n to\n }),\n ...(set_master && {\n set_master\n })\n }\n });\n },\n sendChatMessage: (text, to) => {\n return room.sendMessage(room.handleId, {\n body: {\n action: \"chat_message\",\n request: \"message\",\n room: room.roomId,\n timestamp: new Date().getTime(),\n text,\n ...(to && Array.isArray(to) ? {\n tos: to\n } : {\n to\n })\n }\n });\n },\n __requestMuteStatus: function () {\n this.sendSystemMessage('remote_muted_request');\n },\n __sendMuteStatus: function () {\n for (const val of room.isMuted) {\n this.sendSystemMessage('remote_muted', {\n ...val\n });\n }\n },\n $on: (key, callback, that) => {\n emitter.on(key, callback, that || this);\n room.on(key, callback, that || this);\n },\n $off: (key, callback, that) => {\n emitter.on(key, callback, that || this);\n room.on(key, callback, that || this);\n },\n $clear: function () {\n room.clear();\n emitter.clear();\n }\n };\n};\n/* harmony default export */ __webpack_exports__[\"default\"] = (roomSession);\n\n//# sourceURL=webpack://WatchTogetherSDK/./src/models/room-session.js?");
|
|
8643
|
+
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _modules_wt_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../modules/wt-utils */ \"./src/modules/wt-utils.js\");\n/* harmony import */ var _modules_wt_emitter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../modules/wt-emitter */ \"./src/modules/wt-emitter.js\");\n/* harmony import */ var _modules_sync_modules_sync_hls__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../modules/sync-modules/sync-hls */ \"./src/modules/sync-modules/sync-hls.js\");\n/* harmony import */ var _modules_sync_modules_sync_hls_vod__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../modules/sync-modules/sync-hls-vod */ \"./src/modules/sync-modules/sync-hls-vod.js\");\n/* harmony import */ var _modules_sync_modules_sync_native_hls_vod__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../modules/sync-modules/sync-native-hls-vod */ \"./src/modules/sync-modules/sync-native-hls-vod.js\");\n/* harmony import */ var _modules_sync_modules_sync_native_hls__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../modules/sync-modules/sync-native-hls */ \"./src/modules/sync-modules/sync-native-hls.js\");\n/* harmony import */ var _modules_sync_modules_sync_shaka_dash__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../modules/sync-modules/sync-shaka-dash */ \"./src/modules/sync-modules/sync-shaka-dash.js\");\n/* harmony import */ var _modules_sync_modules_sync_shaka_dash_vod__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../modules/sync-modules/sync-shaka-dash-vod */ \"./src/modules/sync-modules/sync-shaka-dash-vod.js\");\n/* harmony import */ var _modules_sync_modules_sync_dash__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../modules/sync-modules/sync-dash */ \"./src/modules/sync-modules/sync-dash.js\");\n/* harmony import */ var _modules_sync_modules_sync_dash_vod__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../modules/sync-modules/sync-dash-vod */ \"./src/modules/sync-modules/sync-dash-vod.js\");\n/* harmony import */ var _modules_sync_modules_sync_doris__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../modules/sync-modules/sync-doris */ \"./src/modules/sync-modules/sync-doris.js\");\n/* harmony import */ var _modules_sync_modules_sync_disabled__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../modules/sync-modules/sync-disabled */ \"./src/modules/sync-modules/sync-disabled.js\");\n/* harmony import */ var _modules_sync_modules_sync_dazn_dash__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../modules/sync-modules/sync-dazn-dash */ \"./src/modules/sync-modules/sync-dazn-dash.js\");\n/* harmony import */ var _modules_sync_modules_sync_dazn__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../modules/sync-modules/sync-dazn */ \"./src/modules/sync-modules/sync-dazn.js\");\n/* harmony import */ var _modules_sync_modules_sync_module__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../modules/sync-modules/sync-module */ \"./src/modules/sync-modules/sync-module.js\");\n\n\n\n\n\n// SYNCHRONISATION MODULES\n\n\n\n\n\n\n\n\n\n\n\n\n\nlet roomSession = function (_ref, room, wt) {\n let {\n roomId,\n pinHash,\n role,\n options = {}\n } = _ref;\n let primaryRoomId = roomId;\n let {\n simulcast = null,\n simulcastBitrates = null,\n simulcastMode = null,\n simulcastDefaultManualSubstream = null,\n enableDtx = null\n } = options;\n let publicCustomEvents = ['changePlayerSource', 'chatMessage', 'userUpdate', 'reconnecting', 'connecting', 'remoteMuted', 'scaling'];\n const addEvents = events => {\n publicCustomEvents = [...publicCustomEvents, ...events];\n };\n const removeEvents = events => {\n publicCustomEvents = publicCustomEvents.filter(ev => events.indexOf(ev) === -1);\n };\n const emitter = Object(_modules_wt_emitter__WEBPACK_IMPORTED_MODULE_1__[\"default\"])();\n let alpTimeoutId = null;\n let abortController = null;\n let ___; // return object\n\n room.on('addLocalParticipant', () => {\n // TODO: this doesnt seem to be fixable until we switch to different type of messaging\n // At some random case we don't get message back if we don't wait\n\n clearTimeout(alpTimeoutId);\n alpTimeoutId = setTimeout(() => {\n ___.__requestMuteStatus();\n }, 2000);\n });\n room.on('localMuted', _ref2 => {\n let {\n type,\n value,\n source,\n mid\n } = _ref2;\n ___.sendSystemMessage('remote_muted', {\n type,\n value,\n source,\n mid\n });\n });\n room.on('data', data => {\n ___.__parseDataEvents(data);\n });\n return ___ = {\n syncModule: null,\n playerInterface: null,\n get userId() {\n return room.userId;\n },\n get roomId() {\n return roomId;\n },\n get sessionId() {\n return room.sessionId;\n },\n get constructId() {\n return room.constructId;\n },\n // needs to be called before connect or it doesn't have any effect\n changeUserRole: function (newRole) {\n role = newRole;\n },\n kill: function () {\n clearTimeout(alpTimeoutId);\n this.detachPlayer();\n return room.destroy().finally(() => {\n this.$clear();\n return true;\n });\n },\n destroy: function () {\n return wt.room.destroySession(room.constructId);\n },\n connect: function () {\n var _abortController;\n let {\n reactooRoomId = null\n } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n emitter.emit('connecting', true);\n clearTimeout(alpTimeoutId);\n abortController = new AbortController();\n return wt.room.__joinRoom({\n roomId: reactooRoomId || primaryRoomId,\n pinHash,\n role\n }, (_abortController = abortController) === null || _abortController === void 0 ? void 0 : _abortController.signal).then(roomData => {\n var _roomData$data, _roomData$data2, _roomData$data3, _roomData$data3$simul, _roomData$data4, _roomData$data4$simul, _roomData$data5, _roomData$data5$simul, _roomData$data6;\n // Happens when we reroute user to a different room\n if ((roomData === null || roomData === void 0 ? void 0 : (_roomData$data = roomData.data) === null || _roomData$data === void 0 ? void 0 : _roomData$data.reactooRoomId) !== roomId) {\n roomId = roomData.data.reactooRoomId;\n emitter.emit('changeRoomId', roomId);\n }\n room.setRoomType(roomData.data.roomType);\n return room.connect(roomData.data.roomId, roomData.data.pin, roomData.data.href, roomData.data.iceServers, roomData.data.accessToken, roomData.data.display, roomData.data.userId, roomData.data.webrtcVersion, roomData.data.bitrate ? parseInt(roomData.data.bitrate) : 0, roomData.data.recordingFilename, simulcast !== null ? simulcast : roomData === null || roomData === void 0 ? void 0 : (_roomData$data2 = roomData.data) === null || _roomData$data2 === void 0 ? void 0 : _roomData$data2.simulcast, simulcastBitrates !== null ? simulcastBitrates : roomData === null || roomData === void 0 ? void 0 : (_roomData$data3 = roomData.data) === null || _roomData$data3 === void 0 ? void 0 : (_roomData$data3$simul = _roomData$data3.simulcast) === null || _roomData$data3$simul === void 0 ? void 0 : _roomData$data3$simul.bitrates, simulcastMode !== null ? simulcastMode : roomData === null || roomData === void 0 ? void 0 : (_roomData$data4 = roomData.data) === null || _roomData$data4 === void 0 ? void 0 : (_roomData$data4$simul = _roomData$data4.simulcast) === null || _roomData$data4$simul === void 0 ? void 0 : _roomData$data4$simul.mode, simulcastDefaultManualSubstream !== null ? simulcastDefaultManualSubstream : roomData === null || roomData === void 0 ? void 0 : (_roomData$data5 = roomData.data) === null || _roomData$data5 === void 0 ? void 0 : (_roomData$data5$simul = _roomData$data5.simulcast) === null || _roomData$data5$simul === void 0 ? void 0 : _roomData$data5$simul.defaultManualSubstream, enableDtx !== null ? enableDtx : roomData === null || roomData === void 0 ? void 0 : (_roomData$data6 = roomData.data) === null || _roomData$data6 === void 0 ? void 0 : _roomData$data6.enableDtx);\n }).finally(() => {\n emitter.emit('connecting', false);\n });\n },\n disconnect: function (dontWaitForResponses) {\n var _abortController2, _abortController2$abo;\n clearTimeout(alpTimeoutId);\n (_abortController2 = abortController) === null || _abortController2 === void 0 ? void 0 : (_abortController2$abo = _abortController2.abort) === null || _abortController2$abo === void 0 ? void 0 : _abortController2$abo.call(_abortController2);\n return room.disconnect(dontWaitForResponses);\n },\n //TODO: refactor restart method\n restart: function () {\n var _handle$webrtcStuff;\n let {\n isObserver = false,\n reactooRoomId = null\n } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n emitter.emit('reconnecting', true);\n room.isRestarting = true;\n let wasPublished = room.isPublished;\n let handle = room._getHandle(room.handleId);\n let stream = null;\n if (handle !== null && handle !== void 0 && (_handle$webrtcStuff = handle.webrtcStuff) !== null && _handle$webrtcStuff !== void 0 && _handle$webrtcStuff.stream && wasPublished) {\n stream = handle.webrtcStuff.stream;\n }\n return this.disconnect().then(() => Object(_modules_wt_utils__WEBPACK_IMPORTED_MODULE_0__[\"wait\"])(1000)) //TODO: remove 1000ms wait by waiting for proper events from janus\n .then(() => this.connect({\n reactooRoomId\n })).then(() => {\n if (isObserver) {\n return this.publishLocal(null);\n } else if (stream) {\n return this.publishLocal(stream);\n } else return Promise.resolve();\n }).then(() => {\n room.isRestarting = false;\n emitter.emit('reconnecting', false);\n return 1;\n }).catch(error => {\n room.isRestarting = false;\n emitter.emit('reconnecting', false);\n emitter.emit('error', {\n type: 'error',\n id: 26,\n message: 'reconnecting failed',\n data: error\n });\n return Promise.reject(0);\n });\n },\n getStats: function () {\n let type = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;\n return room._getStats(type);\n },\n getRoomParticipants: function () {\n return room._participants;\n },\n __parseDataEvents: function () {\n let msg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n if (msg.videoroom === 'message') {\n if (msg.action === 'pending_shutdown' || msg.action === 'shutting_down') {\n emitter.emit('scaling');\n this.restart(); // current videoroom was reassigned to a different WebRTC instance\n } else if (msg.action === 'force_restart') {\n this.restart();\n } else if (msg.action === 'user_update_displayname' || msg.action === 'user_update_avatar' || msg.action === 'user_update_customattributes' || msg.action === 'user_update_privateattributes') {\n emitter.emit('userUpdate', msg.text);\n } else if (msg.action === 'bitrate_changed') {\n this.setBitrateCap(msg.text);\n } else if (msg.user_action === 'chat_message') {\n emitter.emit('chatMessage', msg);\n } else if (msg.user_action === 'remote_muted') {\n var _decodeJanusDisplay, _decodeJanusDisplay2;\n const fromUserId = (_decodeJanusDisplay = Object(_modules_wt_utils__WEBPACK_IMPORTED_MODULE_0__[\"decodeJanusDisplay\"])(msg.from)) === null || _decodeJanusDisplay === void 0 ? void 0 : _decodeJanusDisplay.userId;\n const ownUserId = (_decodeJanusDisplay2 = Object(_modules_wt_utils__WEBPACK_IMPORTED_MODULE_0__[\"decodeJanusDisplay\"])(room.userId)) === null || _decodeJanusDisplay2 === void 0 ? void 0 : _decodeJanusDisplay2.userId;\n if (fromUserId !== ownUserId) {\n var _decodeJanusDisplay3, _decodeJanusDisplay4;\n emitter.emit('remoteMuted', {\n role: (_decodeJanusDisplay3 = Object(_modules_wt_utils__WEBPACK_IMPORTED_MODULE_0__[\"decodeJanusDisplay\"])(msg.from)) === null || _decodeJanusDisplay3 === void 0 ? void 0 : _decodeJanusDisplay3.role,\n userId: (_decodeJanusDisplay4 = Object(_modules_wt_utils__WEBPACK_IMPORTED_MODULE_0__[\"decodeJanusDisplay\"])(msg.from)) === null || _decodeJanusDisplay4 === void 0 ? void 0 : _decodeJanusDisplay4.userId,\n ...(msg.text && JSON.parse(msg.text))\n });\n }\n } else if (msg.user_action === 'remote_muted_request') {\n var _decodeJanusDisplay5, _decodeJanusDisplay6;\n const fromUserId = (_decodeJanusDisplay5 = Object(_modules_wt_utils__WEBPACK_IMPORTED_MODULE_0__[\"decodeJanusDisplay\"])(msg.from)) === null || _decodeJanusDisplay5 === void 0 ? void 0 : _decodeJanusDisplay5.userId;\n const ownUserId = (_decodeJanusDisplay6 = Object(_modules_wt_utils__WEBPACK_IMPORTED_MODULE_0__[\"decodeJanusDisplay\"])(room.userId)) === null || _decodeJanusDisplay6 === void 0 ? void 0 : _decodeJanusDisplay6.userId;\n if (fromUserId !== ownUserId) {\n this.__sendMuteStatus();\n }\n }\n }\n },\n // DAZN interface\n renderPlayer: function (playerWrapper, fullscreenElement, roomId) {\n try {\n this.syncModule = Object(_modules_sync_modules_sync_dazn__WEBPACK_IMPORTED_MODULE_13__[\"default\"])({\n room,\n wt,\n roomSession: this,\n emitter\n });\n this.playerInterface = wt.__privates.playerFactory(playerWrapper, fullscreenElement, this.syncModule.getHandlers(), {\n roomId\n });\n this.syncModule.initialize({\n playerInterface: this.playerInterface\n });\n return true;\n } catch (e) {\n return false;\n }\n },\n attachPlayer: function (type, inputs) {\n this.detachPlayer();\n if (type === 'universal') {\n this.syncModule = Object(_modules_sync_modules_sync_module__WEBPACK_IMPORTED_MODULE_14__[\"default\"])({\n room,\n emitter\n });\n if (this.syncModule.__events) {\n addEvents(this.syncModule.__events);\n }\n this.syncModule.initialize(inputs);\n }\n\n // Everything below is for legacy player and will be removed in the future\n else if (type === 'hlsjs') {\n this.syncModule = Object(_modules_sync_modules_sync_hls__WEBPACK_IMPORTED_MODULE_2__[\"default\"])({\n room,\n wt,\n roomSession: this,\n emitter\n });\n if (this.syncModule.__events) {\n addEvents(this.syncModule.__events);\n }\n this.syncModule.initialize(inputs);\n } else if (type === 'hlsjs-vod') {\n this.syncModule = Object(_modules_sync_modules_sync_hls_vod__WEBPACK_IMPORTED_MODULE_3__[\"default\"])({\n room,\n wt,\n roomSession: this,\n emitter\n });\n if (this.syncModule.__events) {\n addEvents(this.syncModule.__events);\n }\n this.syncModule.initialize(inputs);\n } else if (type === 'hlsnative-vod') {\n this.syncModule = Object(_modules_sync_modules_sync_native_hls_vod__WEBPACK_IMPORTED_MODULE_4__[\"default\"])({\n room,\n wt,\n roomSession: this,\n emitter\n });\n if (this.syncModule.__events) {\n addEvents(this.syncModule.__events);\n }\n this.syncModule.initialize(inputs);\n } else if (type === 'hlsnative') {\n this.syncModule = Object(_modules_sync_modules_sync_native_hls__WEBPACK_IMPORTED_MODULE_5__[\"default\"])({\n room,\n wt,\n roomSession: this,\n emitter\n });\n if (this.syncModule.__events) {\n addEvents(this.syncModule.__events);\n }\n this.syncModule.initialize(inputs);\n } else if (type === 'shaka-dash-vod') {\n this.syncModule = Object(_modules_sync_modules_sync_shaka_dash_vod__WEBPACK_IMPORTED_MODULE_7__[\"default\"])({\n room,\n wt,\n roomSession: this,\n emitter\n });\n if (this.syncModule.__events) {\n addEvents(this.syncModule.__events);\n }\n this.syncModule.initialize(inputs);\n } else if (type === 'shaka-dash') {\n this.syncModule = Object(_modules_sync_modules_sync_shaka_dash__WEBPACK_IMPORTED_MODULE_6__[\"default\"])({\n room,\n wt,\n roomSession: this,\n emitter\n });\n if (this.syncModule.__events) {\n addEvents(this.syncModule.__events);\n }\n this.syncModule.initialize(inputs);\n } else if (type === 'dashjs') {\n this.syncModule = Object(_modules_sync_modules_sync_dash__WEBPACK_IMPORTED_MODULE_8__[\"default\"])({\n room,\n wt,\n roomSession: this,\n emitter\n });\n if (this.syncModule.__events) {\n addEvents(this.syncModule.__events);\n }\n this.syncModule.initialize(inputs);\n } else if (type === 'dashjs-vod') {\n this.syncModule = Object(_modules_sync_modules_sync_dash_vod__WEBPACK_IMPORTED_MODULE_9__[\"default\"])({\n room,\n wt,\n roomSession: this,\n emitter\n });\n if (this.syncModule.__events) {\n addEvents(this.syncModule.__events);\n }\n this.syncModule.initialize(inputs);\n } else if (type === 'doris') {\n this.syncModule = Object(_modules_sync_modules_sync_doris__WEBPACK_IMPORTED_MODULE_10__[\"default\"])({\n room,\n wt,\n roomSession: this,\n emitter\n });\n if (this.syncModule.__events) {\n addEvents(this.syncModule.__events);\n }\n this.syncModule.initialize(inputs);\n } else if (type === 'dazn-dash') {\n this.syncModule = Object(_modules_sync_modules_sync_dazn_dash__WEBPACK_IMPORTED_MODULE_12__[\"default\"])({\n room,\n wt,\n roomSession: this,\n emitter\n });\n if (this.syncModule.__events) {\n addEvents(this.syncModule.__events);\n }\n this.syncModule.initialize(inputs);\n } else if (type === 'disabled') {\n this.syncModule = Object(_modules_sync_modules_sync_disabled__WEBPACK_IMPORTED_MODULE_11__[\"default\"])({\n room,\n wt,\n roomSession: this,\n emitter\n });\n if (this.syncModule.__events) {\n addEvents(this.syncModule.__events);\n }\n this.syncModule.initialize(inputs);\n } else {\n room._log('Synchronisation type not recognised');\n }\n },\n detachPlayer: function () {\n if (this.syncModule) {\n this.playerInterface = null;\n this.syncModule.destroy();\n if (this.syncModule.__events) {\n removeEvents(this.syncModule.__events);\n }\n this.syncModule = null;\n }\n },\n publishLocal: function () {\n let stream = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;\n let source = arguments.length > 1 ? arguments[1] : undefined;\n return room.publishLocal(stream, source);\n },\n unpublishLocal: () => {\n return room.unpublishLocal();\n },\n toggleAudio: (value, source) => {\n return room.toggleAudio(value, source);\n },\n toggleVideo: (value, source) => {\n return room.toggleVideo(value, source);\n },\n setRestrictSubscribeToUserIds: function () {\n let userIds = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];\n return room.setRestrictSubscribeToUserIds(userIds);\n },\n setTalkIntercomChannels: groups => {\n return room.setTalkIntercomChannels(groups);\n },\n getTalkIntercomChannels: () => {\n return room._talkIntercomChannels;\n },\n getUserTalkIntercomChannels: userId => {\n return room.getUserTalkIntercomChannels(userId);\n },\n setListenIntercomChannels: groups => {\n return room.setListenIntercomChannels(groups);\n },\n getListenIntercomChannels: () => {\n return room._listenIntercomChannels;\n },\n requestKeyFrame: (handleId, mid) => {\n return room.requestKeyFrame(handleId, mid);\n },\n selectSubStream: (handleId, substream, source, mid) => {\n return room.selectSubStream(handleId, substream, source, mid, true);\n },\n setBitrateCap: bitrate => {\n if (role === 'host') {\n return;\n }\n return room.sendMessage(room.handleId, {\n \"body\": {\n \"request\": \"configure\",\n \"bitrate\": parseInt(bitrate)\n }\n }).catch(() => null);\n },\n sendSystemMessage: function (action) {\n let value = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n let to = arguments.length > 2 ? arguments[2] : undefined;\n let set_master = arguments.length > 3 ? arguments[3] : undefined;\n return room.sendMessage(room.handleId, {\n body: {\n action,\n request: \"message\",\n room: room.roomId,\n timestamp: new Date().getTime(),\n text: JSON.stringify(value),\n ...(to && Array.isArray(to) ? {\n tos: to\n } : {\n to\n }),\n ...(set_master && {\n set_master\n })\n }\n });\n },\n sendChatMessage: (text, to) => {\n return room.sendMessage(room.handleId, {\n body: {\n action: \"chat_message\",\n request: \"message\",\n room: room.roomId,\n timestamp: new Date().getTime(),\n text,\n ...(to && Array.isArray(to) ? {\n tos: to\n } : {\n to\n })\n }\n });\n },\n __requestMuteStatus: function () {\n this.sendSystemMessage('remote_muted_request');\n },\n __sendMuteStatus: function () {\n for (const val of room.isMuted) {\n this.sendSystemMessage('remote_muted', {\n ...val\n });\n }\n },\n $on: (key, callback, that) => {\n emitter.on(key, callback, that || this);\n room.on(key, callback, that || this);\n },\n $off: (key, callback, that) => {\n emitter.on(key, callback, that || this);\n room.on(key, callback, that || this);\n },\n $clear: function () {\n room.clear();\n emitter.clear();\n }\n };\n};\n/* harmony default export */ __webpack_exports__[\"default\"] = (roomSession);\n\n//# sourceURL=webpack://WatchTogetherSDK/./src/models/room-session.js?");
|
|
8644
8644
|
|
|
8645
8645
|
/***/ }),
|
|
8646
8646
|
|
|
@@ -8652,7 +8652,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _mod
|
|
|
8652
8652
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
8653
8653
|
|
|
8654
8654
|
"use strict";
|
|
8655
|
-
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _room_session__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./room-session */ \"./src/models/room-session.js\");\n/* harmony import */ var _streaming_session__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./streaming-session */ \"./src/models/streaming-session.js\");\n/* harmony import */ var _modules_wt_utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../modules/wt-utils */ \"./src/modules/wt-utils.js\");\n\n\n\n\n\nlet room = function () {\n var _this = this;\n let roomSessions = [];\n let setExitListeners = () => {\n window.addEventListener('pagehide', event => {\n if (!event.persisted) {\n this.room.destroySessions();\n }\n });\n window.addEventListener('beforeunload', () => {\n this.room.destroySessions();\n });\n };\n setExitListeners();\n return {\n //TODO:deprecated\n integration: function () {\n let data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n return _this.__privates.auth.__client.then(client => client.apis.system.integration({\n type: _this.__instanceType\n }, {\n requestBody: {\n ...data\n },\n requestInterceptor: req => {\n if (!req.headers) {\n req.headers = {};\n }\n req.headers['Authorization'] = 'Bearer ' + localStorage.getItem('rwt_idToken');\n return req;\n }\n }));\n },\n //TODO:deprecated\n getAnalytics: function () {\n let data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n return _this.__privates.auth.__client.then(client => client.apis.system.getAnalytics({\n instanceType: _this.__instanceType,\n ...data\n }));\n },\n sendChatMessage: _ref => {\n let {\n roomId,\n message,\n options,\n senderUserId\n } = _ref;\n return this.__privates.auth.__client.then(client => client.apis.wt.sendRoomMessage({}, {\n requestBody: {\n roomId,\n message,\n options,\n senderUserId\n }\n }));\n },\n createRoom: function () {\n let {\n title,\n description,\n isPublic,\n isRouter,\n isStudioLayout,\n wtChannelId,\n isHd,\n disableSync,\n reduceRoomControls,\n hasStudioChat,\n maxParticipants,\n customAttributes,\n chatRoomId,\n linkedRoomId,\n type,\n dotAttribute\n } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n let _da = dotAttribute ? Array.isArray(dotAttribute) ? dotAttribute.reduce((p, cv) => (p[cv.name] = cv.value) && p || p, {}) : {\n [dotAttribute.name]: dotAttribute.value\n } : {};\n return _this.__privates.auth.__client.then(client => client.apis.wt.createRoom({}, {\n requestBody: {\n title,\n description,\n isRouter,\n isPublic,\n isStudioLayout,\n wtChannelId,\n isHd,\n disableSync,\n reduceRoomControls,\n chatRoomId,\n linkedRoomId,\n hasStudioChat,\n maxParticipants,\n type,\n customAttributes,\n ..._da,\n instanceType: _this.__instanceType\n }\n }));\n },\n updateRoom: function () {\n let {\n roomId,\n title,\n description,\n isPublic,\n isRouter,\n recordings,\n slug,\n password,\n maxParticipants,\n setInstanceType = false,\n wtChannelId,\n isHd,\n isStudioLayout,\n hasStudioChat,\n reduceRoomControls,\n chatRoomId,\n linkedRoomId,\n type,\n disableSync,\n defaultRegion,\n customAttributes,\n dotAttribute\n } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n let _da = dotAttribute ? Array.isArray(dotAttribute) ? dotAttribute.reduce((p, cv) => (p[cv.name] = cv.value) && p || p, {}) : {\n [dotAttribute.name]: dotAttribute.value\n } : {};\n return _this.__privates.auth.__client.then(client => client.apis.wt.updateRoom({\n id: roomId\n }, {\n requestBody: {\n title,\n description,\n slug,\n password,\n isPublic,\n isRouter,\n isHd,\n isStudioLayout,\n hasStudioChat,\n maxParticipants,\n reduceRoomControls,\n chatRoomId,\n linkedRoomId,\n type,\n disableSync,\n defaultRegion,\n customAttributes,\n wtChannelId,\n ..._da,\n ...(setInstanceType && {\n instanceType: setInstanceType === true ? _this.__instanceType : setInstanceType\n }),\n ...(recordings && {\n recordings\n })\n }\n }));\n },\n deleteRoom: roomId => {\n return this.__privates.auth.__client.then(client => client.apis.wt.deleteRoom({\n id: roomId\n }));\n },\n leaveRoom: roomId => {\n return this.__privates.auth.__client.then(client => client.apis.wt.leave({\n roomId\n }));\n },\n updateLayout: _ref2 => {\n let {\n roomId,\n operation,\n name,\n attributeName,\n value,\n target\n } = _ref2;\n //operation : clearLayouts, setLayout, setLayouts, unsetLayout, setName, setTarget, setStyle, setAttribute, unsetAttribute,'sendMessage'\n\n return this.__privates.auth.__client.then(client => client.apis.wt.updateLayout({}, {\n requestBody: {\n roomId,\n operation,\n name,\n attributeName,\n value,\n target\n }\n }));\n },\n getInviteUrl: (roomId, domain, url) => {\n return this.__privates.auth.__client.then(client => client.apis.wt.invite({}, {\n requestBody: {\n roomId,\n domain: domain || location.host,\n url: url || location.href\n }\n }));\n },\n getRoomChatList: function () {\n let {\n roomId,\n type = \"normal\",\n size = 50,\n startKey = null\n } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n let apiParams = {\n roomId,\n type,\n size,\n ...(startKey && {\n startKey\n })\n };\n return _this.__privates.auth.__client.then(client => client.apis.wt.getRoomChatList(apiParams));\n },\n getRoomsList: function () {\n let {\n type = 'participant',\n activeOnly = null,\n instanceType = _this.__instanceType,\n size = 20,\n startKey = null,\n includeWtEventModels = false,\n demo = false,\n viewType = 'list',\n wtChannelId = undefined\n } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n let apiParams = {\n type,\n instanceType,\n size,\n includeWtEventModels,\n demo,\n viewType,\n ...(wtChannelId && {\n wtChannelId\n }),\n ...(activeOnly && {\n activeOnly\n }),\n ...(startKey && {\n startKey\n })\n };\n return _this.__privates.auth.__client.then(client => client.apis.wt.getRoomList(apiParams));\n },\n setUser: _ref3 => {\n let {\n messageId,\n userId,\n roomId,\n flag,\n timestamp,\n option\n } = _ref3;\n //leave, kick, ban, unban, approve, report\n return this.__privates.auth.__client.then(client => client.apis.wt.setUser({\n messageId,\n userId,\n roomId,\n flag,\n timestamp,\n option\n }));\n },\n getRoomById: function (id) {\n let pinHash = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined;\n let showPublic = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : undefined;\n let demo = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;\n let signal = arguments.length > 4 ? arguments[4] : undefined;\n return _this.__privates.auth.__client.then(client => client.apis.wt.getRoom({\n id,\n pinHash,\n \"public\": showPublic,\n demo\n }, {\n ...(signal ? {\n requestInterceptor: req => {\n req.signal = signal;\n return req;\n }\n } : {})\n }));\n },\n getRoomBySlug: function (slug) {\n let password = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined;\n let showPublic = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : undefined;\n let demo = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;\n return _this.__privates.auth.__client.then(client => client.apis.wt.getRoom({\n slug,\n password,\n \"public\": showPublic,\n demo\n }));\n },\n roomRecorder: function () {\n let {\n roomId,\n operation = 'get',\n config,\n outputs,\n destinationIds,\n screenWidth,\n screenHeight\n } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n return _this.__privates.auth.__client.then(client => client.apis.wt.recordRoom({}, {\n requestBody: {\n roomId,\n operation,\n config,\n outputs,\n destinationIds,\n screenWidth,\n screenHeight\n }\n }));\n },\n __joinRoom: function () {\n let {\n roomId,\n pinHash,\n instanceType = _this.__instanceType,\n role = 'participant',\n customBearer = undefined\n } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n let signal = arguments.length > 1 ? arguments[1] : undefined;\n return _this.__privates.auth.__client.then(client => client.apis.wt.join({\n roomId,\n pinHash,\n instanceType,\n role,\n platform: _this.browser === 'firefox' ? 'web-firefox' : 'web'\n }, {\n ...(signal ? {\n requestInterceptor: req => {\n req.signal = signal;\n return req;\n }\n } : {})\n }));\n },\n isSafariSupported: () => {\n return this.__privates.room.safariVp8;\n },\n isWebrtcSupported: () => {\n return this.__privates.room.isWebrtcSupported;\n },\n createStreamingSession: function () {\n let {\n constructId,\n roomId,\n pinHash,\n streamId,\n href,\n iceServers,\n accessToken\n } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n return _this.__privates.room.whenInitialized.then(lib => _streaming_session__WEBPACK_IMPORTED_MODULE_1__[\"default\"].call(_this, {\n roomId,\n pinHash,\n streamId,\n href,\n iceServers,\n accessToken\n }, lib.createSession(constructId, 'streaming'), _this)).then(newSession => {\n let existingSessionIndex = roomSessions.findIndex(session => session.constructId === newSession.constructId);\n if (existingSessionIndex > -1) {\n return _this.room.destroySession(newSession.constructId).then(() => {\n roomSessions.push(newSession);\n return newSession;\n });\n } else {\n roomSessions.push(newSession);\n return newSession;\n }\n });\n },\n createSession: _ref4 => {\n let {\n constructId,\n roomId,\n pinHash,\n role,\n options\n } = _ref4;\n return this.__privates.room.whenInitialized.then(lib => _room_session__WEBPACK_IMPORTED_MODULE_0__[\"default\"].call(this, {\n roomId,\n pinHash,\n role,\n options\n }, lib.createSession(constructId, 'reactooroom', options), this)).then(newSession => {\n let existingSessionIndex = roomSessions.findIndex(session => session.constructId === newSession.constructId);\n if (existingSessionIndex > -1) {\n return this.room.destroySession(newSession.constructId).then(() => {\n roomSessions.push(newSession);\n return newSession;\n });\n } else {\n roomSessions.push(newSession);\n return newSession;\n }\n });\n },\n getSessions: () => {\n return roomSessions;\n },\n getSessionByConstructId: constructId => {\n return roomSessions.find(session => session.constructId === constructId) || null;\n },\n getSessionBySessionId: sessionId => {\n return roomSessions.find(session => session.sessionId === sessionId) || null;\n },\n getSessionByRoomId: roomId => {\n return roomSessions.find(session => session.roomId === roomId) || null;\n },\n getSessionByUserId: userId => {\n return roomSessions.find(session => {\n var _decodeJanusDisplay;\n return ((_decodeJanusDisplay = Object(_modules_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(session.userId)) === null || _decodeJanusDisplay === void 0 ? void 0 : _decodeJanusDisplay.userId) === userId;\n }) || null;\n },\n getSessionByStreamId: streamId => {\n return roomSessions.find(session => session.streamId === streamId) || null;\n },\n destroySession: constructId => {\n let sessionIndex = roomSessions.findIndex(session => session.constructId === constructId);\n if (sessionIndex > -1) {\n return roomSessions[sessionIndex].kill().finally(() => {\n roomSessions.splice(sessionIndex, 1);\n return true;\n });\n }\n return Promise.resolve();\n },\n destroySessionBySessionId: sessionId => {\n let sessionIndex = roomSessions.findIndex(session => session.sessionId === sessionId);\n if (sessionIndex > -1) {\n return roomSessions[sessionIndex].kill().finally(() => {\n roomSessions.splice(sessionIndex, 1);\n return true;\n });\n }\n return Promise.resolve();\n },\n destroySessions: () => {\n roomSessions.forEach(session => session.destroy().catch(e => this.log(e)));\n roomSessions.length = 0;\n },\n queue: function () {\n let {\n roomId,\n operation,\n userId\n } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n //Enum: \"status\" \"join\" \"approve\" \"reject\" \"block\" \"unblock\"\n return _this.__privates.auth.__client.then(client => client.apis.wt.queue({}, {\n requestBody: {\n roomId,\n operation,\n userId\n }\n }));\n },\n getDefaultRegions: () => {\n return this.__privates.auth.__client.then(client => {\n var _client$spec, _client$spec$componen, _client$spec$componen2, _client$spec$componen3, _client$spec$componen4, _client$spec$componen5;\n return [...(((_client$spec = client.spec) === null || _client$spec === void 0 ? void 0 : (_client$spec$componen = _client$spec.components) === null || _client$spec$componen === void 0 ? void 0 : (_client$spec$componen2 = _client$spec$componen.schemas) === null || _client$spec$componen2 === void 0 ? void 0 : (_client$spec$componen3 = _client$spec$componen2.WtRoom) === null || _client$spec$componen3 === void 0 ? void 0 : (_client$spec$componen4 = _client$spec$componen3.properties) === null || _client$spec$componen4 === void 0 ? void 0 : (_client$spec$componen5 = _client$spec$componen4.defaultRegion) === null || _client$spec$componen5 === void 0 ? void 0 : _client$spec$componen5.enum) || [''])];\n });\n }\n };\n};\n/* harmony default export */ __webpack_exports__[\"default\"] = (room);\n\n//# sourceURL=webpack://WatchTogetherSDK/./src/models/room.js?");
|
|
8655
|
+
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _room_session__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./room-session */ \"./src/models/room-session.js\");\n/* harmony import */ var _streaming_session__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./streaming-session */ \"./src/models/streaming-session.js\");\n/* harmony import */ var _modules_wt_utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../modules/wt-utils */ \"./src/modules/wt-utils.js\");\n\n\n\n\n\nlet room = function () {\n var _this = this;\n let roomSessions = [];\n let setExitListeners = () => {\n window.addEventListener('pagehide', event => {\n if (!event.persisted) {\n this.room.destroySessions();\n }\n });\n window.addEventListener('beforeunload', () => {\n this.room.destroySessions();\n });\n };\n setExitListeners();\n return {\n //TODO:deprecated\n integration: function () {\n let data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n return _this.__privates.auth.__client.then(client => client.apis.system.integration({\n type: _this.__instanceType\n }, {\n requestBody: {\n ...data\n },\n requestInterceptor: req => {\n if (!req.headers) {\n req.headers = {};\n }\n req.headers['Authorization'] = 'Bearer ' + localStorage.getItem('rwt_idToken');\n return req;\n }\n }));\n },\n //TODO:deprecated\n getAnalytics: function () {\n let data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n return _this.__privates.auth.__client.then(client => client.apis.system.getAnalytics({\n instanceType: _this.__instanceType,\n ...data\n }));\n },\n sendChatMessage: _ref => {\n let {\n roomId,\n message,\n options,\n senderUserId\n } = _ref;\n return this.__privates.auth.__client.then(client => client.apis.wt.sendRoomMessage({}, {\n requestBody: {\n roomId,\n message,\n options,\n senderUserId\n }\n }));\n },\n createRoom: function () {\n let {\n sourceRoomId,\n title,\n description,\n isPublic,\n isRouter,\n isStudioLayout,\n wtChannelId,\n isHd,\n disableSync,\n reduceRoomControls,\n hasStudioChat,\n maxParticipants,\n customAttributes,\n chatRoomId,\n linkedRoomId,\n type,\n dotAttribute\n } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n let _da = dotAttribute ? Array.isArray(dotAttribute) ? dotAttribute.reduce((p, cv) => (p[cv.name] = cv.value) && p || p, {}) : {\n [dotAttribute.name]: dotAttribute.value\n } : {};\n return _this.__privates.auth.__client.then(client => client.apis.wt.createRoom({\n sourceRoomId\n }, {\n requestBody: {\n title,\n description,\n isRouter,\n isPublic,\n isStudioLayout,\n wtChannelId,\n isHd,\n disableSync,\n reduceRoomControls,\n chatRoomId,\n linkedRoomId,\n hasStudioChat,\n maxParticipants,\n type,\n customAttributes,\n ..._da,\n instanceType: _this.__instanceType\n }\n }));\n },\n updateRoom: function () {\n let {\n roomId,\n title,\n description,\n isPublic,\n isRouter,\n recordings,\n slug,\n password,\n maxParticipants,\n setInstanceType = false,\n wtChannelId,\n isHd,\n isStudioLayout,\n hasStudioChat,\n reduceRoomControls,\n chatRoomId,\n linkedRoomId,\n type,\n disableSync,\n defaultRegion,\n customAttributes,\n dotAttribute\n } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n let _da = dotAttribute ? Array.isArray(dotAttribute) ? dotAttribute.reduce((p, cv) => (p[cv.name] = cv.value) && p || p, {}) : {\n [dotAttribute.name]: dotAttribute.value\n } : {};\n return _this.__privates.auth.__client.then(client => client.apis.wt.updateRoom({\n id: roomId\n }, {\n requestBody: {\n title,\n description,\n slug,\n password,\n isPublic,\n isRouter,\n isHd,\n isStudioLayout,\n hasStudioChat,\n maxParticipants,\n reduceRoomControls,\n chatRoomId,\n linkedRoomId,\n type,\n disableSync,\n defaultRegion,\n customAttributes,\n wtChannelId,\n ..._da,\n ...(setInstanceType && {\n instanceType: setInstanceType === true ? _this.__instanceType : setInstanceType\n }),\n ...(recordings && {\n recordings\n })\n }\n }));\n },\n deleteRoom: roomId => {\n return this.__privates.auth.__client.then(client => client.apis.wt.deleteRoom({\n id: roomId\n }));\n },\n leaveRoom: roomId => {\n return this.__privates.auth.__client.then(client => client.apis.wt.leave({\n roomId\n }));\n },\n updateLayout: _ref2 => {\n let {\n roomId,\n operation,\n name,\n attributeName,\n value,\n target\n } = _ref2;\n //operation : clearLayouts, setLayout, setLayouts, unsetLayout, setName, setTarget, setStyle, setAttribute, unsetAttribute,'sendMessage'\n\n return this.__privates.auth.__client.then(client => client.apis.wt.updateLayout({}, {\n requestBody: {\n roomId,\n operation,\n name,\n attributeName,\n value,\n target\n }\n }));\n },\n getInviteUrl: (roomId, domain, url) => {\n return this.__privates.auth.__client.then(client => client.apis.wt.invite({}, {\n requestBody: {\n roomId,\n domain: domain || location.host,\n url: url || location.href\n }\n }));\n },\n getRoomChatList: function () {\n let {\n roomId,\n type = \"normal\",\n size = 50,\n startKey = null\n } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n let apiParams = {\n roomId,\n type,\n size,\n ...(startKey && {\n startKey\n })\n };\n return _this.__privates.auth.__client.then(client => client.apis.wt.getRoomChatList(apiParams));\n },\n getRoomsList: function () {\n let {\n type = 'participant',\n activeOnly = null,\n instanceType = _this.__instanceType,\n size = 20,\n startKey = null,\n includeWtEventModels = false,\n demo = false,\n viewType = 'list',\n wtChannelId = undefined\n } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n let apiParams = {\n type,\n instanceType,\n size,\n includeWtEventModels,\n demo,\n viewType,\n ...(wtChannelId && {\n wtChannelId\n }),\n ...(activeOnly && {\n activeOnly\n }),\n ...(startKey && {\n startKey\n })\n };\n return _this.__privates.auth.__client.then(client => client.apis.wt.getRoomList(apiParams));\n },\n setUser: _ref3 => {\n let {\n messageId,\n userId,\n roomId,\n flag,\n timestamp,\n option\n } = _ref3;\n //leave, kick, ban, unban, approve, report\n return this.__privates.auth.__client.then(client => client.apis.wt.setUser({\n messageId,\n userId,\n roomId,\n flag,\n timestamp,\n option\n }));\n },\n getRoomById: function (id) {\n let pinHash = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined;\n let showPublic = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : undefined;\n let demo = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;\n let signal = arguments.length > 4 ? arguments[4] : undefined;\n return _this.__privates.auth.__client.then(client => client.apis.wt.getRoom({\n id,\n pinHash,\n \"public\": showPublic,\n demo\n }, {\n ...(signal ? {\n requestInterceptor: req => {\n req.signal = signal;\n return req;\n }\n } : {})\n }));\n },\n getRoomBySlug: function (slug) {\n let password = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined;\n let showPublic = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : undefined;\n let demo = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;\n return _this.__privates.auth.__client.then(client => client.apis.wt.getRoom({\n slug,\n password,\n \"public\": showPublic,\n demo\n }));\n },\n roomRecorder: function () {\n let {\n roomId,\n operation = 'get',\n config,\n outputs,\n destinationIds,\n screenWidth,\n screenHeight\n } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n return _this.__privates.auth.__client.then(client => client.apis.wt.recordRoom({}, {\n requestBody: {\n roomId,\n operation,\n config,\n outputs,\n destinationIds,\n screenWidth,\n screenHeight\n }\n }));\n },\n __joinRoom: function () {\n let {\n roomId,\n pinHash,\n instanceType = _this.__instanceType,\n role = 'participant',\n customBearer = undefined\n } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n let signal = arguments.length > 1 ? arguments[1] : undefined;\n return _this.__privates.auth.__client.then(client => client.apis.wt.join({\n roomId,\n pinHash,\n instanceType,\n role,\n platform: _this.browser === 'firefox' ? 'web-firefox' : 'web'\n }, {\n ...(signal ? {\n requestInterceptor: req => {\n req.signal = signal;\n return req;\n }\n } : {})\n }));\n },\n isSafariSupported: () => {\n return this.__privates.room.safariVp8;\n },\n isWebrtcSupported: () => {\n return this.__privates.room.isWebrtcSupported;\n },\n createStreamingSession: function () {\n let {\n constructId,\n roomId,\n pinHash,\n streamId,\n href,\n iceServers,\n accessToken\n } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n return _this.__privates.room.whenInitialized.then(lib => _streaming_session__WEBPACK_IMPORTED_MODULE_1__[\"default\"].call(_this, {\n roomId,\n pinHash,\n streamId,\n href,\n iceServers,\n accessToken\n }, lib.createSession(constructId, 'streaming'), _this)).then(newSession => {\n let existingSessionIndex = roomSessions.findIndex(session => session.constructId === newSession.constructId);\n if (existingSessionIndex > -1) {\n return _this.room.destroySession(newSession.constructId).then(() => {\n roomSessions.push(newSession);\n return newSession;\n });\n } else {\n roomSessions.push(newSession);\n return newSession;\n }\n });\n },\n createSession: _ref4 => {\n let {\n constructId,\n roomId,\n pinHash,\n role,\n options\n } = _ref4;\n return this.__privates.room.whenInitialized.then(lib => _room_session__WEBPACK_IMPORTED_MODULE_0__[\"default\"].call(this, {\n roomId,\n pinHash,\n role,\n options\n }, lib.createSession(constructId, 'reactooroom', options), this)).then(newSession => {\n let existingSessionIndex = roomSessions.findIndex(session => session.constructId === newSession.constructId);\n if (existingSessionIndex > -1) {\n return this.room.destroySession(newSession.constructId).then(() => {\n roomSessions.push(newSession);\n return newSession;\n });\n } else {\n roomSessions.push(newSession);\n return newSession;\n }\n });\n },\n getSessions: () => {\n return roomSessions;\n },\n getSessionByConstructId: constructId => {\n return roomSessions.find(session => session.constructId === constructId) || null;\n },\n getSessionBySessionId: sessionId => {\n return roomSessions.find(session => session.sessionId === sessionId) || null;\n },\n getSessionByRoomId: roomId => {\n return roomSessions.find(session => session.roomId === roomId) || null;\n },\n getSessionByUserId: userId => {\n return roomSessions.find(session => {\n var _decodeJanusDisplay;\n return ((_decodeJanusDisplay = Object(_modules_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(session.userId)) === null || _decodeJanusDisplay === void 0 ? void 0 : _decodeJanusDisplay.userId) === userId;\n }) || null;\n },\n getSessionByStreamId: streamId => {\n return roomSessions.find(session => session.streamId === streamId) || null;\n },\n destroySession: constructId => {\n let sessionIndex = roomSessions.findIndex(session => session.constructId === constructId);\n if (sessionIndex > -1) {\n return roomSessions[sessionIndex].kill().finally(() => {\n roomSessions.splice(sessionIndex, 1);\n return true;\n });\n }\n return Promise.resolve();\n },\n destroySessionBySessionId: sessionId => {\n let sessionIndex = roomSessions.findIndex(session => session.sessionId === sessionId);\n if (sessionIndex > -1) {\n return roomSessions[sessionIndex].kill().finally(() => {\n roomSessions.splice(sessionIndex, 1);\n return true;\n });\n }\n return Promise.resolve();\n },\n destroySessions: () => {\n roomSessions.forEach(session => session.destroy().catch(e => this.log(e)));\n roomSessions.length = 0;\n },\n queue: function () {\n let {\n roomId,\n operation,\n userId\n } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n //Enum: \"status\" \"join\" \"approve\" \"reject\" \"block\" \"unblock\"\n return _this.__privates.auth.__client.then(client => client.apis.wt.queue({}, {\n requestBody: {\n roomId,\n operation,\n userId\n }\n }));\n },\n getDefaultRegions: () => {\n return this.__privates.auth.__client.then(client => {\n var _client$spec, _client$spec$componen, _client$spec$componen2, _client$spec$componen3, _client$spec$componen4, _client$spec$componen5;\n return [...(((_client$spec = client.spec) === null || _client$spec === void 0 ? void 0 : (_client$spec$componen = _client$spec.components) === null || _client$spec$componen === void 0 ? void 0 : (_client$spec$componen2 = _client$spec$componen.schemas) === null || _client$spec$componen2 === void 0 ? void 0 : (_client$spec$componen3 = _client$spec$componen2.WtRoom) === null || _client$spec$componen3 === void 0 ? void 0 : (_client$spec$componen4 = _client$spec$componen3.properties) === null || _client$spec$componen4 === void 0 ? void 0 : (_client$spec$componen5 = _client$spec$componen4.defaultRegion) === null || _client$spec$componen5 === void 0 ? void 0 : _client$spec$componen5.enum) || [''])];\n });\n }\n };\n};\n/* harmony default export */ __webpack_exports__[\"default\"] = (room);\n\n//# sourceURL=webpack://WatchTogetherSDK/./src/models/room.js?");
|
|
8656
8656
|
|
|
8657
8657
|
/***/ }),
|
|
8658
8658
|
|
|
@@ -8928,7 +8928,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var aws_
|
|
|
8928
8928
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
8929
8929
|
|
|
8930
8930
|
"use strict";
|
|
8931
|
-
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var webrtc_adapter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! webrtc-adapter */ \"./node_modules/webrtc-adapter/src/js/adapter_core.js\");\n/* harmony import */ var _wt_emitter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./wt-emitter */ \"./src/modules/wt-emitter.js\");\n/* harmony import */ var _wt_utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./wt-utils */ \"./src/modules/wt-utils.js\");\nfunction _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\nfunction _toPropertyKey(arg) { var key = _toPrimitive(arg, \"string\"); return typeof key === \"symbol\" ? key : String(key); }\nfunction _toPrimitive(input, hint) { if (typeof input !== \"object\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \"default\"); if (typeof res !== \"object\") return res; throw new TypeError(\"@@toPrimitive must return a primitive value.\"); } return (hint === \"string\" ? String : Number)(input); }\n// Watch together janus webrtc library\n\n\n\n\nclass Room {\n constructor(debug) {\n this.debug = debug;\n this.sessions = [];\n this.safariVp8 = false;\n this.browser = webrtc_adapter__WEBPACK_IMPORTED_MODULE_0__[\"default\"].browserDetails.browser;\n this.browserDetails = webrtc_adapter__WEBPACK_IMPORTED_MODULE_0__[\"default\"].browserDetails;\n this.webrtcSupported = Room.isWebrtcSupported();\n this.safariVp8TestPromise = Room.testSafariVp8();\n this.safariVp8 = null;\n this.safariVp8TestPromise.then(safariVp8 => {\n this.safariVp8 = safariVp8;\n });\n\n // Let's get it started\n this.whenInitialized = this.initialize();\n }\n initialize() {\n return this.safariVp8TestPromise.then(() => this);\n }\n createSession() {\n let constructId = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;\n let type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'reactooroom';\n let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n return new RoomSession(constructId, type, {\n debug: this.debug,\n ...options\n });\n }\n static testSafariVp8() {\n return new Promise(resolve => {\n if (webrtc_adapter__WEBPACK_IMPORTED_MODULE_0__[\"default\"].browserDetails.browser === 'safari' && webrtc_adapter__WEBPACK_IMPORTED_MODULE_0__[\"default\"].browserDetails.version >= 605) {\n if (RTCRtpSender && RTCRtpSender.getCapabilities && RTCRtpSender.getCapabilities(\"video\") && RTCRtpSender.getCapabilities(\"video\").codecs && RTCRtpSender.getCapabilities(\"video\").codecs.length) {\n var isVp8 = false;\n for (var i in RTCRtpSender.getCapabilities(\"video\").codecs) {\n var codec = RTCRtpSender.getCapabilities(\"video\").codecs[i];\n if (codec && codec.mimeType && codec.mimeType.toLowerCase() === \"video/vp8\") {\n isVp8 = true;\n break;\n }\n }\n resolve(isVp8);\n } else {\n // We do it in a very ugly way, as there's no alternative...\n // We create a PeerConnection to see if VP8 is in an offer\n var testpc = new RTCPeerConnection({}, {});\n testpc.createOffer({\n offerToReceiveVideo: true\n }).then(function (offer) {\n let result = offer.sdp.indexOf(\"VP8\") !== -1;\n testpc.close();\n testpc = null;\n resolve(result);\n });\n }\n } else resolve(false);\n });\n }\n static isWebrtcSupported() {\n return window.RTCPeerConnection !== undefined && window.RTCPeerConnection !== null && navigator.mediaDevices !== undefined && navigator.mediaDevices !== null && navigator.mediaDevices.getUserMedia !== undefined && navigator.mediaDevices.getUserMedia !== null;\n }\n}\nclass RoomSession {\n static noop() {}\n static randomString(len) {\n var charSet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n var randomString = '';\n for (var i = 0; i < len; i++) {\n var randomPoz = Math.floor(Math.random() * charSet.length);\n randomString += charSet.substring(randomPoz, randomPoz + 1);\n }\n return randomString;\n }\n constructor() {\n let constructId = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;\n let type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'reactooroom';\n let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n _defineProperty(this, \"_intercomSubscribe\", stream => {\n var _JSON$parse;\n if (stream.type === 'data') {\n return true;\n }\n const intercomGroups = ((_JSON$parse = JSON.parse(stream.description || \"[]\")) === null || _JSON$parse === void 0 ? void 0 : _JSON$parse.intercomGroups) || [];\n return intercomGroups.some(g => this._listenIntercomChannels.indexOf(g) > -1);\n });\n Object.assign(this, Object(_wt_emitter__WEBPACK_IMPORTED_MODULE_1__[\"default\"])());\n this.options = {\n ...options\n };\n this.defaultDataChannelLabel = 'JanusDataChannel';\n this.server = null;\n this.iceServers = null;\n this.token = null;\n this.roomId = null;\n this.streamId = null;\n this.pin = null;\n this.userId = null;\n this.sessiontype = type;\n this.initialBitrate = 0;\n this.simulcast = false;\n this.simulcastMode = 'controlled'; // controlled, manual, browserControlled\n this.simulcastDefaultManualSubstream = 0; // 0 = maximum quality\n\n // ordered from low to high\n this.simulcastBitrates = [{\n rid: 'l',\n active: true,\n maxBitrate: 180000,\n maxFramerate: 20,\n scaleResolutionDownBy: 3.3333333333333335,\n priority: \"low\"\n }, {\n rid: 'm',\n active: true,\n maxBitrate: 500000,\n maxFramerate: 25,\n scaleResolutionDownBy: 1.3333333333333335,\n priority: \"low\"\n }, {\n rid: 'h',\n active: true,\n maxBitrate: 2000000,\n maxFramerate: 30,\n priority: \"low\"\n }];\n this.recordingFilename = null;\n this.pluginName = RoomSession.sessionTypes[type];\n this.id = null;\n this.privateId = null;\n this.constructId = constructId || RoomSession.randomString(16);\n this.sessionId = null;\n this.handleId = null;\n this.ws = null;\n this.isRestarting = false;\n this.isConnecting = false;\n this.isDisconnecting = false;\n this.isConnected = false;\n this.isPublished = false;\n this.isReclaiming = false;\n this.isStreaming = false;\n this.isMuted = [];\n this.isVideoEnabled = false;\n this.isAudioEnabed = false;\n this._statsMaxLength = 31;\n this._upStatsLength = 30;\n this._downStatsLength = 5;\n this._statsTimeoutStopped = true;\n this._statsTimeoutId = null;\n this._statsInterval = 1000;\n this._aqInterval = 2500;\n this._aqTimeoutId = null;\n this._sendMessageTimeout = 5000;\n this._retries = 0;\n this._maxRetries = 5;\n this._keepAliveId = null;\n this._participants = [];\n this._talkIntercomChannels = ['participants'];\n this._listenIntercomChannels = ['participants'];\n this._roomType = 'watchparty';\n this._isDataChannelOpen = false;\n this._abortController = null;\n this.userRoleSubscriptionRules = {\n ...RoomSession.userRoleSubscriptionRules,\n ...(this.options.userRoleSubscriptionRules || {})\n };\n this._log = RoomSession.noop;\n if (this.options.debug) {\n this._enableDebug();\n }\n }\n _participantShouldSubscribe(userId) {\n const myUser = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(this.display);\n const remoteUser = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(userId);\n let localUserRole = (myUser === null || myUser === void 0 ? void 0 : myUser.role) || 'participant';\n let remoteUserRole = (remoteUser === null || remoteUser === void 0 ? void 0 : remoteUser.role) || 'participant';\n return this.userRoleSubscriptionRules[localUserRole][this._roomType || 'watchparty'].indexOf(remoteUserRole) > -1;\n }\n _getAddParticipantEventName(handleId) {\n var _decodeJanusDisplay;\n let handle = this._getHandle(handleId);\n if (!handle) {\n this.emit('error', {\n type: 'warning',\n id: 15,\n message: 'id non-existent',\n data: [handleId, 'getParticipantEventName']\n });\n return;\n }\n const participantRole = (_decodeJanusDisplay = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay === void 0 ? void 0 : _decodeJanusDisplay.role;\n switch (participantRole) {\n case 'participant':\n return 'addRemoteParticipant';\n case 'talkback':\n return 'addRemoteTalkback';\n case 'monitor':\n return 'addRemoteTalkback';\n case 'observer':\n case 'observerSolo1':\n case 'observerSolo2':\n case 'observerSolo3':\n return 'addRemoteObserver';\n case 'host':\n return 'addRemoteInstructor';\n case 'companionTV':\n return 'addRemoteCompanionTV';\n case 'companionPhone':\n return 'addRemoteCompanionPhone';\n default:\n return 'addRemoteParticipant';\n }\n }\n _getRemoveParticipantEventName(handleId) {\n var _decodeJanusDisplay2;\n let handle = this._getHandle(handleId);\n if (!handle) {\n this.emit('error', {\n type: 'warning',\n id: 15,\n message: 'id non-existent',\n data: [handleId, 'getParticipantEventName']\n });\n return;\n }\n const participantRole = (_decodeJanusDisplay2 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay2 === void 0 ? void 0 : _decodeJanusDisplay2.role;\n switch (participantRole) {\n case 'participant':\n return 'removeRemoteParticipant';\n case 'talkback':\n return 'removeRemoteTalkback';\n case 'monitor':\n return 'removeRemoteTalkback';\n case 'observer':\n case 'observerSolo1':\n case 'observerSolo2':\n case 'observerSolo3':\n return 'removeRemoteObserver';\n case 'host':\n return 'removeRemoteInstructor';\n case 'companionTV':\n return 'removeRemoteCompanionTV';\n case 'companionPhone':\n return 'removeRemoteCompanionPhone';\n default:\n return 'removeRemoteParticipant';\n }\n }\n sendMessage(handleId) {\n let message = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {\n body: 'Example Body'\n };\n let dontWait = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;\n let dontResolveOnAck = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;\n let retry = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0;\n return this._send({\n \"janus\": \"message\",\n \"handle_id\": handleId,\n ...message\n }, dontWait, dontResolveOnAck, retry).then(json => {\n if (json && json[\"janus\"] === \"success\") {\n let plugindata = json[\"plugindata\"] || {};\n let data = plugindata[\"data\"];\n return Promise.resolve(data);\n }\n return Promise.resolve();\n }).catch(json => {\n if (json && json[\"error\"]) {\n return Promise.reject({\n type: 'warning',\n id: 1,\n message: 'sendMessage failed',\n data: json[\"error\"]\n });\n } else {\n return Promise.reject({\n type: 'warning',\n id: 1,\n message: 'sendMessage failed',\n data: json\n });\n }\n });\n }\n _send() {\n let request = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n let ignoreResponse = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;\n let dontResolveOnAck = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;\n let retry = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;\n let transaction = RoomSession.randomString(12);\n let requestData = {\n ...request,\n transaction,\n token: this.token,\n ...(this.sessionId && {\n 'session_id': this.sessionId\n } || {})\n };\n this._log(requestData);\n const op = () => new Promise((resolve, reject) => {\n let messageTimeoutId = null;\n let abortResponse = () => {\n this._abortController.signal.removeEventListener('abort', abortResponse);\n clearTimeout(messageTimeoutId);\n this.ws.removeEventListener('message', parseResponse);\n reject({\n type: 'warning',\n id: 17,\n message: 'connection cancelled'\n });\n };\n let parseResponse = event => {\n let json = JSON.parse(event.data);\n let r_transaction = json['transaction'];\n if (r_transaction === transaction && (!dontResolveOnAck || json['janus'] !== 'ack')) {\n clearTimeout(messageTimeoutId);\n this._abortController.signal.removeEventListener('abort', abortResponse);\n this.ws.removeEventListener('message', parseResponse);\n if (json['janus'] === 'error') {\n var _json$error;\n if ((json === null || json === void 0 ? void 0 : (_json$error = json.error) === null || _json$error === void 0 ? void 0 : _json$error.code) == 403) {\n this.disconnect(true);\n }\n reject({\n type: 'error',\n id: 2,\n message: 'send failed',\n data: json,\n requestData\n });\n } else {\n resolve(json);\n }\n }\n };\n if (ignoreResponse) {\n if (this.ws && this.ws.readyState === 1) {\n this.ws.send(JSON.stringify(requestData));\n }\n resolve();\n } else {\n if (this.ws && this.ws.readyState === 1) {\n this.ws.addEventListener('message', parseResponse);\n messageTimeoutId = setTimeout(() => {\n this.ws.removeEventListener('message', parseResponse);\n this._abortController.signal.removeEventListener('abort', abortResponse);\n reject({\n type: 'warning',\n id: 3,\n message: 'send timeout',\n data: requestData\n });\n }, this._sendMessageTimeout);\n this._abortController.signal.addEventListener('abort', abortResponse);\n this.ws.send(JSON.stringify(requestData));\n } else {\n reject({\n type: 'warning',\n id: 29,\n message: 'No connection to WebSockets',\n data: requestData\n });\n }\n }\n });\n return op().catch(e => {\n if (e.id === 17) {\n return Promise.reject(e);\n } else if (e.id === 29 && retry > 0) {\n return Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"wait\"])(this._sendMessageTimeout).then(() => this._send(request, ignoreResponse, dontResolveOnAck, retry - 1));\n } else if (retry > 0) {\n return this._send(request, ignoreResponse, dontResolveOnAck, retry - 1);\n } else {\n return Promise.reject(e);\n }\n });\n }\n _connectionClosed() {\n if (!this.isConnected || this.isConnecting || this.isDisconnecting) {\n return;\n }\n if (this._retries < this._maxRetries) {\n setTimeout(() => {\n this._retries++;\n this._reconnect().catch(e => {\n this.emit('error', e);\n });\n }, 3000 * this._retries);\n } else {\n if (this.sessiontype === 'reactooroom') {\n this.disconnect(true);\n } else if (this.sessiontype === 'streaming') {\n this.stopStream();\n }\n this.emit('error', {\n type: 'error',\n id: 4,\n message: 'Lost connection to WebSockets',\n data: null\n });\n }\n }\n _wipeListeners() {\n if (this.ws) {\n this.ws.removeEventListener('close', this.__connectionClosedBoundFn);\n this.ws.removeEventListener('message', this.__handleWsEventsBoundFn);\n }\n }\n _startKeepAlive() {\n this._send({\n \"janus\": \"keepalive\"\n }).then(json => {\n if (json[\"janus\"] !== 'ack') {\n this.emit('error', {\n type: 'warning',\n id: 5,\n message: 'keepalive response suspicious',\n data: json[\"janus\"]\n });\n }\n }).catch(e => {\n this.emit('error', {\n type: 'warning',\n id: 6,\n message: 'keepalive dead',\n data: e\n });\n this._connectionClosed();\n });\n this._keepAliveId = setTimeout(() => {\n this._startKeepAlive();\n }, 10000);\n }\n _stopKeepAlive() {\n clearTimeout(this._keepAliveId);\n }\n _handleWsEvents(event) {\n let json = JSON.parse(event.data);\n var sender = json[\"sender\"];\n var type = json[\"janus\"];\n let handle = this._getHandle(sender);\n if (!handle) {\n return;\n }\n if (type === \"trickle\") {\n let candidate = json[\"candidate\"];\n let config = handle.webrtcStuff;\n if (config.pc && config.remoteSdp) {\n if (!candidate || candidate.completed === true) {\n config.pc.addIceCandidate(null);\n } else {\n config.pc.addIceCandidate(candidate);\n }\n } else {\n if (!config.candidates) {\n config.candidates = [];\n }\n config.candidates.push(candidate);\n }\n } else if (type === \"webrtcup\") {\n //none universal\n } else if (type === \"hangup\") {\n this._log('hangup on', handle.handleId, handle.handleId === this.handleId, json);\n this._removeParticipant(handle.handleId, null, false);\n } else if (type === \"detached\") {\n this._log('detached on', handle.handleId, handle.handleId === this.handleId, json);\n this._removeParticipant(handle.handleId, null, true);\n } else if (type === \"media\") {\n this._log('Media event:', handle.handleId, json[\"type\"], json[\"receiving\"], json[\"mid\"]);\n } else if (type === \"slowlink\") {\n this._log('Slowlink', handle.handleId, json[\"uplink\"], json[\"lost\"], json[\"mid\"]);\n } else if (type === \"event\") {\n //none universal\n } else if (type === 'timeout') {\n this._log('WebSockets Gateway timeout', json);\n this.ws.close(3504, \"Gateway timeout\");\n } else if (type === 'success' || type === 'error') {\n // we're capturing those elsewhere\n } else {\n this._log(`Unknown event: ${type} on session: ${this.sessionId}`);\n }\n\n // LOCAL\n\n if (sender === this.handleId) {\n if (type === \"event\") {\n var plugindata = json[\"plugindata\"] || {};\n var msg = plugindata[\"data\"] || {};\n var jsep = json[\"jsep\"];\n let result = msg[\"result\"] || null;\n let event = msg[\"videoroom\"] || null;\n let list = msg[\"publishers\"] || {};\n let leaving = msg[\"leaving\"];\n let kicked = msg[\"kicked\"];\n let substream = msg[\"substream\"];\n let temporal = msg[\"temporal\"];\n\n //let joining = msg[\"joining\"];\n let unpublished = msg[\"unpublished\"];\n let error = msg[\"error\"];\n if (event === \"joined\") {\n var _decodeJanusDisplay3, _decodeJanusDisplay4;\n this.id = msg[\"id\"];\n this.privateId = msg[\"private_id\"];\n this.isConnected = true;\n this._log('We have successfully joined Room');\n this.emit('joined', true, this.constructId);\n this.emit('addLocalParticipant', {\n tid: Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"generateUUID\"])(),\n id: handle.handleId,\n constructId: this.constructId,\n userId: (_decodeJanusDisplay3 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay3 === void 0 ? void 0 : _decodeJanusDisplay3.userId,\n role: (_decodeJanusDisplay4 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(this.display)) === null || _decodeJanusDisplay4 === void 0 ? void 0 : _decodeJanusDisplay4.role,\n track: null,\n stream: null,\n streamMap: {},\n source: null,\n adding: false,\n removing: false,\n hasAudioTrack: false,\n hasVideoTrack: false\n });\n for (let f in list) {\n let userId = list[f][\"display\"];\n let streams = list[f][\"streams\"] || [];\n let id = list[f][\"id\"];\n for (let i in streams) {\n streams[i][\"id\"] = id;\n streams[i][\"display\"] = userId;\n }\n this._log('Remote userId: ', userId);\n if (this._participantShouldSubscribe(userId)) {\n this._log('Creating user: ', userId);\n this._createParticipant(userId, id).then(handle => {\n this._updateParticipantsTrackData(handle.handleId, streams);\n const subscribe = streams.filter(s => !s.disabled && this._intercomSubscribe(s)).map(stream => ({\n feed: stream.id,\n mid: stream.mid\n }));\n handle.webrtcStuff.subscribeMap = structuredClone(subscribe);\n return this.sendMessage(handle.handleId, {\n body: {\n \"request\": \"join\",\n \"room\": this.roomId,\n \"ptype\": \"subscriber\",\n \"private_id\": this.privateId,\n streams: subscribe,\n //\"feed\": id,\n ...(this.webrtcVersion > 1000 ? {\n id: this.userId\n } : {}),\n pin: this.pin\n }\n });\n }).catch(err => {\n this.emit('error', err);\n });\n }\n }\n } else if (event === \"event\") {\n if (substream !== undefined && substream !== null) {\n this._log('Substream event:', substream, sender);\n }\n if (temporal !== undefined && temporal !== null) {\n this._log('Temporal event:', temporal);\n }\n if (msg[\"streams\"] !== undefined && msg[\"streams\"] !== null) {\n this._log('Got my own streams back', msg[\"streams\"]);\n }\n for (let f in list) {\n let userId = list[f][\"display\"];\n let streams = list[f][\"streams\"] || [];\n let id = list[f][\"id\"];\n for (let i in streams) {\n streams[i][\"id\"] = id;\n streams[i][\"display\"] = userId;\n }\n this._log('Remote userId: ', userId);\n if (this._participantShouldSubscribe(userId)) {\n let handle = this._getHandle(null, id);\n if (handle) {\n this._updateParticipantsTrackData(handle.handleId, streams);\n let subscribe = streams.filter(stream => !stream.disabled && this._intercomSubscribe(stream) && !this._isAlreadySubscribed(handle.handleId, stream.id, stream.mid)).map(s => ({\n feed: s.id,\n mid: s.mid\n }));\n let unsubscribe = streams.filter(stream => stream.disabled || !this._intercomSubscribe(stream)).map(s => ({\n feed: s.id,\n mid: s.mid\n }));\n this._updateSubscribeMap(handle.handleId, subscribe, unsubscribe);\n this._log('Already subscribed to user: ', userId, 'Update streams', subscribe, unsubscribe);\n if (subscribe.length || unsubscribe.length) {\n this.sendMessage(handle.handleId, {\n body: {\n \"request\": \"update\",\n ...(subscribe.length ? {\n subscribe\n } : {}),\n ...(unsubscribe.length ? {\n unsubscribe\n } : {})\n }\n });\n }\n } else {\n this._log('Creating user: ', userId, streams);\n this._createParticipant(userId, id).then(handle => {\n this._updateParticipantsTrackData(handle.handleId, streams);\n const subscribe = streams.filter(s => !s.disabled && this._intercomSubscribe(s)).map(stream => ({\n feed: stream.id,\n mid: stream.mid\n }));\n handle.webrtcStuff.subscribeMap = structuredClone(subscribe);\n return this.sendMessage(handle.handleId, {\n body: {\n \"request\": \"join\",\n \"room\": this.roomId,\n \"ptype\": \"subscriber\",\n \"private_id\": this.privateId,\n streams: subscribe,\n ...(this.webrtcVersion > 1000 ? {\n id: this.userId\n } : {}),\n pin: this.pin\n }\n });\n }).catch(err => {\n this.emit('error', err);\n });\n }\n }\n }\n if (leaving === 'ok') {\n this._log('leaving', this.handleId, 'this is us');\n this._removeParticipant(this.handleId);\n if (msg['reason'] === 'kicked') {\n this.emit('kicked');\n this.disconnect().catch(() => {});\n }\n } else if (leaving) {\n //TODO: in 1 PeerConnection case we only unsubscribe from streams\n this._log('leaving', leaving);\n this._removeParticipant(null, leaving, true);\n }\n if (unpublished === 'ok') {\n this._log('unpublished', this.handleId, 'this is us');\n this._removeParticipant(this.handleId, null, false); // we do just hangup\n } else if (unpublished) {\n //TODO: in 1 PeerConnection case we only unsubscribe from streams\n this._log('unpublished', unpublished);\n this._removeParticipant(null, unpublished, true); // we do hangup and detach\n }\n\n if (kicked === 'ok') {\n // this case shouldn't exist\n } else if (kicked) {\n this._log('kicked', kicked);\n this._removeParticipant(null, kicked, true); // we do hangup and detach\n }\n\n if (error) {\n this.emit('error', {\n type: 'error',\n id: 7,\n message: 'local participant error',\n data: [sender, msg]\n });\n }\n }\n\n // Streaming related\n else if (result && result[\"status\"]) {\n this.emit('streamingStatus', result[\"status\"]);\n if (result[\"status\"] === 'stopped') {\n this.stopStream();\n }\n if (result[\"status\"] === 'started') {\n this.emit('streaming', true);\n this.isStreaming = true;\n }\n }\n if (jsep !== undefined && jsep !== null) {\n if (this.sessiontype === 'reactooroom') {\n this._webrtcPeer(this.handleId, jsep).catch(err => {\n this.emit('error', err);\n });\n } else if (this.sessiontype === 'streaming') {\n this._publishRemote(this.handleId, jsep).catch(err => {\n this.emit('error', err);\n });\n }\n }\n } else if (type === \"webrtcup\") {\n if (this.simulcast) {\n return;\n }\n this._log('Configuring bitrate: ' + this.initialBitrate);\n if (this.initialBitrate > 0) {\n this.sendMessage(this.handleId, {\n \"body\": {\n \"request\": \"configure\",\n \"bitrate\": this.initialBitrate\n }\n }).catch(() => null);\n }\n }\n }\n\n //REMOTE\n else {\n let plugindata = json[\"plugindata\"] || {};\n let msg = plugindata[\"data\"] || {};\n let jsep = json[\"jsep\"];\n let event = msg[\"videoroom\"];\n let error = msg[\"error\"];\n let substream = msg[\"substream\"];\n let mid = msg[\"mid\"];\n let temporal = msg[\"temporal\"];\n if (substream !== undefined && substream !== null) {\n this._log('Substream: ', sender, mid, substream);\n this._setSelectedSubstream(sender, mid, substream);\n this._resetStats(sender, mid);\n this.requestKeyFrame(sender, mid);\n }\n if (temporal !== undefined && temporal !== null) {\n this._log('Temporal: ', temporal);\n }\n if (type === \"webrtcup\") {\n this.requestKeyFrame(handle.handleId);\n }\n if (event === \"updated\") {\n this._log('Remote has updated tracks', msg);\n if (msg[\"streams\"]) {\n this._updateTransceiverMap(handle.handleId, msg[\"streams\"]);\n }\n }\n if (event === \"attached\") {\n var _decodeJanusDisplay5, _decodeJanusDisplay6, _handle$webrtcStuff, _handle$webrtcStuff2, _handle$webrtcStuff3;\n this._log('Remote have successfully joined Room', msg);\n if (msg[\"streams\"]) {\n this._updateTransceiverMap(handle.handleId, msg[\"streams\"] || []);\n }\n this.emit(this._getAddParticipantEventName(handle.handleId), {\n tid: Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"generateUUID\"])(),\n id: handle.handleId,\n userId: (_decodeJanusDisplay5 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay5 === void 0 ? void 0 : _decodeJanusDisplay5.userId,\n role: (_decodeJanusDisplay6 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay6 === void 0 ? void 0 : _decodeJanusDisplay6.role,\n stream: null,\n streamMap: structuredClone((_handle$webrtcStuff = handle.webrtcStuff) === null || _handle$webrtcStuff === void 0 ? void 0 : _handle$webrtcStuff.streamMap),\n tracksMap: structuredClone((_handle$webrtcStuff2 = handle.webrtcStuff) === null || _handle$webrtcStuff2 === void 0 ? void 0 : _handle$webrtcStuff2.tracksMap),\n transceiverMap: structuredClone((_handle$webrtcStuff3 = handle.webrtcStuff) === null || _handle$webrtcStuff3 === void 0 ? void 0 : _handle$webrtcStuff3.transceiverMap),\n source: null,\n track: null,\n adding: false,\n removing: false,\n constructId: this.constructId,\n hasAudioTrack: false,\n hasVideoTrack: false\n });\n }\n if (error) {\n this.emit('error', {\n type: 'warning',\n id: 8,\n message: 'remote participant error',\n data: [sender, msg]\n });\n }\n if (jsep) {\n this._publishRemote(handle.handleId, jsep).catch(err => {\n this.emit('error', err);\n });\n }\n }\n }\n _handleDataEvents(handleId, type, data) {\n let handle = this._getHandle(handleId);\n if (type === 'state') {\n this._log(` - Data channel status - `, `UID: ${handleId}`, `STATUS: ${JSON.stringify(data)}`, `ME: ${handleId === this.handleId}`);\n if (handle) {\n let config = handle.webrtcStuff;\n config.dataChannelOpen = this.defaultDataChannelLabel === (data === null || data === void 0 ? void 0 : data.label) && (data === null || data === void 0 ? void 0 : data.state) === 'open';\n }\n if (handleId === this.handleId && this.defaultDataChannelLabel === (data === null || data === void 0 ? void 0 : data.label)) {\n this._isDataChannelOpen = (data === null || data === void 0 ? void 0 : data.state) === 'open';\n this.emit('dataChannel', (data === null || data === void 0 ? void 0 : data.state) === 'open');\n }\n }\n if (type === 'error') {\n this.emit('error', {\n type: 'warning',\n id: 9,\n message: 'data event warning',\n data: [handleId, data]\n });\n if (handle) {\n let config = handle.webrtcStuff;\n if (this.defaultDataChannelLabel === data.label) {\n config.dataChannelOpen = false;\n }\n }\n if (handleId === this.handleId && this.defaultDataChannelLabel === data.label) {\n this._isDataChannelOpen = false;\n this.emit('dataChannel', false);\n }\n }\n if (handleId === this.handleId && type === 'message') {\n let d = null;\n try {\n d = JSON.parse(data);\n } catch (e) {\n this.emit('error', {\n type: 'warning',\n id: 10,\n message: 'data message parse error',\n data: [handleId, e]\n });\n return;\n }\n this.emit('data', d);\n }\n }\n\n //removeHandle === true -> hangup, detach, removeHandle === false -> hangup\n _removeParticipant(handleId, rfid) {\n let removeHandle = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;\n let handle = this._getHandle(handleId, rfid);\n if (!handle) {\n return Promise.resolve();\n } else {\n handleId = handle.handleId;\n }\n return this._send({\n \"janus\": \"hangup\",\n \"handle_id\": handleId\n }, true).then(() => removeHandle ? this._send({\n \"janus\": \"detach\",\n \"handle_id\": handleId\n }, true) : Promise.resolve()).finally(() => {\n try {\n if (handle.webrtcStuff.stream) {\n if (!this.isRestarting) {\n var _handle$webrtcStuff$s;\n (_handle$webrtcStuff$s = handle.webrtcStuff.stream) === null || _handle$webrtcStuff$s === void 0 ? void 0 : _handle$webrtcStuff$s.getTracks().forEach(track => track.stop());\n } else {\n var _handle$webrtcStuff$s2;\n (_handle$webrtcStuff$s2 = handle.webrtcStuff.stream) === null || _handle$webrtcStuff$s2 === void 0 ? void 0 : _handle$webrtcStuff$s2.getTracks().forEach(track => track.onended = null);\n }\n }\n } catch (e) {\n // Do nothing\n }\n if (handle.webrtcStuff.stream) {\n handle.webrtcStuff.stream.onremovetrack = null;\n handle.webrtcStuff.stream = null;\n }\n if (handle.webrtcStuff.dataChannel) {\n Object.keys(handle.webrtcStuff.dataChannel).forEach(label => {\n handle.webrtcStuff.dataChannel[label].onmessage = null;\n handle.webrtcStuff.dataChannel[label].onopen = null;\n handle.webrtcStuff.dataChannel[label].onclose = null;\n handle.webrtcStuff.dataChannel[label].onerror = null;\n });\n }\n if (handle.webrtcStuff.pc) {\n handle.webrtcStuff.pc.onicecandidate = null;\n handle.webrtcStuff.pc.ontrack = null;\n handle.webrtcStuff.pc.ondatachannel = null;\n handle.webrtcStuff.pc.onconnectionstatechange = null;\n handle.webrtcStuff.pc.oniceconnectionstatechange = null;\n }\n try {\n handle.webrtcStuff.pc.close();\n } catch (e) {}\n handle.webrtcStuff = {\n stream: null,\n streamMap: {},\n tracksMap: [],\n transceiverMap: [],\n subscribeMap: [],\n mySdp: null,\n mediaConstraints: null,\n pc: null,\n dataChannelOpen: false,\n dataChannel: null,\n dtmfSender: null,\n trickle: true,\n iceDone: false,\n isIceRestarting: false,\n stats: {},\n selectedSubstream: {},\n initialSimulcastSubstreamBeenSet: {},\n forcedBrowserControlledMode: {}\n };\n if (handleId === this.handleId) {\n var _decodeJanusDisplay7, _decodeJanusDisplay8;\n this._isDataChannelOpen = false;\n this.isPublished = false;\n this.emit('published', {\n status: false,\n hasStream: false\n });\n this.emit('removeLocalParticipant', {\n id: handleId,\n userId: (_decodeJanusDisplay7 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay7 === void 0 ? void 0 : _decodeJanusDisplay7.userId,\n role: (_decodeJanusDisplay8 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay8 === void 0 ? void 0 : _decodeJanusDisplay8.role\n });\n } else {\n var _decodeJanusDisplay9, _decodeJanusDisplay10;\n this.emit(this._getRemoveParticipantEventName(handleId), {\n id: handleId,\n userId: (_decodeJanusDisplay9 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay9 === void 0 ? void 0 : _decodeJanusDisplay9.userId,\n role: (_decodeJanusDisplay10 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay10 === void 0 ? void 0 : _decodeJanusDisplay10.role\n });\n }\n if (removeHandle) {\n let handleIndex = this._participants.findIndex(p => p.handleId === handleId);\n this._participants.splice(handleIndex, 1);\n }\n return true;\n });\n }\n _createParticipant() {\n let userId = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;\n let rfid = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;\n return this._send({\n \"janus\": \"attach\",\n \"plugin\": this.pluginName\n }).then(json => {\n let handleId = json.data[\"id\"];\n let handle = {\n handleId,\n rfid,\n userId,\n webrtcStuff: {\n stream: null,\n streamMap: {},\n tracksMap: [],\n transceiverMap: [],\n subscribeMap: [],\n mySdp: null,\n mediaConstraints: null,\n pc: null,\n dataChannelOpen: false,\n dataChannel: null,\n dtmfSender: null,\n trickle: true,\n iceDone: false,\n isIceRestarting: false,\n stats: {},\n selectedSubstream: {},\n initialSimulcastSubstreamBeenSet: {},\n forcedBrowserControlledMode: {}\n }\n };\n this._participants.push(handle);\n return handle;\n });\n }\n _updateSubscribeMap(handleId, subscribe, unsubscribe) {\n let handle = this._getHandle(handleId);\n if (!handle) {\n this.emit('error', {\n type: 'warning',\n id: 15,\n message: 'id non-existent',\n data: [handleId, 'updateSubscribeMap']\n });\n return;\n }\n let currentSubscribeMap = handle.webrtcStuff.subscribeMap;\n subscribe.forEach(s => {\n if (!currentSubscribeMap.find(c => c.feed === s.feed && c.mid === s.mid)) {\n currentSubscribeMap.push(s);\n }\n });\n unsubscribe.forEach(s => {\n let index = currentSubscribeMap.findIndex(c => c.feed === s.feed && c.mid === s.mid);\n if (index > -1) {\n currentSubscribeMap.splice(index, 1);\n }\n });\n }\n _isAlreadySubscribed(handleId, feed, mid) {\n let handle = this._getHandle(handleId);\n if (!handle) {\n this.emit('error', {\n type: 'warning',\n id: 15,\n message: 'id non-existent',\n data: [handleId, 'isAlreadySubscribed']\n });\n return;\n }\n return handle.webrtcStuff.subscribeMap.findIndex(t => t.mid === mid && t.feed === feed) > -1;\n }\n _updateTransceiverMap(handleId, streams) {\n this._log('Updating current transceiver map', handleId, streams);\n let handle = this._getHandle(handleId);\n if (!handle) {\n this.emit('error', {\n type: 'warning',\n id: 15,\n message: 'id non-existent',\n data: [handleId, 'updateTransceiverMap']\n });\n return;\n }\n let config = handle.webrtcStuff;\n config.transceiverMap = structuredClone(streams);\n }\n _updateParticipantsTrackData(handleId, streams) {\n this._log('Updating participants track data', handleId, streams);\n let handle = this._getHandle(handleId);\n if (!handle) {\n this.emit('error', {\n type: 'warning',\n id: 15,\n message: 'id non-existent',\n data: [handleId, 'updateParticipantsTrackData']\n });\n return;\n }\n let config = handle.webrtcStuff;\n config.tracksMap = structuredClone(streams.map(s => {\n let source = null;\n let simulcastBitrates = null;\n try {\n const description = JSON.parse(s.description);\n source = description === null || description === void 0 ? void 0 : description.source;\n simulcastBitrates = description === null || description === void 0 ? void 0 : description.simulcastBitrates;\n } catch (e) {}\n return {\n active: !s.disabled,\n description: s.description,\n source: source,\n simulcastBitrates: simulcastBitrates,\n display: s.display,\n id: s.id,\n mid: s.mid,\n mindex: s.mindex,\n codec: s.codec,\n type: s.type\n };\n }));\n }\n _updateRemoteParticipantStreamMap(handleId) {\n this._log('Updating participants stream map', handleId);\n let handle = this._getHandle(handleId);\n if (!handle) {\n this.emit('error', {\n type: 'warning',\n id: 15,\n message: 'id non-existent',\n data: [handleId, 'updateRemoteParticipantStreamMap']\n });\n return;\n }\n let config = handle.webrtcStuff;\n config.streamMap = {};\n config.transceiverMap.forEach(tItem => {\n var _JSON$parse2, _config$pc$getTransce, _config$pc$getTransce2, _config$pc$getTransce3;\n if (tItem.type === 'data') {\n return;\n }\n if (tItem.active === false) {\n return;\n }\n const source = (_JSON$parse2 = JSON.parse(tItem.feed_description)) === null || _JSON$parse2 === void 0 ? void 0 : _JSON$parse2.source;\n if (!config.streamMap[source]) {\n config.streamMap[source] = [];\n }\n let trackId = (_config$pc$getTransce = config.pc.getTransceivers().find(t => t.mid === tItem.mid)) === null || _config$pc$getTransce === void 0 ? void 0 : (_config$pc$getTransce2 = _config$pc$getTransce.receiver) === null || _config$pc$getTransce2 === void 0 ? void 0 : (_config$pc$getTransce3 = _config$pc$getTransce2.track) === null || _config$pc$getTransce3 === void 0 ? void 0 : _config$pc$getTransce3.id;\n if (trackId) {\n config.streamMap[source].push(trackId);\n }\n });\n }\n _joinRoom(roomId, pin, userId, display) {\n return this.sendMessage(this.handleId, {\n body: {\n \"request\": \"join\",\n \"room\": roomId,\n \"pin\": pin,\n \"ptype\": \"publisher\",\n \"display\": display,\n ...(this.webrtcVersion > 1000 ? {\n id: userId\n } : {})\n }\n }, false, true);\n }\n _watchStream(id) {\n return this.sendMessage(this.handleId, {\n body: {\n \"request\": \"watch\",\n id: String(id)\n }\n }, false, true);\n }\n _leaveRoom() {\n let dontWait = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;\n return this.isConnected ? this.sendMessage(this.handleId, {\n body: {\n \"request\": \"leave\"\n }\n }, dontWait).finally(() => {\n this.isConnected = false;\n this.emit('joined', false);\n }) : Promise.resolve();\n }\n\n // internal reconnect\n\n _reconnect() {\n if (this.isReclaiming) {\n return Promise.resolve();\n }\n if (this.ws) {\n this._wipeListeners();\n if (this.ws.readyState === 1) {\n this.ws.close();\n }\n }\n this._stopKeepAlive();\n this.isReclaiming = true;\n this.emit('joining', true);\n return new Promise((resolve, reject) => {\n let abortReconnect = () => {\n this._abortController.signal.removeEventListener('abort', abortReconnect);\n this.ws.removeEventListener('close', this.__connectionClosedBoundFn);\n this.ws.removeEventListener('message', this.__handleWsEventsBoundFn);\n this.ws.onopen = null;\n this.ws.onerror = null;\n this.isReclaiming = false;\n this.emit('joining', false);\n reject({\n type: 'warning',\n id: 17,\n message: 'Connection cancelled',\n data: e\n });\n };\n this.ws = new WebSocket(this.server, 'janus-protocol');\n this.__connectionClosedBoundFn = this._connectionClosed.bind(this);\n this.__handleWsEventsBoundFn = this._handleWsEvents.bind(this);\n this.ws.addEventListener('close', this.__connectionClosedBoundFn);\n this.ws.addEventListener('message', this.__handleWsEventsBoundFn);\n this.ws.onopen = () => {\n this._abortController.signal.removeEventListener('abort', abortReconnect);\n this._send({\n \"janus\": \"claim\"\n }).then(json => {\n this.sessionId = json[\"session_id\"] ? json[\"session_id\"] : json.data[\"id\"];\n this._startKeepAlive();\n this.isReclaiming = false;\n this.emit('joining', false);\n this._retries = 0;\n resolve(json);\n }).catch(error => {\n this.isReclaiming = false;\n this.emit('joining', false);\n reject({\n type: 'error',\n id: 11,\n message: 'reconnection error',\n data: error\n });\n });\n };\n\n // this is called before 'close' event callback so it doesn't break reconnect loop\n this.ws.onerror = e => {\n this._abortController.signal.removeEventListener('abort', abortReconnect);\n this.isReclaiming = false;\n this.emit('joining', false);\n reject({\n type: 'warning',\n id: 12,\n message: 'ws reconnection error',\n data: e\n });\n };\n this._abortController.signal.addEventListener('abort', abortReconnect);\n });\n }\n connect(roomId, pin, server, iceServers, token, display, userId) {\n let webrtcVersion = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : 0;\n let initialBitrate = arguments.length > 8 && arguments[8] !== undefined ? arguments[8] : 0;\n let recordingFilename = arguments.length > 9 ? arguments[9] : undefined;\n let simulcast = arguments.length > 10 && arguments[10] !== undefined ? arguments[10] : false;\n let simulcastBitrates = arguments.length > 11 && arguments[11] !== undefined ? arguments[11] : this.simulcastBitrates;\n let simulcastMode = arguments.length > 12 && arguments[12] !== undefined ? arguments[12] : this.simulcastMode;\n let simulcastDefaultManualSubstream = arguments.length > 13 && arguments[13] !== undefined ? arguments[13] : this.simulcastDefaultManualSubstream;\n let simulcastInitialSubstream = arguments.length > 14 && arguments[14] !== undefined ? arguments[14] : null;\n if (this.isConnecting) {\n return Promise.reject({\n type: 'warning',\n id: 16,\n message: 'connection already in progress'\n });\n }\n if (this.ws) {\n this._wipeListeners();\n }\n this._stopKeepAlive();\n this._abortController = new AbortController();\n this.sessionId = null;\n this.server = server;\n this.iceServers = iceServers;\n this.token = token;\n this.roomId = roomId;\n this.pin = pin;\n this.display = display;\n this.userId = userId;\n this.webrtcVersion = webrtcVersion;\n this.initialBitrate = initialBitrate;\n this.recordingFilename = recordingFilename;\n this.isConnecting = true;\n this.simulcast = simulcast;\n this.simulcastMode = simulcastMode;\n this.simulcastDefaultManualSubstream = simulcastDefaultManualSubstream;\n if (simulcastBitrates !== null) {\n this.simulcastBitrates = structuredClone(simulcastBitrates).sort((a, b) => {\n if (a.maxBitrate === b.maxBitrate) {\n return a.maxFramerate - b.maxFramerate;\n }\n return a.maxBitrate - b.maxBitrate;\n });\n }\n this.emit('joining', true);\n return new Promise((resolve, reject) => {\n this.ws = new WebSocket(this.server, 'janus-protocol');\n this.__connectionClosedBoundFn = this._connectionClosed.bind(this);\n this.__handleWsEventsBoundFn = this._handleWsEvents.bind(this);\n let abortConnect = () => {\n this._abortController.signal.removeEventListener('abort', abortConnect);\n this.ws.removeEventListener('close', this.__connectionClosedBoundFn);\n this.ws.removeEventListener('message', this.__handleWsEventsBoundFn);\n this.ws.onopen = null;\n this.ws.onerror = null;\n this.isConnecting = false;\n this.emit('joining', false);\n reject({\n type: 'warning',\n id: 17,\n message: 'Connection cancelled'\n });\n };\n this.ws.addEventListener('close', this.__connectionClosedBoundFn);\n this.ws.addEventListener('message', this.__handleWsEventsBoundFn);\n this.ws.onopen = () => {\n this._abortController.signal.removeEventListener('abort', abortConnect);\n this._retries = 0;\n this._send({\n \"janus\": \"create\"\n }).then(json => {\n this.sessionId = json[\"session_id\"] ? json[\"session_id\"] : json.data[\"id\"];\n this._startKeepAlive();\n return 1;\n }).then(() => this._createParticipant(userId)).then(handle => {\n this.handleId = handle.handleId;\n return 1;\n }).then(() => this._joinRoom(roomId, pin, userId, display)).then(() => {\n this._enableStatsWatch();\n this._enableSubstreamAutoSelect();\n this.isConnecting = false;\n this.emit('joining', false);\n resolve(this);\n }).catch(error => {\n this.isConnecting = false;\n this.emit('joining', false);\n reject({\n type: (error === null || error === void 0 ? void 0 : error.type) === 'warning' ? 'warning' : 'error',\n id: 13,\n message: 'connection error',\n data: error\n });\n });\n };\n this.ws.onerror = e => {\n this._abortController.signal.removeEventListener('abort', abortConnect);\n this.isConnecting = false;\n this.emit('joining', false);\n reject({\n type: 'error',\n id: 14,\n message: 'ws connection error',\n data: e\n });\n };\n this._abortController.signal.addEventListener('abort', abortConnect);\n });\n }\n disconnect() {\n var _this$_abortControlle, _this$_abortControlle2;\n if (this.isDisconnecting) {\n return Promise.resolve();\n }\n (_this$_abortControlle = this._abortController) === null || _this$_abortControlle === void 0 ? void 0 : (_this$_abortControlle2 = _this$_abortControlle.abort) === null || _this$_abortControlle2 === void 0 ? void 0 : _this$_abortControlle2.call(_this$_abortControlle);\n this.isDisconnecting = true;\n this._stopKeepAlive();\n this._disableStatsWatch();\n this._disableSubstreamAutoSelect();\n let isConnected = this.isConnected;\n return Promise.all(this._participants.map(p => this._removeParticipant(p.handleId))).finally(() => {\n this._wipeListeners();\n if (this.ws && this.ws.readyState === 1) {\n this._send({\n \"janus\": \"destroy\"\n }, true);\n this.ws.close();\n }\n this.sessionId = null;\n this.isPublished = false;\n this.isConnected = false;\n this.isDisconnecting = false;\n this.emit('publishing', false);\n this.emit('published', {\n status: false,\n hasStream: false\n });\n this.emit('joining', false);\n this.emit('joined', false);\n this.emit('disconnect', isConnected);\n return Promise.resolve('Disconnected');\n });\n }\n startStream(streamId, server, iceServers, token, userId) {\n if (this.isConnecting) {\n return Promise.reject({\n type: 'warning',\n id: 16,\n message: 'connection error',\n data: 'Connection is in progress'\n });\n }\n if (this.ws) {\n this._wipeListeners();\n }\n this._stopKeepAlive();\n this._abortController = new AbortController();\n this.server = server;\n this.iceServers = iceServers;\n this.token = token;\n this.streamId = streamId;\n this.userId = userId;\n this.sessionId = null;\n this.isConnecting = true;\n this.emit('streamStarting', true);\n return new Promise((resolve, reject) => {\n this.ws = new WebSocket(this.server, 'janus-protocol');\n this.__connectionClosedBoundFn = this._connectionClosed.bind(this);\n this.__handleWsEventsBoundFn = this._handleWsEvents.bind(this);\n let abortConnect = () => {\n this._abortController.signal.removeEventListener('abort', abortConnect);\n this.ws.removeEventListener('close', this.__connectionClosedBoundFn);\n this.ws.removeEventListener('message', this.__handleWsEventsBoundFn);\n this.ws.onopen = null;\n this.ws.onerror = null;\n this.isConnecting = false;\n this.emit('streamStarting', false);\n reject({\n type: 'warning',\n id: 17,\n message: 'Connection cancelled'\n });\n };\n this.ws.addEventListener('close', this.__connectionClosedBoundFn);\n this.ws.addEventListener('message', this.__handleWsEventsBoundFn);\n this.ws.onopen = () => {\n this._abortController.signal.removeEventListener('abort', abortConnect);\n this._retries = 0;\n this._send({\n \"janus\": \"create\"\n }).then(json => {\n this.sessionId = json[\"session_id\"] ? json[\"session_id\"] : json.data[\"id\"];\n this._startKeepAlive();\n return 1;\n }).then(() => this._createParticipant(userId)).then(handle => {\n this.handleId = handle.handleId;\n return 1;\n }).then(() => this._watchStream(streamId)).then(() => {\n this.isConnecting = false;\n this.emit('streamStarting', false);\n resolve(this);\n }).catch(error => {\n this.isConnecting = false;\n this.emit('streamStarting', false);\n reject({\n type: 'error',\n id: 13,\n message: 'connection error',\n data: error\n });\n });\n };\n this.ws.onerror = e => {\n this._abortController.signal.removeEventListener('abort', abortConnect);\n this.isConnecting = false;\n this.emit('streamStarting', false);\n reject({\n type: 'error',\n id: 14,\n message: 'ws connection error',\n data: e\n });\n };\n this._abortController.signal.addEventListener('abort', abortConnect);\n });\n }\n stopStream() {\n var _this$_abortControlle3, _this$_abortControlle4;\n if (this.isDisconnecting) {\n return Promise.resolve();\n }\n (_this$_abortControlle3 = this._abortController) === null || _this$_abortControlle3 === void 0 ? void 0 : (_this$_abortControlle4 = _this$_abortControlle3.abort) === null || _this$_abortControlle4 === void 0 ? void 0 : _this$_abortControlle4.call(_this$_abortControlle3);\n this._stopKeepAlive();\n let isStreaming = this.isStreaming;\n this.isDisconnecting = true;\n return this._removeParticipant(this.handleId).finally(() => {\n this.sendMessage(this.handleId, {\n body: {\n \"request\": \"stop\"\n }\n }, true);\n this._wipeListeners();\n this._send({\n \"janus\": \"destroy\"\n }, true);\n if (this.ws && this.ws.readyState === 1) {\n this.ws.close();\n }\n this.sessionId = null;\n this.isDisconnecting = false;\n this.isStreaming = false;\n this.emit('streamStarting', false);\n this.emit('streaming', false);\n this.emit('disconnect', isStreaming);\n return Promise.resolve('Disconnected');\n });\n }\n destroy() {\n if (this.sessiontype === 'reactooroom') {\n return this.disconnect().then(() => {\n this.clear();\n return true;\n });\n } else if (this.sessiontype === 'streaming') {\n return this.stopStream().then(() => {\n this.clear();\n return true;\n });\n }\n }\n _enableDebug() {\n this._log = console.log.bind(console);\n }\n _getHandle(handleId) {\n let rfid = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;\n let userId = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;\n return this._participants.find(p => {\n var _decodeJanusDisplay11;\n return p.handleId === handleId || rfid && p.rfid === rfid || userId && ((_decodeJanusDisplay11 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(p.userId)) === null || _decodeJanusDisplay11 === void 0 ? void 0 : _decodeJanusDisplay11.userId) === userId;\n });\n }\n _disableStatsWatch() {\n if (this._statsTimeoutId) {\n clearInterval(this._statsTimeout);\n this._statsTimeoutStopped = true;\n this._statsTimeoutId = null;\n }\n }\n _enableStatsWatch() {\n if (this._statsTimeoutId) {\n clearTimeout(this._statsTimeoutId);\n this._statsTimeoutId = null;\n }\n this._statsTimeoutStopped = false;\n const loop = () => {\n let startTime = performance.now();\n let endTime = null;\n this._getStats('video').then(participantsStats => {\n endTime = performance.now();\n this._parseVideoStats(participantsStats);\n }).finally(() => {\n if (!this._statsTimeoutStopped) {\n this._statsTimeoutId = setTimeout(loop, this._statsInterval - Math.min(endTime - startTime, this._statsInterval));\n }\n });\n };\n loop();\n }\n\n // This method completely ignores temporal layers\n // We prefer higher fps and lower resolution so if the fps in not in the range of 0.7 of the max fps we go to the next lower resolution\n\n _enableSubstreamAutoSelect() {\n if (!this.simulcast) {\n return;\n }\n if (this._aqTimeoutId) {\n clearTimeout(this._aqTimeoutId);\n this._aqTimeoutId = null;\n }\n this._aqTimeoutId = setInterval(() => {\n this._participants.forEach(p => {\n if (p.handleId !== this.handleId) {\n var _p$webrtcStuff, _p$webrtcStuff$pc, _transceivers$filter;\n const transceivers = (_p$webrtcStuff = p.webrtcStuff) === null || _p$webrtcStuff === void 0 ? void 0 : (_p$webrtcStuff$pc = _p$webrtcStuff.pc) === null || _p$webrtcStuff$pc === void 0 ? void 0 : _p$webrtcStuff$pc.getTransceivers();\n const mids = (transceivers === null || transceivers === void 0 ? void 0 : (_transceivers$filter = transceivers.filter(t => t.receiver.track.kind === \"video\")) === null || _transceivers$filter === void 0 ? void 0 : _transceivers$filter.map(t => t.mid)) || [];\n mids.forEach(mid => {\n const {\n source,\n simulcastBitrates\n } = p.webrtcStuff.tracksMap.find(t => t.mid === mid) || {};\n if (!simulcastBitrates) {\n return;\n }\n const initialSubstreamBeenSet = !!p.webrtcStuff.initialSimulcastSubstreamBeenSet[mid];\n const defaultSelectedSubstream = typeof this.simulcastDefaultManualSubstream === 'object' ? this.simulcastDefaultManualSubstream[source] !== undefined ? this.simulcastDefaultManualSubstream[source] : this.simulcastDefaultManualSubstream['default'] : this.simulcastDefaultManualSubstream;\n const simulcastMode = typeof this.simulcastMode === 'object' ? this.simulcastMode[source] !== undefined ? this.simulcastMode[source] : this.simulcastMode['default'] : this.simulcastMode;\n if (simulcastMode === 'browserControlled' || p.webrtcStuff.forcedBrowserControlledMode[mid]) {\n // do nothing\n } else if (simulcastMode === 'manual' || !initialSubstreamBeenSet) {\n p.webrtcStuff.initialSimulcastSubstreamBeenSet[mid] = true;\n const currentSubstream = p.webrtcStuff.selectedSubstream[mid];\n if (defaultSelectedSubstream !== undefined && defaultSelectedSubstream !== null && defaultSelectedSubstream !== currentSubstream) {\n this._log('Attempting to force substream quality', defaultSelectedSubstream);\n this.selectSubStream(p.handleId, defaultSelectedSubstream, undefined, mid, false).catch(reason => this._log(`Changing substream for mid: ${mid} failed. Reason: ${reason}`));\n }\n } else if (simulcastMode === 'controlled') {\n var _p$webrtcStuff2, _p$webrtcStuff2$stats, _p$webrtcStuff2$stats2, _p$webrtcStuff3, _p$webrtcStuff3$stats, _p$webrtcStuff3$stats2;\n const currentSubstream = p.webrtcStuff.selectedSubstream[mid];\n const settingsForCurrentSubstream = simulcastBitrates === null || simulcastBitrates === void 0 ? void 0 : simulcastBitrates[simulcastBitrates.length - 1 - currentSubstream];\n let directionDecision = 0;\n if (((_p$webrtcStuff2 = p.webrtcStuff) === null || _p$webrtcStuff2 === void 0 ? void 0 : (_p$webrtcStuff2$stats = _p$webrtcStuff2.stats) === null || _p$webrtcStuff2$stats === void 0 ? void 0 : (_p$webrtcStuff2$stats2 = _p$webrtcStuff2$stats[mid]) === null || _p$webrtcStuff2$stats2 === void 0 ? void 0 : _p$webrtcStuff2$stats2.length) > this._upStatsLength) {\n const upMedianStats = this._calculateMedianStats(p.webrtcStuff.stats[mid].slice(this._upStatsLength * -1));\n if ((upMedianStats === null || upMedianStats === void 0 ? void 0 : upMedianStats.framesPerSecond) >= Math.floor(((settingsForCurrentSubstream === null || settingsForCurrentSubstream === void 0 ? void 0 : settingsForCurrentSubstream.maxFramerate) || 30) * 0.7) && (upMedianStats === null || upMedianStats === void 0 ? void 0 : upMedianStats.freezeDurationSinceLast) < this._upStatsLength * this._statsInterval * 0.33 / 1000 && (upMedianStats === null || upMedianStats === void 0 ? void 0 : upMedianStats.freezeCountSinceLast) < 3) {\n directionDecision = 1;\n }\n }\n if (((_p$webrtcStuff3 = p.webrtcStuff) === null || _p$webrtcStuff3 === void 0 ? void 0 : (_p$webrtcStuff3$stats = _p$webrtcStuff3.stats) === null || _p$webrtcStuff3$stats === void 0 ? void 0 : (_p$webrtcStuff3$stats2 = _p$webrtcStuff3$stats[mid]) === null || _p$webrtcStuff3$stats2 === void 0 ? void 0 : _p$webrtcStuff3$stats2.length) > this._downStatsLength) {\n const downMedianStats = this._calculateMedianStats(p.webrtcStuff.stats[mid].slice(this._downStatsLength * -1));\n if ((downMedianStats === null || downMedianStats === void 0 ? void 0 : downMedianStats.framesPerSecond) < Math.floor(((settingsForCurrentSubstream === null || settingsForCurrentSubstream === void 0 ? void 0 : settingsForCurrentSubstream.maxFramerate) || 30) * 0.7) || (downMedianStats === null || downMedianStats === void 0 ? void 0 : downMedianStats.freezeDurationSinceLast) > this._downStatsLength * this._statsInterval * 0.33 / 1000 || (downMedianStats === null || downMedianStats === void 0 ? void 0 : downMedianStats.freezeCountSinceLast) > 5 /* || downMedianStats?.jitter > maxJitter(settingsForCurrentSubstream.maxFramerate) */) {\n directionDecision = -1;\n }\n }\n if (directionDecision === -1) {\n if (currentSubstream < simulcastBitrates.length - 1) {\n this._log('Attempting to down the quality for mid: ', mid, ' quality:', currentSubstream + 1);\n this._resetStats(p.handleId, mid);\n this.selectSubStream(p.handleId, currentSubstream + 1, undefined, mid, false).catch(reason => this._log(`Changing substream for mid: ${mid} failed. Reason: ${reason}`));\n }\n } else if (directionDecision === 1) {\n if (currentSubstream > 0) {\n this._log('Attempting to up the quality for mid: ', mid, ' quality:', currentSubstream - 1);\n this._resetStats(p.handleId, mid);\n this.selectSubStream(p.handleId, currentSubstream - 1, undefined, mid, false).catch(reason => this._log(`Changing substream for mid: ${mid} failed. Reason: ${reason}`));\n }\n } else {\n this._log('No quality change for mid: ', mid);\n }\n }\n });\n }\n });\n }, this._aqInterval);\n }\n _disableSubstreamAutoSelect() {\n if (this._aqTimeoutId) {\n clearTimeout(this._aqTimeoutId);\n this._aqTimeoutId = null;\n }\n }\n _calculateMedianStats(stats) {\n let medianStats = {\n framesPerSecond: null,\n jitter: null,\n roundTripTime: null,\n freezeDurationSinceLast: null,\n freezeCountSinceLast: null\n };\n let keys = Object.keys(medianStats);\n keys.forEach(key => {\n if (key === 'freezeDurationSinceLast' || key === 'freezeCountSinceLast') {\n medianStats[key] = stats.reduce((acc, cur) => acc + cur[key], 0);\n }\n // median but ignore first value of stats array\n else {\n let values = stats.map(s => s[key]);\n medianStats[key] = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"median\"])(values);\n }\n });\n medianStats.statsLength = stats.length;\n return medianStats;\n }\n _parseVideoStats(participantsStats) {\n participantsStats.forEach(sourceStats => {\n sourceStats.forEach(participantStats => {\n var _participantStats$han;\n if (participantStats !== null && (participantStats === null || participantStats === void 0 ? void 0 : (_participantStats$han = participantStats.handle) === null || _participantStats$han === void 0 ? void 0 : _participantStats$han.handleId) !== this.handleId) {\n let handle = this._getHandle(participantStats.handle.handleId);\n if (handle) {\n var _decodeJanusDisplay12;\n if (!handle.webrtcStuff.stats[participantStats.mid]) {\n handle.webrtcStuff.stats[participantStats.mid] = [];\n }\n const stats = {\n framesPerSecond: null,\n framesDropped: null,\n totalFreezesDuration: null,\n freezeDurationSinceLast: null,\n freezeCount: null,\n jitter: null,\n packetsLost: null,\n nackCount: null,\n roundTripTime: null,\n width: null,\n height: null,\n networkType: null,\n powerEfficientDecoder: null\n };\n participantStats.stats.forEach(report => {\n if (report.type === 'inbound-rtp' && report.kind === 'video') {\n var _handle$webrtcStuff$s3, _handle$webrtcStuff$s4, _handle$webrtcStuff$s5, _handle$webrtcStuff$s6, _handle$webrtcStuff$s7, _handle$webrtcStuff$s8, _handle$webrtcStuff$s9, _handle$webrtcStuff$s10, _handle$webrtcStuff$s11, _handle$webrtcStuff$s12;\n stats.framesPerSecond = report.framesPerSecond || 0;\n stats.framesDropped = report.framesDropped || 0;\n stats.totalFreezesDuration = report.totalFreezesDuration || 0;\n stats.freezeDurationSinceLast = (report.totalFreezesDuration || 0) - (((_handle$webrtcStuff$s3 = handle.webrtcStuff.stats) === null || _handle$webrtcStuff$s3 === void 0 ? void 0 : (_handle$webrtcStuff$s4 = _handle$webrtcStuff$s3[participantStats.mid]) === null || _handle$webrtcStuff$s4 === void 0 ? void 0 : (_handle$webrtcStuff$s5 = _handle$webrtcStuff$s4[((_handle$webrtcStuff$s6 = handle.webrtcStuff.stats) === null || _handle$webrtcStuff$s6 === void 0 ? void 0 : (_handle$webrtcStuff$s7 = _handle$webrtcStuff$s6[participantStats.mid]) === null || _handle$webrtcStuff$s7 === void 0 ? void 0 : _handle$webrtcStuff$s7.length) - 1]) === null || _handle$webrtcStuff$s5 === void 0 ? void 0 : _handle$webrtcStuff$s5.totalFreezesDuration) || 0);\n stats.freezeCount = report.freezeCount || 0;\n stats.freezeCountSinceLast = (report.freezeCount || 0) - (((_handle$webrtcStuff$s8 = handle.webrtcStuff.stats) === null || _handle$webrtcStuff$s8 === void 0 ? void 0 : (_handle$webrtcStuff$s9 = _handle$webrtcStuff$s8[participantStats.mid]) === null || _handle$webrtcStuff$s9 === void 0 ? void 0 : (_handle$webrtcStuff$s10 = _handle$webrtcStuff$s9[((_handle$webrtcStuff$s11 = handle.webrtcStuff.stats) === null || _handle$webrtcStuff$s11 === void 0 ? void 0 : (_handle$webrtcStuff$s12 = _handle$webrtcStuff$s11[participantStats.mid]) === null || _handle$webrtcStuff$s12 === void 0 ? void 0 : _handle$webrtcStuff$s12.length) - 1]) === null || _handle$webrtcStuff$s10 === void 0 ? void 0 : _handle$webrtcStuff$s10.freezeCount) || 0);\n stats.jitter = report.jitter;\n stats.packetsLost = report.packetsLost;\n stats.nackCount = report.nackCount;\n stats.width = report.frameWidth;\n stats.height = report.frameHeight;\n stats.powerEfficientDecoder = report.powerEfficientDecoder;\n }\n if (report.type === 'candidate-pair') {\n stats.roundTripTime = report.currentRoundTripTime;\n }\n if (report.type === 'local-candidate') {\n stats.networkType = report.networkType;\n }\n stats.selectedSubstream = handle.webrtcStuff.selectedSubstream[participantStats.mid];\n if (handle.webrtcStuff.forcedBrowserControlledMode[participantStats.mid]) {\n stats.simulcastMode = 'browserControlled';\n } else {\n stats.simulcastMode = typeof this.simulcastMode === 'object' ? this.simulcastMode[participantStats.source] !== undefined ? this.simulcastMode[participantStats.source] : this.simulcastMode['default'] : this.simulcastMode;\n }\n });\n\n // pushing stats into handle stats array but keeping only 6 last stats\n handle.webrtcStuff.stats[participantStats.mid].push(stats);\n if (handle.webrtcStuff.stats[participantStats.mid].length > this._statsMaxLength) {\n handle.webrtcStuff.stats[participantStats.mid].shift();\n }\n this.emit('rtcStats', {\n handleId: participantStats.handle.handleId,\n stats,\n userId: (_decodeJanusDisplay12 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(participantStats.handle.userId)) === null || _decodeJanusDisplay12 === void 0 ? void 0 : _decodeJanusDisplay12.userId,\n source: participantStats.source,\n mid: participantStats.mid\n });\n }\n }\n });\n });\n }\n _getStats() {\n let type = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;\n return Promise.all(this._participants.map(participant => {\n let mediaTrack = [];\n if (type === 'video') {\n var _participant$webrtcSt, _participant$webrtcSt2;\n mediaTrack = (participant === null || participant === void 0 ? void 0 : (_participant$webrtcSt = participant.webrtcStuff) === null || _participant$webrtcSt === void 0 ? void 0 : (_participant$webrtcSt2 = _participant$webrtcSt.stream) === null || _participant$webrtcSt2 === void 0 ? void 0 : _participant$webrtcSt2.getVideoTracks()) || [];\n } else if (type === 'audio') {\n var _participant$webrtcSt3, _participant$webrtcSt4;\n mediaTrack = (participant === null || participant === void 0 ? void 0 : (_participant$webrtcSt3 = participant.webrtcStuff) === null || _participant$webrtcSt3 === void 0 ? void 0 : (_participant$webrtcSt4 = _participant$webrtcSt3.stream) === null || _participant$webrtcSt4 === void 0 ? void 0 : _participant$webrtcSt4.getAudioTracks()) || [];\n }\n if (type !== null) {\n var _participant$webrtcSt5, _participant$webrtcSt6;\n const transceivers = participant === null || participant === void 0 ? void 0 : (_participant$webrtcSt5 = participant.webrtcStuff) === null || _participant$webrtcSt5 === void 0 ? void 0 : (_participant$webrtcSt6 = _participant$webrtcSt5.pc) === null || _participant$webrtcSt6 === void 0 ? void 0 : _participant$webrtcSt6.getTransceivers();\n return Promise.all(mediaTrack.map(track => {\n var _transceivers$find;\n const source = Object.keys(participant.webrtcStuff.streamMap).find(s => participant.webrtcStuff.streamMap[s].find(t => t === track.id));\n const mid = (_transceivers$find = transceivers.find(t => {\n var _t$receiver, _t$receiver$track, _t$sender, _t$sender$track;\n return ((_t$receiver = t.receiver) === null || _t$receiver === void 0 ? void 0 : (_t$receiver$track = _t$receiver.track) === null || _t$receiver$track === void 0 ? void 0 : _t$receiver$track.id) === track.id || ((_t$sender = t.sender) === null || _t$sender === void 0 ? void 0 : (_t$sender$track = _t$sender.track) === null || _t$sender$track === void 0 ? void 0 : _t$sender$track.id) === track.id;\n })) === null || _transceivers$find === void 0 ? void 0 : _transceivers$find.mid;\n return participant.webrtcStuff.pc.getStats(track).then(r => ({\n stats: r,\n source,\n mid,\n handle: participant\n })).catch(e => Promise.reject({\n stats: null,\n error: e,\n handle: participant,\n source,\n mid\n }));\n }));\n } else {\n var _participant$webrtcSt7, _participant$webrtcSt8;\n return participant === null || participant === void 0 ? void 0 : (_participant$webrtcSt7 = participant.webrtcStuff) === null || _participant$webrtcSt7 === void 0 ? void 0 : (_participant$webrtcSt8 = _participant$webrtcSt7.pc) === null || _participant$webrtcSt8 === void 0 ? void 0 : _participant$webrtcSt8.getStats(null).then(r => ({\n handle: participant,\n stats: r\n })).catch(e => Promise.reject({\n handle: participant,\n error: e\n }));\n }\n }));\n }\n _resetStats(handleId, mid) {\n let handle = this._getHandle(handleId);\n if (handle) {\n let config = handle.webrtcStuff;\n if (!mid) {\n Object.keys(config.stats).forEach(mid => {\n config.stats[mid] = [config.stats[mid][config.stats[mid].length - 1]];\n });\n } else {\n // clearing stats for the new substream\n if (config.stats[mid]) {\n config.stats[mid] = [config.stats[mid][config.stats[mid].length - 1]];\n }\n }\n }\n }\n _sendTrickleCandidate(handleId, candidate) {\n return this._send({\n \"janus\": \"trickle\",\n \"candidate\": candidate,\n \"handle_id\": handleId\n }, false, false, 5);\n }\n _webrtc(handleId) {\n let enableOntrack = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;\n let handle = this._getHandle(handleId);\n if (!handle) {\n this.emit('error', {\n type: 'error',\n id: 15,\n message: 'id non-existent',\n data: [handleId, 'create rtc connection']\n });\n return;\n }\n let config = handle.webrtcStuff;\n if (!config.pc) {\n let pc_config = {\n \"iceServers\": this.iceServers,\n \"iceTransportPolicy\": 'all',\n \"bundlePolicy\": undefined\n };\n pc_config[\"sdpSemantics\"] = \"unified-plan\";\n let pc_constraints = {};\n if (webrtc_adapter__WEBPACK_IMPORTED_MODULE_0__[\"default\"].browserDetails.browser === \"edge\") {\n // This is Edge, enable BUNDLE explicitly\n pc_config.bundlePolicy = \"max-bundle\";\n }\n\n // pc_config.bundlePolicy = 'balanced';\n // pc_config.iceTransportPolicy = 'relay';\n // pc_config.rtcpMuxPolicy = \"negotiate\";\n\n this._log('new RTCPeerConnection', pc_config, pc_constraints);\n config.pc = new RTCPeerConnection(pc_config, pc_constraints);\n config.pc.onnegotiationneeded = () => {\n this._log('onnegotiationneeded');\n };\n config.pc.onconnectionstatechange = () => {\n if (config.pc.connectionState === 'failed') {\n this._log('connectionState failed');\n this._iceRestart(handleId);\n }\n this.emit('connectionState', [handleId, handleId === this.handleId, config.pc.connectionState]);\n if (handleId !== this.handleId && config.pc.connectionState === 'connected') {\n var _decodeJanusDisplay13, _decodeJanusDisplay14;\n this.emit(this._getAddParticipantEventName(handle.handleId), {\n tid: Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"generateUUID\"])(),\n id: handle.handleId,\n userId: (_decodeJanusDisplay13 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay13 === void 0 ? void 0 : _decodeJanusDisplay13.userId,\n role: (_decodeJanusDisplay14 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay14 === void 0 ? void 0 : _decodeJanusDisplay14.role,\n stream: config.stream,\n streamMap: structuredClone(config.streamMap),\n tracksMap: structuredClone(config.tracksMap),\n transceiverMap: structuredClone(config.transceiverMap),\n track: null,\n source: null,\n constructId: this.constructId,\n adding: false,\n removing: false,\n hasAudioTrack: !!(config.stream && config.stream.getAudioTracks().length),\n hasVideoTrack: !!(config.stream && config.stream.getVideoTracks().length)\n });\n }\n };\n config.pc.oniceconnectionstatechange = () => {\n if (config.pc.iceConnectionState === 'failed') {\n this._log('iceConnectionState failed');\n this._iceRestart(handleId);\n }\n this.emit('iceState', [handleId, handleId === this.handleId, config.pc.iceConnectionState]);\n if (handleId !== this.handleId && (config.pc.iceConnectionState === 'completed' || config.pc.iceConnectionState === 'connected')) {\n var _decodeJanusDisplay15, _decodeJanusDisplay16;\n this.emit(this._getAddParticipantEventName(handle.handleId), {\n tid: Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"generateUUID\"])(),\n id: handle.handleId,\n userId: (_decodeJanusDisplay15 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay15 === void 0 ? void 0 : _decodeJanusDisplay15.userId,\n role: (_decodeJanusDisplay16 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay16 === void 0 ? void 0 : _decodeJanusDisplay16.role,\n stream: config.stream,\n streamMap: structuredClone(config.streamMap),\n tracksMap: structuredClone(config.tracksMap),\n transceiverMap: structuredClone(config.transceiverMap),\n track: null,\n source: null,\n constructId: this.constructId,\n adding: false,\n hasAudioTrack: !!(config.stream && config.stream.getAudioTracks().length),\n hasVideoTrack: !!(config.stream && config.stream.getVideoTracks().length)\n });\n }\n };\n config.pc.onicecandidate = event => {\n if (event.candidate == null || webrtc_adapter__WEBPACK_IMPORTED_MODULE_0__[\"default\"].browserDetails.browser === 'edge' && event.candidate.candidate.indexOf('endOfCandidates') > 0) {\n config.iceDone = true;\n this._sendTrickleCandidate(handleId, {\n \"completed\": true\n }).catch(e => {\n this.emit('error', e);\n });\n } else {\n // JSON.stringify doesn't work on some WebRTC objects anymore\n // See https://code.google.com/p/chromium/issues/detail?id=467366\n var candidate = {\n \"candidate\": event.candidate.candidate,\n \"sdpMid\": event.candidate.sdpMid,\n \"sdpMLineIndex\": event.candidate.sdpMLineIndex\n };\n this._sendTrickleCandidate(handleId, candidate).catch(e => {\n this.emit('error', e);\n });\n }\n };\n if (enableOntrack) {\n config.pc.ontrack = event => {\n var _event$streams, _event$streams$;\n if (!event.streams) return;\n if (!config.stream) {\n config.stream = new MediaStream();\n }\n if (!((_event$streams = event.streams) !== null && _event$streams !== void 0 && (_event$streams$ = _event$streams[0]) !== null && _event$streams$ !== void 0 && _event$streams$.onremovetrack)) {\n event.streams[0].onremovetrack = ev => {\n var _config$stream, _config$pc, _config$pc$getTransce4, _decodeJanusDisplay17, _decodeJanusDisplay18;\n this._log('Remote track removed', ev);\n (_config$stream = config.stream) === null || _config$stream === void 0 ? void 0 : _config$stream.removeTrack(ev.track);\n\n // check if handle still exists\n if (!this._getHandle(handle.handleId)) {\n return;\n }\n this._updateRemoteParticipantStreamMap(handle.handleId);\n let transceiver = (_config$pc = config.pc) === null || _config$pc === void 0 ? void 0 : (_config$pc$getTransce4 = _config$pc.getTransceivers()) === null || _config$pc$getTransce4 === void 0 ? void 0 : _config$pc$getTransce4.find(t => t.receiver.track === ev.track);\n let mid = (transceiver === null || transceiver === void 0 ? void 0 : transceiver.mid) || ev.track.id;\n let source = Object.keys(config.streamMap).find(key => config.streamMap[key].includes(ev.track.id));\n this.emit(this._getAddParticipantEventName(handle.handleId), {\n tid: Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"generateUUID\"])(),\n id: handle.handleId,\n mid,\n constructId: this.constructId,\n userId: (_decodeJanusDisplay17 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay17 === void 0 ? void 0 : _decodeJanusDisplay17.userId,\n role: (_decodeJanusDisplay18 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay18 === void 0 ? void 0 : _decodeJanusDisplay18.role,\n stream: config.stream,\n streamMap: structuredClone(config.streamMap),\n tracksMap: structuredClone(config.tracksMap),\n transceiverMap: structuredClone(config.transceiverMap),\n source,\n track: ev.track,\n adding: false,\n removing: true,\n hasAudioTrack: !!(config.stream && config.stream.getAudioTracks().length),\n hasVideoTrack: !!(config.stream && config.stream.getVideoTracks().length)\n });\n };\n }\n if (event.track) {\n var _config$stream2, _decodeJanusDisplay19, _decodeJanusDisplay20;\n (_config$stream2 = config.stream) === null || _config$stream2 === void 0 ? void 0 : _config$stream2.addTrack(event.track);\n this._updateRemoteParticipantStreamMap(handle.handleId);\n let mid = event.transceiver ? event.transceiver.mid : event.track.id;\n let source = Object.keys(config.streamMap).find(key => config.streamMap[key].includes(event.track.id));\n if (event.track.kind === 'video') {\n this.requestKeyFrame(handle.handleId, mid);\n }\n this.emit(this._getAddParticipantEventName(handle.handleId), {\n tid: Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"generateUUID\"])(),\n mid,\n id: handle.handleId,\n userId: (_decodeJanusDisplay19 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay19 === void 0 ? void 0 : _decodeJanusDisplay19.userId,\n role: (_decodeJanusDisplay20 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay20 === void 0 ? void 0 : _decodeJanusDisplay20.role,\n stream: config.stream,\n streamMap: structuredClone(config.streamMap),\n tracksMap: structuredClone(config.tracksMap),\n transceiverMap: structuredClone(config.transceiverMap),\n source,\n track: event.track,\n constructId: this.constructId,\n adding: true,\n removing: false,\n hasAudioTrack: !!(config.stream && config.stream.getAudioTracks().length),\n hasVideoTrack: !!(config.stream && config.stream.getVideoTracks().length)\n });\n if (event.track.onended) return;\n event.track.onended = ev => {\n var _config$stream3, _config$pc2, _config$pc2$getTransc, _decodeJanusDisplay21, _decodeJanusDisplay22;\n this._log('Remote track ended');\n (_config$stream3 = config.stream) === null || _config$stream3 === void 0 ? void 0 : _config$stream3.removeTrack(ev.target);\n // check if handle still exists\n if (!this._getHandle(handle.handleId)) {\n return;\n }\n this._updateRemoteParticipantStreamMap(handle.handleId);\n let transceiver = (_config$pc2 = config.pc) === null || _config$pc2 === void 0 ? void 0 : (_config$pc2$getTransc = _config$pc2.getTransceivers()) === null || _config$pc2$getTransc === void 0 ? void 0 : _config$pc2$getTransc.find(t => t.receiver.track === ev.target);\n let mid = (transceiver === null || transceiver === void 0 ? void 0 : transceiver.mid) || ev.target.id;\n let source = Object.keys(config.streamMap).find(key => config.streamMap[key].includes(ev.target.id));\n this.emit(this._getAddParticipantEventName(handle.handleId), {\n tid: Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"generateUUID\"])(),\n id: handle.handleId,\n mid,\n constructId: this.constructId,\n userId: (_decodeJanusDisplay21 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay21 === void 0 ? void 0 : _decodeJanusDisplay21.userId,\n role: (_decodeJanusDisplay22 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay22 === void 0 ? void 0 : _decodeJanusDisplay22.role,\n stream: config.stream,\n streamMap: structuredClone(config.streamMap),\n tracksMap: structuredClone(config.tracksMap),\n transceiverMap: structuredClone(config.transceiverMap),\n source,\n track: ev.target,\n adding: false,\n removing: true,\n hasAudioTrack: !!(config.stream && config.stream.getAudioTracks().length),\n hasVideoTrack: !!(config.stream && config.stream.getVideoTracks().length)\n });\n };\n event.track.onmute = ev => {\n var _decodeJanusDisplay23, _decodeJanusDisplay24;\n this._log('Remote track muted');\n let transceiver = config.pc.getTransceivers().find(t => t.receiver.track === ev.target);\n let mid = transceiver.mid || ev.target.id;\n let source = Object.keys(config.streamMap).find(key => config.streamMap[key].includes(ev.target.id));\n this.emit('remoteTrackMuted', {\n id: handle.handleId,\n mid,\n constructId: this.constructId,\n userId: (_decodeJanusDisplay23 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay23 === void 0 ? void 0 : _decodeJanusDisplay23.userId,\n role: (_decodeJanusDisplay24 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay24 === void 0 ? void 0 : _decodeJanusDisplay24.role,\n stream: config.stream,\n streamMap: structuredClone(config.streamMap),\n source,\n kind: ev.target.kind,\n track: ev.target,\n muted: true\n });\n\n // questionable hotfix\n // when a track is muted, we try to switch to lower quality substream\n\n if (!this.simulcast) {\n return;\n }\n const simulcastMode = typeof this.simulcastMode === 'object' ? this.simulcastMode[source] !== undefined ? this.simulcastMode[source] : this.simulcastMode['default'] : this.simulcastMode;\n const {\n simulcastBitrates\n } = handle.webrtcStuff.tracksMap.find(t => t.mid === mid) || {};\n const currentSubstream = handle.webrtcStuff.selectedSubstream[mid];\n if (!(simulcastMode === 'browserControlled' || handle.webrtcStuff.forcedBrowserControlledMode[mid]) && ev.target.kind === 'video' && currentSubstream < simulcastBitrates.length - 1) {\n this.selectSubStream(handle.handleId, currentSubstream + 1, undefined, mid, false).catch(reason => this._log(`Changing substream for mid: ${mid} failed. Reason: ${reason}`));\n }\n };\n event.track.onunmute = ev => {\n var _decodeJanusDisplay25, _decodeJanusDisplay26;\n this._log('Remote track unmuted');\n let transceiver = config.pc.getTransceivers().find(t => t.receiver.track === ev.target);\n let mid = transceiver.mid || ev.target.id;\n let source = Object.keys(config.streamMap).find(key => config.streamMap[key].includes(ev.target.id));\n this.emit('remoteTrackMuted', {\n id: handle.handleId,\n mid,\n constructId: this.constructId,\n userId: (_decodeJanusDisplay25 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay25 === void 0 ? void 0 : _decodeJanusDisplay25.userId,\n role: (_decodeJanusDisplay26 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay26 === void 0 ? void 0 : _decodeJanusDisplay26.role,\n stream: config.stream,\n streamMap: structuredClone(config.streamMap),\n source,\n kind: ev.target.kind,\n track: ev.target,\n muted: false\n });\n };\n }\n };\n }\n }\n if (!config.dataChannel || !config.dataChannelOpen) {\n config.dataChannel = {};\n var onDataChannelMessage = event => {\n this._handleDataEvents(handleId, 'message', event.data);\n };\n var onDataChannelStateChange = event => {\n let label = event.target.label;\n let protocol = event.target.protocol;\n let state = config.dataChannel[label] ? config.dataChannel[label].readyState : \"null\";\n this._handleDataEvents(handleId, 'state', {\n state,\n label\n });\n };\n var onDataChannelError = error => {\n var _error$channel;\n this._handleDataEvents(handleId, 'error', {\n label: error === null || error === void 0 ? void 0 : (_error$channel = error.channel) === null || _error$channel === void 0 ? void 0 : _error$channel.label,\n error\n });\n };\n const createDataChannel = (label, protocol, incoming) => {\n let options = {\n ordered: true\n };\n if (!incoming) {\n if (protocol) {\n options = {\n ...options,\n protocol\n };\n }\n config.dataChannel[label] = config.pc.createDataChannel(label, options);\n } else {\n config.dataChannel[label] = incoming;\n }\n config.dataChannel[label].onmessage = onDataChannelMessage;\n config.dataChannel[label].onopen = onDataChannelStateChange;\n config.dataChannel[label].onclose = onDataChannelStateChange;\n config.dataChannel[label].onerror = onDataChannelError;\n };\n createDataChannel(this.defaultDataChannelLabel, null, null);\n config.pc.ondatachannel = function (event) {\n createDataChannel(event.channel.label, event.channel.protocol, event.channel);\n };\n }\n }\n _webrtcPeer(handleId, jsep) {\n let handle = this._getHandle(handleId);\n if (!handle) {\n return Promise.reject({\n type: 'warning',\n id: 15,\n message: 'id non-existent',\n data: [handleId, 'rtc peer']\n });\n }\n var config = handle.webrtcStuff;\n if (jsep !== undefined && jsep !== null) {\n if (config.pc === null) {\n this._log(\"No PeerConnection: if this is an answer, use createAnswer and not _webrtcPeer\");\n return Promise.resolve(null);\n }\n return config.pc.setRemoteDescription(jsep).then(() => {\n config.remoteSdp = jsep.sdp;\n // Any trickle candidate we cached?\n if (config.candidates && config.candidates.length > 0) {\n for (var i = 0; i < config.candidates.length; i++) {\n var candidate = config.candidates[i];\n if (!candidate || candidate.completed === true) {\n config.pc.addIceCandidate(null);\n } else {\n config.pc.addIceCandidate(candidate);\n }\n }\n config.candidates = [];\n }\n // Done\n return true;\n }).catch(e => {\n return Promise.reject({\n type: 'warning',\n id: 32,\n message: 'rtc peer',\n data: [handleId, e]\n });\n });\n } else {\n return Promise.reject({\n type: 'warning',\n id: 22,\n message: 'rtc peer',\n data: [handleId, 'invalid jsep']\n });\n }\n }\n _iceRestart(handleId) {\n let handle = this._getHandle(handleId);\n if (!handle) {\n return;\n }\n var config = handle.webrtcStuff;\n\n // Already restarting;\n if (config.isIceRestarting) {\n return;\n }\n config.isIceRestarting = true;\n if (this.handleId === handleId) {\n this._log('Performing local ICE restart');\n let hasAudio = !!(config.stream && config.stream.getAudioTracks().length > 0);\n let hasVideo = !!(config.stream && config.stream.getVideoTracks().length > 0);\n this._createAO('offer', handleId, true).then(jsep => {\n if (!jsep) {\n return null;\n }\n return this.sendMessage(handleId, {\n body: {\n \"request\": \"configure\",\n \"keyframe\": true,\n \"audio\": hasAudio,\n \"video\": hasVideo,\n \"data\": true,\n ...(this.recordingFilename ? {\n filename: this.recordingFilename\n } : {})\n },\n jsep\n }, false, false, 5);\n }).then(r => {\n config.isIceRestarting = false;\n this._log('ICE restart success');\n }).catch(e => {\n config.isIceRestarting = false;\n this.emit('error', {\n type: 'warning',\n id: 28,\n message: 'iceRestart failed',\n data: e\n });\n });\n } else {\n this._log('Performing remote ICE restart', handleId);\n return this.sendMessage(handleId, {\n body: {\n \"request\": \"configure\",\n \"restart\": true\n }\n }, false, false, 5).then(() => {}).then(() => {\n config.isIceRestarting = false;\n this._log('ICE restart success');\n }).catch(() => {\n config.isIceRestarting = false;\n });\n }\n }\n _setupTransceivers(handleId, _ref) {\n let [audioSend, audioRecv, videoSend, videoRecv, audioTransceiver = null, videoTransceiver = null] = _ref;\n //TODO: this should be refactored to use handle's trackMap so we dont have to pass any parameters\n\n let handle = this._getHandle(handleId);\n if (!handle) {\n return null;\n }\n let config = handle.webrtcStuff;\n const setTransceiver = function (transceiver, send, recv) {\n let kind = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'audio';\n if (!send && !recv) {\n // disabled: have we removed it?\n if (transceiver) {\n if (transceiver.setDirection) {\n transceiver.setDirection(\"inactive\");\n } else {\n transceiver.direction = \"inactive\";\n }\n }\n } else {\n if (send && recv) {\n if (transceiver) {\n if (transceiver.setDirection) {\n transceiver.setDirection(\"sendrecv\");\n } else {\n transceiver.direction = \"sendrecv\";\n }\n }\n } else if (send && !recv) {\n if (transceiver) {\n if (transceiver.setDirection) {\n transceiver.setDirection(\"sendonly\");\n } else {\n transceiver.direction = \"sendonly\";\n }\n }\n } else if (!send && recv) {\n if (transceiver) {\n if (transceiver.setDirection) {\n transceiver.setDirection(\"recvonly\");\n } else {\n transceiver.direction = \"recvonly\";\n }\n } else {\n // In theory, this is the only case where we might not have a transceiver yet\n config.pc.addTransceiver(kind, {\n direction: \"recvonly\"\n });\n }\n }\n }\n };\n\n // if we're passing any transceivers, we work only on them, doesn't matter if one of them is null\n if (audioTransceiver || videoTransceiver) {\n if (audioTransceiver) {\n setTransceiver(audioTransceiver, audioSend, audioRecv, 'audio');\n }\n if (videoTransceiver) {\n setTransceiver(videoTransceiver, videoSend, videoRecv, 'video');\n }\n }\n // else we work on all transceivers\n else {\n let transceivers = config.pc.getTransceivers();\n if (transceivers && transceivers.length > 0) {\n for (let i in transceivers) {\n let t = transceivers[i];\n if (t.sender && t.sender.track && t.sender.track.kind === \"audio\" || t.receiver && t.receiver.track && t.receiver.track.kind === \"audio\") {\n setTransceiver(t, audioSend, audioRecv, 'audio');\n }\n if (t.sender && t.sender.track && t.sender.track.kind === \"video\" || t.receiver && t.receiver.track && t.receiver.track.kind === \"video\") {\n setTransceiver(t, videoSend, videoRecv, 'video');\n }\n }\n }\n }\n }\n _createAO() {\n let type = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'offer';\n let handleId = arguments.length > 1 ? arguments[1] : undefined;\n let iceRestart = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;\n let handle = this._getHandle(handleId);\n if (!handle) {\n return Promise.reject({\n type: 'warning',\n id: 15,\n message: 'id non-existent',\n data: [handleId, 'createAO', type]\n });\n }\n let methodName = null;\n if (type === 'offer') {\n methodName = 'createOffer';\n } else {\n methodName = 'createAnswer';\n }\n let config = handle.webrtcStuff;\n let mediaConstraints = {};\n if (iceRestart) {\n mediaConstraints[\"iceRestart\"] = true;\n }\n return config.pc[methodName](mediaConstraints).then(response => {\n config.mySdp = response.sdp;\n let _p = config.pc.setLocalDescription(response).catch(e => {\n return Promise.reject({\n type: 'warning',\n id: 24,\n message: 'setLocalDescription',\n data: [handleId, e]\n });\n });\n config.mediaConstraints = mediaConstraints;\n if (!config.iceDone && !config.trickle) {\n // Don't do anything until we have all candidates\n return Promise.resolve(null);\n }\n\n // JSON.stringify doesn't work on some WebRTC objects anymore\n // See https://code.google.com/p/chromium/issues/detail?id=467366\n var jsep = {\n \"type\": response.type,\n \"sdp\": response.sdp\n };\n if (response.e2ee) jsep.e2ee = true;\n if (response.rid_order === \"hml\" || response.rid_order === \"lmh\") jsep.rid_order = response.rid_order;\n if (response.force_relay) jsep.force_relay = true;\n return _p.then(() => jsep);\n }, e => {\n return Promise.reject({\n type: 'warning',\n id: 25,\n message: methodName,\n data: [handleId, e]\n });\n });\n }\n _publishRemote(handleId, jsep) {\n let handle = this._getHandle(handleId);\n if (!handle) {\n return Promise.reject({\n type: 'warning',\n id: 15,\n message: 'id non-existent',\n data: [handleId, 'publish remote participant']\n });\n }\n this._webrtc(handleId, true);\n let config = handle.webrtcStuff;\n if (jsep) {\n return config.pc.setRemoteDescription(jsep).then(() => {\n config.remoteSdp = jsep.sdp;\n // Any trickle candidate we cached?\n if (config.candidates && config.candidates.length > 0) {\n for (var i = 0; i < config.candidates.length; i++) {\n var candidate = config.candidates[i];\n if (!candidate || candidate.completed === true) {\n // end-of-candidates\n config.pc.addIceCandidate(null);\n } else {\n // New candidate\n config.pc.addIceCandidate(candidate);\n }\n }\n config.candidates = [];\n }\n this._setupTransceivers(handleId, [false, true, false, true]);\n\n // Create the answer now\n return this._createAO('answer', handleId, false).then(_jsep => {\n if (!_jsep) {\n this.emit('error', {\n type: 'warning',\n id: 19,\n message: 'publish remote participant',\n data: [handleId, 'no jsep']\n });\n return Promise.resolve();\n }\n return this.sendMessage(handleId, {\n \"body\": {\n \"request\": \"start\",\n ...(this.roomId && {\n \"room\": this.roomId\n }),\n ...(this.pin && {\n pin: this.pin\n })\n },\n \"jsep\": _jsep\n });\n });\n }, e => Promise.reject({\n type: 'warning',\n id: 23,\n message: 'setRemoteDescription',\n data: [handleId, e]\n }));\n } else {\n return Promise.resolve();\n }\n }\n\n //Public methods\n _republishOnTrackEnded(source) {\n let handle = this._getHandle(this.handleId);\n if (!handle) {\n return;\n }\n let config = handle.webrtcStuff;\n if (!config.stream) {\n return;\n }\n let sourceTrackIds = config.streamMap[source] || [];\n let remainingTracks = [];\n for (let i = 0; i < sourceTrackIds.length; i++) {\n let foundTrack = config.stream.getTracks().find(t => t.id === sourceTrackIds[i]);\n if (foundTrack) {\n remainingTracks.push(foundTrack);\n }\n }\n if (remainingTracks.length) {\n let stream = new MediaStream();\n remainingTracks.forEach(track => stream.addTrack(track));\n return this.publishLocal(stream, source);\n } else {\n return this.publishLocal(null, source);\n }\n }\n publishLocal() {\n var _stream$getVideoTrack, _stream$getAudioTrack, _config$stream4, _config$stream4$getAu, _config$stream5, _config$stream5$getVi, _stream$getAudioTrack2, _stream$getVideoTrack2;\n let stream = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;\n let source = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'camera0';\n if (this.isDisconnecting || !this.isConnected) {\n return Promise.reject({\n type: 'warning',\n id: 18,\n message: 'Either not connected or disconnecting'\n });\n }\n if ((stream === null || stream === void 0 ? void 0 : (_stream$getVideoTrack = stream.getVideoTracks()) === null || _stream$getVideoTrack === void 0 ? void 0 : _stream$getVideoTrack.length) > 1) {\n return Promise.reject({\n type: 'warning',\n id: 30,\n message: 'multiple video tracks not supported',\n data: null\n });\n }\n if ((stream === null || stream === void 0 ? void 0 : (_stream$getAudioTrack = stream.getAudioTracks()) === null || _stream$getAudioTrack === void 0 ? void 0 : _stream$getAudioTrack.length) > 1) {\n return Promise.reject({\n type: 'warning',\n id: 30,\n message: 'multiple audio tracks not supported',\n data: null\n });\n }\n let handle = this._getHandle(this.handleId);\n if (!handle) {\n return Promise.reject({\n type: 'error',\n id: 31,\n message: 'no local id, connect before publishing',\n data: null\n });\n }\n this.emit('publishing', true);\n this._webrtc(this.handleId);\n let config = handle.webrtcStuff;\n if (!config.stream) {\n config.stream = new MediaStream();\n }\n let needsNegotiation = !this.isPublished;\n let transceivers = config.pc.getTransceivers();\n let existingTracks = [...(config.streamMap[source] || [])];\n if (stream !== null && stream !== void 0 && stream.getTracks().length) {\n var _stream$getTracks;\n config.streamMap[source] = (stream === null || stream === void 0 ? void 0 : (_stream$getTracks = stream.getTracks()) === null || _stream$getTracks === void 0 ? void 0 : _stream$getTracks.map(track => track.id)) || [];\n } else {\n delete config.streamMap[source];\n }\n\n // remove old audio track related to this source\n let oldAudioStream = config === null || config === void 0 ? void 0 : (_config$stream4 = config.stream) === null || _config$stream4 === void 0 ? void 0 : (_config$stream4$getAu = _config$stream4.getAudioTracks()) === null || _config$stream4$getAu === void 0 ? void 0 : _config$stream4$getAu.find(track => existingTracks.includes(track.id));\n if (oldAudioStream) {\n try {\n oldAudioStream.stop();\n } catch (e) {\n this._log(e);\n }\n config.stream.removeTrack(oldAudioStream);\n }\n\n // remove old video track related to this source\n let oldVideoStream = config === null || config === void 0 ? void 0 : (_config$stream5 = config.stream) === null || _config$stream5 === void 0 ? void 0 : (_config$stream5$getVi = _config$stream5.getVideoTracks()) === null || _config$stream5$getVi === void 0 ? void 0 : _config$stream5$getVi.find(track => existingTracks.includes(track.id));\n if (oldVideoStream) {\n try {\n oldVideoStream.stop();\n } catch (e) {\n this._log(e);\n }\n config.stream.removeTrack(oldVideoStream);\n }\n let audioTrackReplacePromise = Promise.resolve();\n let videoTrackReplacePromise = Promise.resolve();\n let audioTransceiver = null;\n let videoTransceiver = null;\n let replaceAudio = stream === null || stream === void 0 ? void 0 : (_stream$getAudioTrack2 = stream.getAudioTracks()) === null || _stream$getAudioTrack2 === void 0 ? void 0 : _stream$getAudioTrack2.length;\n let replaceVideo = stream === null || stream === void 0 ? void 0 : (_stream$getVideoTrack2 = stream.getVideoTracks()) === null || _stream$getVideoTrack2 === void 0 ? void 0 : _stream$getVideoTrack2.length;\n for (const transceiver of transceivers) {\n var _transceiver$sender, _transceiver$sender$t, _transceiver$sender2, _transceiver$sender2$, _transceiver$sender3, _transceiver$sender3$, _transceiver$sender4, _transceiver$sender4$, _transceiver$sender5, _transceiver$sender5$, _transceiver$sender5$2, _transceiver$sender6, _transceiver$sender6$, _transceiver$sender6$2;\n if (['sendonly', 'sendrecv'].includes(transceiver.currentDirection) && ((_transceiver$sender = transceiver.sender) === null || _transceiver$sender === void 0 ? void 0 : (_transceiver$sender$t = _transceiver$sender.track) === null || _transceiver$sender$t === void 0 ? void 0 : _transceiver$sender$t.kind) === 'audio' && existingTracks.includes((_transceiver$sender2 = transceiver.sender) === null || _transceiver$sender2 === void 0 ? void 0 : (_transceiver$sender2$ = _transceiver$sender2.track) === null || _transceiver$sender2$ === void 0 ? void 0 : _transceiver$sender2$.id)) {\n audioTransceiver = transceiver;\n } else if (['sendonly', 'sendrecv'].includes(transceiver.currentDirection) && ((_transceiver$sender3 = transceiver.sender) === null || _transceiver$sender3 === void 0 ? void 0 : (_transceiver$sender3$ = _transceiver$sender3.track) === null || _transceiver$sender3$ === void 0 ? void 0 : _transceiver$sender3$.kind) === 'video' && existingTracks.includes((_transceiver$sender4 = transceiver.sender) === null || _transceiver$sender4 === void 0 ? void 0 : (_transceiver$sender4$ = _transceiver$sender4.track) === null || _transceiver$sender4$ === void 0 ? void 0 : _transceiver$sender4$.id)) {\n videoTransceiver = transceiver;\n }\n\n // Reusing existing transceivers\n // TODO: if we start using different codecs for different sources, we need to check for that here\n else if (transceiver.currentDirection === 'inactive' && (_transceiver$sender5 = transceiver.sender) !== null && _transceiver$sender5 !== void 0 && (_transceiver$sender5$ = _transceiver$sender5.getParameters()) !== null && _transceiver$sender5$ !== void 0 && (_transceiver$sender5$2 = _transceiver$sender5$.codecs) !== null && _transceiver$sender5$2 !== void 0 && _transceiver$sender5$2.find(c => c.mimeType.indexOf('audio') > -1) && replaceAudio && !audioTransceiver) {\n audioTransceiver = transceiver;\n needsNegotiation = true;\n } else if (transceiver.currentDirection === 'inactive' && (_transceiver$sender6 = transceiver.sender) !== null && _transceiver$sender6 !== void 0 && (_transceiver$sender6$ = _transceiver$sender6.getParameters()) !== null && _transceiver$sender6$ !== void 0 && (_transceiver$sender6$2 = _transceiver$sender6$.codecs) !== null && _transceiver$sender6$2 !== void 0 && _transceiver$sender6$2.find(c => c.mimeType.indexOf('video') > -1) && replaceVideo && !videoTransceiver) {\n videoTransceiver = transceiver;\n needsNegotiation = true;\n }\n }\n if (replaceAudio) {\n config.stream.addTrack(stream.getAudioTracks()[0]);\n if (audioTransceiver && audioTransceiver.sender) {\n audioTrackReplacePromise = audioTransceiver.sender.replaceTrack(stream.getAudioTracks()[0]);\n } else {\n config.pc.addTrack(stream.getAudioTracks()[0], config.stream);\n needsNegotiation = true;\n }\n } else {\n if (audioTransceiver && audioTransceiver.sender) {\n audioTrackReplacePromise = audioTransceiver.sender.replaceTrack(null);\n needsNegotiation = true;\n }\n }\n if (replaceVideo) {\n config.stream.addTrack(stream.getVideoTracks()[0]);\n if (videoTransceiver && videoTransceiver.sender) {\n videoTrackReplacePromise = videoTransceiver.sender.replaceTrack(stream.getVideoTracks()[0]);\n } else {\n if (!this.simulcast) {\n config.pc.addTrack(stream.getVideoTracks()[0], config.stream);\n } else {\n if (webrtc_adapter__WEBPACK_IMPORTED_MODULE_0__[\"default\"].browserDetails.browser !== 'firefox') {\n // standard\n config.pc.addTransceiver(stream.getVideoTracks()[0], {\n direction: 'sendonly',\n streams: [config.stream],\n sendEncodings: structuredClone(this.simulcastBitrates)\n });\n } else {\n // firefox\n let transceiver = config.pc.addTransceiver(stream.getVideoTracks()[0], {\n direction: 'sendonly',\n streams: [config.stream]\n });\n let sender = transceiver ? transceiver.sender : null;\n if (sender) {\n let parameters = sender.getParameters() || {};\n parameters.encodings = stream.getVideoTracks()[0].sendEncodings || structuredClone(this.simulcastBitrates);\n sender.setParameters(parameters);\n }\n }\n }\n needsNegotiation = true;\n }\n } else {\n if (videoTransceiver && videoTransceiver.sender) {\n videoTrackReplacePromise = videoTransceiver.sender.replaceTrack(null);\n needsNegotiation = true;\n }\n }\n this.isAudioEnabed = !!(config.stream && config.stream.getAudioTracks().length > 0);\n this.isVideoEnabled = !!(config.stream && config.stream.getVideoTracks().length > 0);\n\n // we possibly created new transceivers, so we need to get them again\n transceivers = config.pc.getTransceivers();\n existingTracks = [...(config.streamMap[source] || [])];\n if (!audioTransceiver) {\n audioTransceiver = transceivers.find(transceiver => transceiver.sender.track && transceiver.sender.track.kind === 'audio' && existingTracks.includes(transceiver.sender.track.id));\n }\n if (!videoTransceiver) {\n videoTransceiver = transceivers.find(transceiver => transceiver.sender.track && transceiver.sender.track.kind === 'video' && existingTracks.includes(transceiver.sender.track.id));\n }\n let hasAudio = !!(stream && stream.getAudioTracks().length > 0);\n let hasVideo = !!(stream && stream.getVideoTracks().length > 0);\n this._setupTransceivers(this.handleId, [hasAudio, false, hasVideo, false, audioTransceiver, videoTransceiver]);\n const emitEvents = () => {\n var _decodeJanusDisplay27, _decodeJanusDisplay28;\n this.isPublished = true;\n if (!config.stream.onremovetrack) {\n config.stream.onremovetrack = ev => {};\n }\n let republishTimeoutId = null;\n let tracks = config.stream.getTracks();\n this.emit('addLocalParticipant', {\n tid: Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"generateUUID\"])(),\n id: handle.handleId,\n userId: (_decodeJanusDisplay27 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay27 === void 0 ? void 0 : _decodeJanusDisplay27.userId,\n role: (_decodeJanusDisplay28 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(this.display)) === null || _decodeJanusDisplay28 === void 0 ? void 0 : _decodeJanusDisplay28.role,\n stream: tracks.length ? config.stream : null,\n // that null is there due to backward compatibility\n track: null,\n streamMap: structuredClone(config.streamMap),\n source,\n adding: false,\n removing: false,\n constructId: this.constructId,\n hasAudioTrack: hasAudio,\n hasVideoTrack: hasVideo\n });\n if (tracks.length) {\n tracks.forEach(track => {\n // used as a flag to not emit tracks that been already emitted\n if (!track.onended) {\n var _decodeJanusDisplay29, _decodeJanusDisplay30;\n this.emit('addLocalParticipant', {\n tid: Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"generateUUID\"])(),\n id: handle.handleId,\n userId: (_decodeJanusDisplay29 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay29 === void 0 ? void 0 : _decodeJanusDisplay29.userId,\n role: (_decodeJanusDisplay30 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(this.display)) === null || _decodeJanusDisplay30 === void 0 ? void 0 : _decodeJanusDisplay30.role,\n track,\n stream: config.stream,\n streamMap: structuredClone(config.streamMap),\n source,\n adding: true,\n removing: false,\n constructId: this.constructId,\n hasAudioTrack: hasAudio,\n hasVideoTrack: hasVideo\n });\n track.onended = ev => {\n config.stream.removeTrack(track);\n clearTimeout(republishTimeoutId);\n republishTimeoutId = setTimeout(() => {\n this._republishOnTrackEnded(source);\n }, 100);\n };\n }\n });\n }\n this.isMuted = [];\n for (const source of Object.keys(config.streamMap)) {\n var _config$stream6, _config$stream6$getAu, _config$stream7, _config$stream7$getVi, _transceivers$find2, _transceivers$find3;\n const audioTrack = (_config$stream6 = config.stream) === null || _config$stream6 === void 0 ? void 0 : (_config$stream6$getAu = _config$stream6.getAudioTracks()) === null || _config$stream6$getAu === void 0 ? void 0 : _config$stream6$getAu.find(track => config.streamMap[source].includes(track.id));\n const videoTrack = (_config$stream7 = config.stream) === null || _config$stream7 === void 0 ? void 0 : (_config$stream7$getVi = _config$stream7.getVideoTracks()) === null || _config$stream7$getVi === void 0 ? void 0 : _config$stream7$getVi.find(track => config.streamMap[source].includes(track.id));\n this.isMuted.push({\n type: 'audio',\n value: !audioTrack || !audioTrack.enabled,\n source,\n mid: (_transceivers$find2 = transceivers.find(transceiver => {\n var _transceiver$sender7, _transceiver$sender7$, _transceiver$sender8, _transceiver$sender8$;\n return ((_transceiver$sender7 = transceiver.sender) === null || _transceiver$sender7 === void 0 ? void 0 : (_transceiver$sender7$ = _transceiver$sender7.track) === null || _transceiver$sender7$ === void 0 ? void 0 : _transceiver$sender7$.kind) === 'audio' && ((_transceiver$sender8 = transceiver.sender) === null || _transceiver$sender8 === void 0 ? void 0 : (_transceiver$sender8$ = _transceiver$sender8.track) === null || _transceiver$sender8$ === void 0 ? void 0 : _transceiver$sender8$.id) === (audioTrack === null || audioTrack === void 0 ? void 0 : audioTrack.id);\n })) === null || _transceivers$find2 === void 0 ? void 0 : _transceivers$find2.mid\n });\n this.isMuted.push({\n type: 'video',\n value: !videoTrack || !videoTrack.enabled,\n source,\n mid: (_transceivers$find3 = transceivers.find(transceiver => {\n var _transceiver$sender9, _transceiver$sender9$, _transceiver$sender10, _transceiver$sender11;\n return ((_transceiver$sender9 = transceiver.sender) === null || _transceiver$sender9 === void 0 ? void 0 : (_transceiver$sender9$ = _transceiver$sender9.track) === null || _transceiver$sender9$ === void 0 ? void 0 : _transceiver$sender9$.kind) === 'video' && ((_transceiver$sender10 = transceiver.sender) === null || _transceiver$sender10 === void 0 ? void 0 : (_transceiver$sender11 = _transceiver$sender10.track) === null || _transceiver$sender11 === void 0 ? void 0 : _transceiver$sender11.id) === (videoTrack === null || videoTrack === void 0 ? void 0 : videoTrack.id);\n })) === null || _transceivers$find3 === void 0 ? void 0 : _transceivers$find3.mid\n });\n this.emit('localHasVideo', !!videoTrack, source);\n this.emit('localHasAudio', !!audioTrack, source);\n }\n for (const val of this.isMuted) {\n this.emit('localMuted', {\n ...val\n });\n }\n this.emit('published', {\n status: true,\n hasStream: tracks.length > 0\n });\n this.emit('publishing', false);\n return this;\n };\n\n // this should be enough\n if (!needsNegotiation) {\n return Promise.all([audioTrackReplacePromise, videoTrackReplacePromise]).then(() => emitEvents());\n }\n this._log('Starting negotiation');\n return Promise.all([audioTrackReplacePromise, videoTrackReplacePromise]).then(() => this._createAO('offer', this.handleId, false)).then(jsep => {\n if (!jsep) {\n return null;\n }\n //HOTFIX: Temporary fix for Safari 13\n if (jsep.sdp && jsep.sdp.indexOf(\"\\r\\na=ice-ufrag\") === -1) {\n jsep.sdp = jsep.sdp.replace(\"\\na=ice-ufrag\", \"\\r\\na=ice-ufrag\");\n }\n let descriptions = [];\n Object.keys(config.streamMap).forEach(source => {\n config.streamMap[source].forEach(trackId => {\n let t = transceivers.find(transceiver => transceiver.sender.track && transceiver.sender.track.id === trackId);\n if (t) {\n descriptions.push({\n mid: t.mid,\n description: JSON.stringify({\n source,\n simulcastBitrates: this.simulcastBitrates,\n intercomGroups: this._talkIntercomChannels\n })\n });\n }\n });\n });\n return this.sendMessage(this.handleId, {\n body: {\n \"request\": \"configure\",\n \"audio\": this.isAudioEnabed,\n \"video\": this.isVideoEnabled,\n \"data\": true,\n ...(this.recordingFilename ? {\n filename: this.recordingFilename\n } : {}),\n descriptions: descriptions\n },\n jsep\n });\n }).then(r => {\n if (this._isDataChannelOpen === true) {\n return Promise.resolve(r);\n } else {\n return new Promise((resolve, reject) => {\n let dataChannelTimeoutId = null;\n let _resolve = val => {\n if (val) {\n clearTimeout(dataChannelTimeoutId);\n this._abortController.signal.removeEventListener('abort', _rejectAbort);\n this.off('dataChannel', _resolve, this);\n resolve(this);\n }\n };\n let _rejectTimeout = () => {\n this.off('dataChannel', _resolve, this);\n this._abortController.signal.removeEventListener('abort', _rejectAbort);\n reject({\n type: 'error',\n id: 27,\n message: 'Data channel did not open',\n data: null\n });\n };\n let _rejectAbort = () => {\n this._abortController.signal.removeEventListener('abort', _rejectAbort);\n clearTimeout(dataChannelTimeoutId);\n this.off('dataChannel', _resolve, this);\n reject({\n type: 'warning',\n id: 17,\n message: 'Connection cancelled'\n });\n };\n dataChannelTimeoutId = setTimeout(_rejectTimeout, 10000);\n this._abortController.signal.addEventListener('abort', _rejectAbort);\n this.on('dataChannel', _resolve, this);\n });\n }\n }).then(() => emitEvents()).catch(e => {\n this.emit('publishing', false);\n return Promise.reject(e);\n });\n }\n unpublishLocal() {\n let dontWait = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;\n return this.isPublished ? this.sendMessage(this.handleId, {\n body: {\n \"request\": \"unpublish\"\n }\n }, dontWait).finally(r => {\n this.isPublished = false;\n this.emit('published', {\n status: false,\n hasStream: false\n });\n return r;\n }) : Promise.resolve();\n }\n getUserTalkIntercomChannels(userId) {\n let talkIntercomChannels = [];\n let handle = this._getHandle(null, null, userId);\n if (handle) {\n let config = handle.webrtcStuff;\n talkIntercomChannels = config.tracksMap.reduce((acc, val) => {\n if (val.description) {\n try {\n let description = JSON.parse(val.description);\n if (description.intercomGroups) {\n description.intercomGroups.forEach(group => {\n if (!acc.includes(group)) {\n acc.push(group);\n }\n });\n }\n } catch (e) {}\n }\n return acc;\n }, []);\n }\n return talkIntercomChannels;\n }\n toggleAudio() {\n var _config$pc3;\n let value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;\n let source = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'camera0';\n let mid = arguments.length > 2 ? arguments[2] : undefined;\n let handle = this._getHandle(this.handleId);\n if (!handle) {\n this.emit('error', {\n type: 'warning',\n id: 21,\n message: 'no local id, connect first',\n data: null\n });\n return;\n }\n let config = handle.webrtcStuff;\n let transceivers = (_config$pc3 = config.pc) === null || _config$pc3 === void 0 ? void 0 : _config$pc3.getTransceivers();\n let transceiver = null;\n if (source) {\n transceiver = transceivers === null || transceivers === void 0 ? void 0 : transceivers.find(t => t.sender && t.sender.track && t.receiver.track.kind === \"audio\" && (config.streamMap[source] || []).includes(t.sender.track.id));\n } else {\n transceiver = transceivers === null || transceivers === void 0 ? void 0 : transceivers.find(t => t.sender && t.sender.track && t.receiver.track.kind === \"audio\" && (mid ? t.mid === mid : true));\n }\n if (transceiver) {\n transceiver.sender.track.enabled = value !== null ? !!value : !transceiver.sender.track.enabled;\n }\n this.isMuted = [];\n for (const source of Object.keys(config.streamMap)) {\n var _config$stream8, _config$stream8$getAu, _config$stream9, _config$stream9$getVi, _audioTransceiver$sen, _audioTransceiver$sen2, _videoTransceiver$sen, _videoTransceiver$sen2;\n const audioTrack = (_config$stream8 = config.stream) === null || _config$stream8 === void 0 ? void 0 : (_config$stream8$getAu = _config$stream8.getAudioTracks()) === null || _config$stream8$getAu === void 0 ? void 0 : _config$stream8$getAu.find(track => config.streamMap[source].includes(track.id));\n const audioTransceiver = transceivers === null || transceivers === void 0 ? void 0 : transceivers.find(transceiver => transceiver.sender.track && transceiver.sender.track.kind === 'audio' && transceiver.sender.track.id === (audioTrack === null || audioTrack === void 0 ? void 0 : audioTrack.id));\n const videoTrack = (_config$stream9 = config.stream) === null || _config$stream9 === void 0 ? void 0 : (_config$stream9$getVi = _config$stream9.getVideoTracks()) === null || _config$stream9$getVi === void 0 ? void 0 : _config$stream9$getVi.find(track => config.streamMap[source].includes(track.id));\n const videoTransceiver = transceivers === null || transceivers === void 0 ? void 0 : transceivers.find(transceiver => transceiver.sender.track && transceiver.sender.track.kind === 'video' && transceiver.sender.track.id === (videoTrack === null || videoTrack === void 0 ? void 0 : videoTrack.id));\n this.isMuted.push({\n type: 'audio',\n value: !audioTrack || !audioTransceiver || !(audioTransceiver !== null && audioTransceiver !== void 0 && (_audioTransceiver$sen = audioTransceiver.sender) !== null && _audioTransceiver$sen !== void 0 && (_audioTransceiver$sen2 = _audioTransceiver$sen.track) !== null && _audioTransceiver$sen2 !== void 0 && _audioTransceiver$sen2.enabled),\n source,\n mid: audioTransceiver === null || audioTransceiver === void 0 ? void 0 : audioTransceiver.mid\n });\n this.isMuted.push({\n type: 'video',\n value: !videoTrack || !videoTransceiver || !(videoTransceiver !== null && videoTransceiver !== void 0 && (_videoTransceiver$sen = videoTransceiver.sender) !== null && _videoTransceiver$sen !== void 0 && (_videoTransceiver$sen2 = _videoTransceiver$sen.track) !== null && _videoTransceiver$sen2 !== void 0 && _videoTransceiver$sen2.enabled),\n source,\n mid: videoTransceiver === null || videoTransceiver === void 0 ? void 0 : videoTransceiver.mid\n });\n }\n for (let val of this.isMuted) {\n this.emit('localMuted', {\n ...val\n });\n }\n }\n toggleVideo() {\n var _config$pc4;\n let value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;\n let source = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'camera0';\n let mid = arguments.length > 2 ? arguments[2] : undefined;\n let handle = this._getHandle(this.handleId);\n if (!handle) {\n this.emit('error', {\n type: 'warning',\n id: 21,\n message: 'no local id, connect first',\n data: null\n });\n return;\n }\n let config = handle.webrtcStuff;\n let transceivers = (_config$pc4 = config.pc) === null || _config$pc4 === void 0 ? void 0 : _config$pc4.getTransceivers();\n let transceiver = null;\n if (source) {\n transceiver = transceivers === null || transceivers === void 0 ? void 0 : transceivers.find(t => t.sender && t.sender.track && t.receiver.track.kind === \"video\" && (config.streamMap[source] || []).includes(t.sender.track.id));\n } else {\n transceiver = transceivers === null || transceivers === void 0 ? void 0 : transceivers.find(t => t.sender && t.sender.track && t.receiver.track.kind === \"video\" && (mid ? t.mid === mid : true));\n }\n if (transceiver) {\n transceiver.sender.track.enabled = value !== null ? !!value : !transceiver.sender.track.enabled;\n }\n this.isMuted = [];\n for (const source of Object.keys(config.streamMap)) {\n var _config$stream10, _config$stream10$getA, _config$stream11, _config$stream11$getV, _audioTransceiver$sen3, _audioTransceiver$sen4, _videoTransceiver$sen3, _videoTransceiver$sen4;\n const audioTrack = (_config$stream10 = config.stream) === null || _config$stream10 === void 0 ? void 0 : (_config$stream10$getA = _config$stream10.getAudioTracks()) === null || _config$stream10$getA === void 0 ? void 0 : _config$stream10$getA.find(track => config.streamMap[source].includes(track.id));\n const audioTransceiver = transceivers === null || transceivers === void 0 ? void 0 : transceivers.find(transceiver => transceiver.sender.track && transceiver.sender.track.kind === 'audio' && transceiver.sender.track.id === (audioTrack === null || audioTrack === void 0 ? void 0 : audioTrack.id));\n const videoTrack = (_config$stream11 = config.stream) === null || _config$stream11 === void 0 ? void 0 : (_config$stream11$getV = _config$stream11.getVideoTracks()) === null || _config$stream11$getV === void 0 ? void 0 : _config$stream11$getV.find(track => config.streamMap[source].includes(track.id));\n const videoTransceiver = transceivers === null || transceivers === void 0 ? void 0 : transceivers.find(transceiver => transceiver.sender.track && transceiver.sender.track.kind === 'video' && transceiver.sender.track.id === (videoTrack === null || videoTrack === void 0 ? void 0 : videoTrack.id));\n this.isMuted.push({\n type: 'audio',\n value: !audioTrack || !audioTransceiver || !(audioTransceiver !== null && audioTransceiver !== void 0 && (_audioTransceiver$sen3 = audioTransceiver.sender) !== null && _audioTransceiver$sen3 !== void 0 && (_audioTransceiver$sen4 = _audioTransceiver$sen3.track) !== null && _audioTransceiver$sen4 !== void 0 && _audioTransceiver$sen4.enabled),\n source,\n mid: audioTransceiver === null || audioTransceiver === void 0 ? void 0 : audioTransceiver.mid\n });\n this.isMuted.push({\n type: 'video',\n value: !videoTrack || !videoTransceiver || !(videoTransceiver !== null && videoTransceiver !== void 0 && (_videoTransceiver$sen3 = videoTransceiver.sender) !== null && _videoTransceiver$sen3 !== void 0 && (_videoTransceiver$sen4 = _videoTransceiver$sen3.track) !== null && _videoTransceiver$sen4 !== void 0 && _videoTransceiver$sen4.enabled),\n source,\n mid: videoTransceiver === null || videoTransceiver === void 0 ? void 0 : videoTransceiver.mid\n });\n }\n for (let val of this.isMuted) {\n this.emit('localMuted', {\n ...val\n });\n }\n }\n requestKeyFrame(handleId, mid) {\n this.sendMessage(handleId, {\n \"body\": {\n \"request\": \"configure\",\n \"keyframe\": true,\n ...(mid !== undefined ? {\n streams: [{\n mid,\n keyframe: true\n }]\n } : {})\n }\n }).catch(() => null);\n }\n _setSelectedSubstream(handleId, mid, substream) {\n let handle = this._getHandle(handleId);\n if (handle) {\n let config = handle.webrtcStuff;\n if (!mid) {\n Object.keys(config.selectedSubstream).forEach(mid => {\n config.selectedSubstream[mid] = substream;\n });\n } else {\n config.selectedSubstream[mid] = substream;\n }\n }\n }\n selectSubStream(handleId) {\n let substream = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 2;\n let source = arguments.length > 2 ? arguments[2] : undefined;\n let mid = arguments.length > 3 ? arguments[3] : undefined;\n let manual = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;\n this._log('Select substream called for handle:', handleId, 'Source or mid:', source ? source : mid, 'Substream:', substream);\n let handle = this._getHandle(handleId);\n if (!handle) {\n return Promise.resolve();\n }\n let config = handle.webrtcStuff;\n return new Promise((resolve, reject) => {\n let messageTimeoutId;\n let abortResponse = () => {\n clearTimeout(messageTimeoutId);\n this._abortController.signal.removeEventListener('abort', abortResponse);\n this.ws.removeEventListener('message', parseResponse);\n reject('aborted');\n };\n let parseResponse = event => {\n let json = JSON.parse(event.data);\n var sender = json[\"sender\"];\n if (sender === handleId) {\n let plugindata = json[\"plugindata\"] || {};\n let msg = plugindata[\"data\"] || {};\n let substream = msg[\"substream\"];\n if (substream !== undefined && substream !== null && (mid !== undefined ? msg[\"mid\"] === mid : true)) {\n clearTimeout(messageTimeoutId);\n this._abortController.signal.removeEventListener('abort', abortResponse);\n this.ws.removeEventListener('message', parseResponse);\n resolve({\n substream,\n sender\n });\n }\n }\n };\n if (source !== undefined || mid !== undefined) {\n if (mid === undefined) {\n let transceivers = config.pc.getTransceivers();\n for (let trackId of config.streamMap[source]) {\n let transceiver = transceivers.find(transceiver => transceiver.receiver.track && transceiver.receiver.track.kind === 'video' && transceiver.receiver.track.id === trackId);\n if (transceiver) {\n mid = transceiver.mid;\n break;\n }\n }\n }\n if (mid !== undefined) {\n if (substream === null) {\n if (manual) {\n config.forcedBrowserControlledMode[mid] = false;\n }\n resolve({\n substream,\n sender: handleId\n });\n return;\n }\n if (manual) {\n config.forcedBrowserControlledMode[mid] = true;\n }\n this.ws.addEventListener('message', parseResponse);\n this._abortController.signal.addEventListener('abort', abortResponse);\n messageTimeoutId = setTimeout(() => {\n this._abortController.signal.removeEventListener('abort', abortResponse);\n this.ws.removeEventListener('message', parseResponse);\n reject('timeout');\n }, 10000);\n this.sendMessage(handleId, {\n \"body\": {\n \"request\": \"configure\",\n \"streams\": [{\n mid,\n substream: parseInt(substream)\n }]\n }\n });\n } else {\n reject('no mid found');\n }\n } else {\n reject('no source or mid');\n }\n });\n }\n setTalkIntercomChannels() {\n let groups = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['participants'];\n if (typeof groups !== 'object' || !(\"length\" in groups)) {\n this._log('setTalkIntercomChannels: groups must be an array');\n groups = [groups];\n }\n this._talkIntercomChannels = structuredClone(groups);\n let handle = this._getHandle(this.handleId);\n if (!handle) {\n return Promise.resolve();\n }\n let config = handle.webrtcStuff;\n let transceivers = config.pc.getTransceivers();\n let descriptions = [];\n Object.keys(config.streamMap).forEach(source => {\n config.streamMap[source].forEach(trackId => {\n let t = transceivers.find(transceiver => transceiver.sender.track && transceiver.sender.track.id === trackId);\n if (t) {\n descriptions.push({\n mid: t.mid,\n description: JSON.stringify({\n simulcastBitrates: this.simulcastBitrates,\n intercomGroups: groups,\n source: source\n })\n });\n }\n });\n });\n return this.sendMessage(this.handleId, {\n body: {\n \"request\": \"configure\",\n descriptions: descriptions\n }\n });\n }\n setListenIntercomChannels() {\n let groups = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['participants'];\n if (typeof groups !== 'object' || !(\"length\" in groups)) {\n this._log('setListenIntercomChannels: groups must be an array');\n groups = [groups];\n }\n this._listenIntercomChannels = structuredClone(groups);\n let handle = this._getHandle(this.handleId);\n if (!handle) {\n return Promise.resolve();\n }\n let promises = [];\n this._participants.forEach(participant => {\n if (participant.handleId === this.handleId) {\n return;\n }\n let handle = this._getHandle(participant.handleId);\n if (handle) {\n const tracksMap = handle.webrtcStuff.tracksMap.filter(t => t.active);\n const subscribe = [];\n const unsubscribe = [];\n tracksMap.forEach(track => {\n if (track.type === 'data') {\n return;\n }\n const description = JSON.parse(track.description);\n const intercomGroups = (description === null || description === void 0 ? void 0 : description.intercomGroups) || [];\n if (this._listenIntercomChannels.some(g => intercomGroups.includes(g))) {\n if (!this._isAlreadySubscribed(participant.handleId, track.id, track.mid)) {\n subscribe.push({\n feed: track.id,\n mid: track.mid\n });\n }\n } else {\n unsubscribe.push({\n feed: track.id,\n mid: track.mid\n });\n }\n });\n this._updateSubscribeMap(participant.handleId, subscribe, unsubscribe);\n if (subscribe.length || unsubscribe.length) {\n promises.push(this.sendMessage(handle.handleId, {\n body: {\n \"request\": \"update\",\n ...(subscribe.length ? {\n subscribe\n } : {}),\n ...(unsubscribe.length ? {\n unsubscribe\n } : {})\n }\n }));\n }\n }\n });\n return Promise.all(promises);\n }\n setRoomType() {\n let type = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'watchparty';\n this._roomType = type;\n return this._roomType;\n }\n}\n_defineProperty(RoomSession, \"sessionTypes\", {\n 'reactooroom': 'janus.plugin.reactooroom',\n 'streaming': 'janus.plugin.streaming'\n});\n_defineProperty(RoomSession, \"userRoleSubscriptionRules\", {\n participant: {\n \"watchparty\": ['participant', 'talkback'],\n \"studio\": ['participant', 'talkback', 'host', 'observer'],\n \"commentary\": ['participant', 'talkback', 'host'],\n \"intercom\": ['host', 'talkback', 'observer', 'observerSolo1', 'observerSolo2', 'observerSolo3'],\n \"videowall\": ['host', 'talkback', 'observer', 'observerSolo1', 'observerSolo2', 'observerSolo3'],\n \"videowall-queue\": ['host', 'talkback', 'observer', 'observerSolo1', 'observerSolo2', 'observerSolo3'],\n \"videowall-queue-video\": ['host', 'talkback', 'observer', 'observerSolo1', 'observerSolo2', 'observerSolo3']\n },\n monitor: {\n \"watchparty\": ['participant', 'host'],\n \"studio\": ['participant', 'host', 'observer'],\n \"commentary\": ['participant', 'host'],\n \"intercom\": ['host', 'participant'],\n \"videowall\": ['host', 'participant'],\n \"videowall-queue\": ['host', 'participant'],\n \"videowall-queue-video\": ['host', 'participant']\n },\n talkback: {\n \"watchparty\": ['participant', 'host', 'talkback'],\n \"studio\": ['participant', 'host', 'observer', 'talkback'],\n \"commentary\": ['host', 'participant', 'talkback'],\n \"intercom\": ['host', 'participant', 'talkback'],\n \"videowall\": ['host', 'participant', 'talkback'],\n \"videowall-queue\": ['host', 'participant', 'talkback'],\n \"videowall-queue-video\": ['host', 'participant', 'talkback']\n },\n observer: {\n \"watchparty\": ['participant'],\n \"studio\": ['participant'],\n \"commentary\": ['participant'],\n \"intercom\": ['participant'],\n \"videowall\": ['participant'],\n \"videowall-queue\": ['participant'],\n \"videowall-queue-video\": ['participant']\n },\n observerSolo1: {\n \"watchparty\": ['participant'],\n \"studio\": ['participant'],\n \"commentary\": ['participant'],\n \"intercom\": ['participant'],\n \"videowall\": ['participant'],\n \"videowall-queue\": ['participant'],\n \"videowall-queue-video\": ['participant']\n },\n observerSolo2: {\n \"watchparty\": ['participant'],\n \"studio\": ['participant'],\n \"commentary\": ['participant'],\n \"intercom\": ['participant'],\n \"videowall\": ['participant'],\n \"videowall-queue\": ['participant'],\n \"videowall-queue-video\": ['participant']\n },\n observerSolo3: {\n \"watchparty\": ['participant'],\n \"studio\": ['participant'],\n \"commentary\": ['participant'],\n \"intercom\": ['participant'],\n \"videowall\": ['participant'],\n \"videowall-queue\": ['participant'],\n \"videowall-queue-video\": ['participant']\n },\n host: {\n \"watchparty\": [],\n \"studio\": [],\n \"commentary\": [],\n \"intercom\": [],\n \"videowall\": [],\n \"videowall-queue\": [],\n \"videowall-queue-video\": []\n },\n companionTV: {},\n companionPhone: {}\n});\n/* harmony default export */ __webpack_exports__[\"default\"] = (Room);\n\n//# sourceURL=webpack://WatchTogetherSDK/./src/modules/wt-room.js?");
|
|
8931
|
+
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var webrtc_adapter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! webrtc-adapter */ \"./node_modules/webrtc-adapter/src/js/adapter_core.js\");\n/* harmony import */ var _wt_emitter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./wt-emitter */ \"./src/modules/wt-emitter.js\");\n/* harmony import */ var _wt_utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./wt-utils */ \"./src/modules/wt-utils.js\");\nfunction _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\nfunction _toPropertyKey(arg) { var key = _toPrimitive(arg, \"string\"); return typeof key === \"symbol\" ? key : String(key); }\nfunction _toPrimitive(input, hint) { if (typeof input !== \"object\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \"default\"); if (typeof res !== \"object\") return res; throw new TypeError(\"@@toPrimitive must return a primitive value.\"); } return (hint === \"string\" ? String : Number)(input); }\n// Watch together janus webrtc library\n\n\n\n\nclass Room {\n constructor(debug) {\n this.debug = debug;\n this.sessions = [];\n this.safariVp8 = false;\n this.browser = webrtc_adapter__WEBPACK_IMPORTED_MODULE_0__[\"default\"].browserDetails.browser;\n this.browserDetails = webrtc_adapter__WEBPACK_IMPORTED_MODULE_0__[\"default\"].browserDetails;\n this.webrtcSupported = Room.isWebrtcSupported();\n this.safariVp8TestPromise = Room.testSafariVp8();\n this.safariVp8 = null;\n this.safariVp8TestPromise.then(safariVp8 => {\n this.safariVp8 = safariVp8;\n });\n\n // Let's get it started\n this.whenInitialized = this.initialize();\n }\n initialize() {\n return this.safariVp8TestPromise.then(() => this);\n }\n createSession() {\n let constructId = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;\n let type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'reactooroom';\n let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n return new RoomSession(constructId, type, {\n debug: this.debug,\n ...options\n });\n }\n static testSafariVp8() {\n return new Promise(resolve => {\n if (webrtc_adapter__WEBPACK_IMPORTED_MODULE_0__[\"default\"].browserDetails.browser === 'safari' && webrtc_adapter__WEBPACK_IMPORTED_MODULE_0__[\"default\"].browserDetails.version >= 605) {\n if (RTCRtpSender && RTCRtpSender.getCapabilities && RTCRtpSender.getCapabilities(\"video\") && RTCRtpSender.getCapabilities(\"video\").codecs && RTCRtpSender.getCapabilities(\"video\").codecs.length) {\n var isVp8 = false;\n for (var i in RTCRtpSender.getCapabilities(\"video\").codecs) {\n var codec = RTCRtpSender.getCapabilities(\"video\").codecs[i];\n if (codec && codec.mimeType && codec.mimeType.toLowerCase() === \"video/vp8\") {\n isVp8 = true;\n break;\n }\n }\n resolve(isVp8);\n } else {\n // We do it in a very ugly way, as there's no alternative...\n // We create a PeerConnection to see if VP8 is in an offer\n var testpc = new RTCPeerConnection({}, {});\n testpc.createOffer({\n offerToReceiveVideo: true\n }).then(function (offer) {\n let result = offer.sdp.indexOf(\"VP8\") !== -1;\n testpc.close();\n testpc = null;\n resolve(result);\n });\n }\n } else resolve(false);\n });\n }\n static isWebrtcSupported() {\n return window.RTCPeerConnection !== undefined && window.RTCPeerConnection !== null && navigator.mediaDevices !== undefined && navigator.mediaDevices !== null && navigator.mediaDevices.getUserMedia !== undefined && navigator.mediaDevices.getUserMedia !== null;\n }\n}\nclass RoomSession {\n static noop() {}\n static randomString(len) {\n var charSet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n var randomString = '';\n for (var i = 0; i < len; i++) {\n var randomPoz = Math.floor(Math.random() * charSet.length);\n randomString += charSet.substring(randomPoz, randomPoz + 1);\n }\n return randomString;\n }\n constructor() {\n let constructId = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;\n let type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'reactooroom';\n let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n _defineProperty(this, \"_intercomSubscribe\", stream => {\n var _JSON$parse;\n if (stream.type === 'data') {\n return true;\n }\n const intercomGroups = ((_JSON$parse = JSON.parse(stream.description || \"[]\")) === null || _JSON$parse === void 0 ? void 0 : _JSON$parse.intercomGroups) || [];\n return intercomGroups.some(g => this._listenIntercomChannels.indexOf(g) > -1);\n });\n Object.assign(this, Object(_wt_emitter__WEBPACK_IMPORTED_MODULE_1__[\"default\"])());\n this.options = {\n ...options\n };\n this.defaultDataChannelLabel = 'JanusDataChannel';\n this.server = null;\n this.iceServers = null;\n this.token = null;\n this.roomId = null;\n this.streamId = null;\n this.pin = null;\n this.userId = null;\n this.sessiontype = type;\n this.initialBitrate = 0;\n this.simulcast = false;\n this.enableDtx = false;\n this.simulcastMode = 'controlled'; // controlled, manual, browserControlled\n this.simulcastDefaultManualSubstream = 0; // 0 = maximum quality\n\n // ordered from low to high\n this.simulcastBitrates = [{\n rid: 'l',\n active: true,\n maxBitrate: 180000,\n maxFramerate: 20,\n scaleResolutionDownBy: 3.3333333333333335,\n priority: \"low\"\n }, {\n rid: 'm',\n active: true,\n maxBitrate: 500000,\n maxFramerate: 25,\n scaleResolutionDownBy: 1.3333333333333335,\n priority: \"low\"\n }, {\n rid: 'h',\n active: true,\n maxBitrate: 2000000,\n maxFramerate: 30,\n priority: \"low\"\n }];\n this.recordingFilename = null;\n this.pluginName = RoomSession.sessionTypes[type];\n this.id = null;\n this.privateId = null;\n this.constructId = constructId || RoomSession.randomString(16);\n this.sessionId = null;\n this.handleId = null;\n this.ws = null;\n this.isRestarting = false;\n this.isConnecting = false;\n this.isDisconnecting = false;\n this.isConnected = false;\n this.isPublished = false;\n this.isReclaiming = false;\n this.isStreaming = false;\n this.isMuted = [];\n this.isVideoEnabled = false;\n this.isAudioEnabed = false;\n this._statsMaxLength = 31;\n this._upStatsLength = 30;\n this._downStatsLength = 5;\n this._statsTimeoutStopped = true;\n this._statsTimeoutId = null;\n this._statsInterval = 1000;\n this._aqInterval = 2500;\n this._aqTimeoutId = null;\n this._sendMessageTimeout = 5000;\n this._retries = 0;\n this._maxRetries = 5;\n this._keepAliveId = null;\n this._participants = [];\n this._restrictSubscribeToUserIds = []; // all if empty\n this._talkIntercomChannels = ['participants'];\n this._listenIntercomChannels = ['participants'];\n this._roomType = 'watchparty';\n this._isDataChannelOpen = false;\n this._abortController = null;\n this._remoteUsersCache = [];\n this.userRoleSubscriptionRules = {\n ...RoomSession.userRoleSubscriptionRules,\n ...(this.options.userRoleSubscriptionRules || {})\n };\n this._log = RoomSession.noop;\n if (this.options.debug) {\n this._enableDebug();\n }\n }\n _pushToRemoteUsersCache(userId, streams, id) {\n const existingIndex = this._remoteUsersCache.findIndex(u => u.userId === userId);\n if (existingIndex > -1) {\n this._remoteUsersCache.splice(existingIndex, 1, {\n userId,\n streams,\n id\n });\n } else {\n this._remoteUsersCache.push({\n userId,\n streams,\n id\n });\n }\n }\n _removeFromRemoteUsersCache(rfid) {\n const existingIndex = this._remoteUsersCache.findIndex(u => u.id === rfid);\n if (existingIndex > -1) {\n this._remoteUsersCache.splice(existingIndex, 1);\n }\n }\n _participantShouldSubscribe(userId) {\n const myUser = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(this.display);\n const remoteUser = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(userId);\n let localUserRole = (myUser === null || myUser === void 0 ? void 0 : myUser.role) || 'participant';\n let remoteUserRole = (remoteUser === null || remoteUser === void 0 ? void 0 : remoteUser.role) || 'participant';\n return this.userRoleSubscriptionRules[localUserRole][this._roomType || 'watchparty'].indexOf(remoteUserRole) > -1 && (this._restrictSubscribeToUserIds.length === 0 || this._restrictSubscribeToUserIds.indexOf(remoteUser === null || remoteUser === void 0 ? void 0 : remoteUser.userId) > -1);\n }\n _getAddParticipantEventName(handleId) {\n var _decodeJanusDisplay;\n let handle = this._getHandle(handleId);\n if (!handle) {\n this.emit('error', {\n type: 'warning',\n id: 15,\n message: 'id non-existent',\n data: [handleId, 'getParticipantEventName']\n });\n return;\n }\n const participantRole = (_decodeJanusDisplay = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay === void 0 ? void 0 : _decodeJanusDisplay.role;\n switch (participantRole) {\n case 'participant':\n return 'addRemoteParticipant';\n case 'talkback':\n return 'addRemoteTalkback';\n case 'monitor':\n return 'addRemoteTalkback';\n case 'observer':\n case 'observerSolo1':\n case 'observerSolo2':\n case 'observerSolo3':\n return 'addRemoteObserver';\n case 'host':\n return 'addRemoteInstructor';\n case 'companionTV':\n return 'addRemoteCompanionTV';\n case 'companionPhone':\n return 'addRemoteCompanionPhone';\n default:\n return 'addRemoteParticipant';\n }\n }\n _getRemoveParticipantEventName(handleId) {\n var _decodeJanusDisplay2;\n let handle = this._getHandle(handleId);\n if (!handle) {\n this.emit('error', {\n type: 'warning',\n id: 15,\n message: 'id non-existent',\n data: [handleId, 'getParticipantEventName']\n });\n return;\n }\n const participantRole = (_decodeJanusDisplay2 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay2 === void 0 ? void 0 : _decodeJanusDisplay2.role;\n switch (participantRole) {\n case 'participant':\n return 'removeRemoteParticipant';\n case 'talkback':\n return 'removeRemoteTalkback';\n case 'monitor':\n return 'removeRemoteTalkback';\n case 'observer':\n case 'observerSolo1':\n case 'observerSolo2':\n case 'observerSolo3':\n return 'removeRemoteObserver';\n case 'host':\n return 'removeRemoteInstructor';\n case 'companionTV':\n return 'removeRemoteCompanionTV';\n case 'companionPhone':\n return 'removeRemoteCompanionPhone';\n default:\n return 'removeRemoteParticipant';\n }\n }\n sendMessage(handleId) {\n let message = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {\n body: 'Example Body'\n };\n let dontWait = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;\n let dontResolveOnAck = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;\n let retry = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0;\n return this._send({\n \"janus\": \"message\",\n \"handle_id\": handleId,\n ...message\n }, dontWait, dontResolveOnAck, retry).then(json => {\n if (json && json[\"janus\"] === \"success\") {\n let plugindata = json[\"plugindata\"] || {};\n let data = plugindata[\"data\"];\n return Promise.resolve(data);\n }\n return Promise.resolve();\n }).catch(json => {\n if (json && json[\"error\"]) {\n return Promise.reject({\n type: 'warning',\n id: 1,\n message: 'sendMessage failed',\n data: json[\"error\"]\n });\n } else {\n return Promise.reject({\n type: 'warning',\n id: 1,\n message: 'sendMessage failed',\n data: json\n });\n }\n });\n }\n _send() {\n let request = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n let ignoreResponse = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;\n let dontResolveOnAck = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;\n let retry = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;\n let transaction = RoomSession.randomString(12);\n let requestData = {\n ...request,\n transaction,\n token: this.token,\n ...(this.sessionId && {\n 'session_id': this.sessionId\n } || {})\n };\n this._log(requestData);\n const op = () => new Promise((resolve, reject) => {\n let messageTimeoutId = null;\n let abortResponse = () => {\n this._abortController.signal.removeEventListener('abort', abortResponse);\n clearTimeout(messageTimeoutId);\n this.ws.removeEventListener('message', parseResponse);\n reject({\n type: 'warning',\n id: 17,\n message: 'connection cancelled'\n });\n };\n let parseResponse = event => {\n let json = JSON.parse(event.data);\n let r_transaction = json['transaction'];\n if (r_transaction === transaction && (!dontResolveOnAck || json['janus'] !== 'ack')) {\n clearTimeout(messageTimeoutId);\n this._abortController.signal.removeEventListener('abort', abortResponse);\n this.ws.removeEventListener('message', parseResponse);\n if (json['janus'] === 'error') {\n var _json$error;\n if ((json === null || json === void 0 ? void 0 : (_json$error = json.error) === null || _json$error === void 0 ? void 0 : _json$error.code) == 403) {\n this.disconnect(true);\n }\n reject({\n type: 'error',\n id: 2,\n message: 'send failed',\n data: json,\n requestData\n });\n } else {\n resolve(json);\n }\n }\n };\n if (ignoreResponse) {\n if (this.ws && this.ws.readyState === 1) {\n this.ws.send(JSON.stringify(requestData));\n }\n resolve();\n } else {\n if (this.ws && this.ws.readyState === 1) {\n this.ws.addEventListener('message', parseResponse);\n messageTimeoutId = setTimeout(() => {\n this.ws.removeEventListener('message', parseResponse);\n this._abortController.signal.removeEventListener('abort', abortResponse);\n reject({\n type: 'warning',\n id: 3,\n message: 'send timeout',\n data: requestData\n });\n }, this._sendMessageTimeout);\n this._abortController.signal.addEventListener('abort', abortResponse);\n this.ws.send(JSON.stringify(requestData));\n } else {\n reject({\n type: 'warning',\n id: 29,\n message: 'No connection to WebSockets',\n data: requestData\n });\n }\n }\n });\n return op().catch(e => {\n if (e.id === 17) {\n return Promise.reject(e);\n } else if (e.id === 29 && retry > 0) {\n return Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"wait\"])(this._sendMessageTimeout).then(() => this._send(request, ignoreResponse, dontResolveOnAck, retry - 1));\n } else if (retry > 0) {\n return this._send(request, ignoreResponse, dontResolveOnAck, retry - 1);\n } else {\n return Promise.reject(e);\n }\n });\n }\n _connectionClosed() {\n if (!this.isConnected || this.isConnecting || this.isDisconnecting) {\n return;\n }\n if (this._retries < this._maxRetries) {\n setTimeout(() => {\n this._retries++;\n this._reconnect().catch(e => {\n this.emit('error', e);\n });\n }, 3000 * this._retries);\n } else {\n if (this.sessiontype === 'reactooroom') {\n this.disconnect(true);\n } else if (this.sessiontype === 'streaming') {\n this.stopStream();\n }\n this.emit('error', {\n type: 'error',\n id: 4,\n message: 'Lost connection to WebSockets',\n data: null\n });\n }\n }\n _wipeListeners() {\n if (this.ws) {\n this.ws.removeEventListener('close', this.__connectionClosedBoundFn);\n this.ws.removeEventListener('message', this.__handleWsEventsBoundFn);\n }\n }\n _startKeepAlive() {\n this._send({\n \"janus\": \"keepalive\"\n }).then(json => {\n if (json[\"janus\"] !== 'ack') {\n this.emit('error', {\n type: 'warning',\n id: 5,\n message: 'keepalive response suspicious',\n data: json[\"janus\"]\n });\n }\n }).catch(e => {\n this.emit('error', {\n type: 'warning',\n id: 6,\n message: 'keepalive dead',\n data: e\n });\n this._connectionClosed();\n });\n this._keepAliveId = setTimeout(() => {\n this._startKeepAlive();\n }, 10000);\n }\n _stopKeepAlive() {\n clearTimeout(this._keepAliveId);\n }\n _handleWsEvents(event) {\n let json = JSON.parse(event.data);\n var sender = json[\"sender\"];\n var type = json[\"janus\"];\n let handle = this._getHandle(sender);\n if (!handle) {\n return;\n }\n if (type === \"trickle\") {\n let candidate = json[\"candidate\"];\n let config = handle.webrtcStuff;\n if (config.pc && config.remoteSdp) {\n if (!candidate || candidate.completed === true) {\n config.pc.addIceCandidate(null);\n } else {\n config.pc.addIceCandidate(candidate);\n }\n } else {\n if (!config.candidates) {\n config.candidates = [];\n }\n config.candidates.push(candidate);\n }\n } else if (type === \"webrtcup\") {\n //none universal\n } else if (type === \"hangup\") {\n this._log('hangup on', handle.handleId, handle.handleId === this.handleId, json);\n this._removeParticipant(handle.handleId, null, false);\n } else if (type === \"detached\") {\n this._log('detached on', handle.handleId, handle.handleId === this.handleId, json);\n this._removeParticipant(handle.handleId, null, true);\n } else if (type === \"media\") {\n this._log('Media event:', handle.handleId, json[\"type\"], json[\"receiving\"], json[\"mid\"]);\n } else if (type === \"slowlink\") {\n this._log('Slowlink', handle.handleId, json[\"uplink\"], json[\"lost\"], json[\"mid\"]);\n } else if (type === \"event\") {\n //none universal\n } else if (type === 'timeout') {\n this._log('WebSockets Gateway timeout', json);\n this.ws.close(3504, \"Gateway timeout\");\n } else if (type === 'success' || type === 'error') {\n // we're capturing those elsewhere\n } else {\n this._log(`Unknown event: ${type} on session: ${this.sessionId}`);\n }\n\n // LOCAL\n\n if (sender === this.handleId) {\n if (type === \"event\") {\n var plugindata = json[\"plugindata\"] || {};\n var msg = plugindata[\"data\"] || {};\n var jsep = json[\"jsep\"];\n let result = msg[\"result\"] || null;\n let event = msg[\"videoroom\"] || null;\n let list = msg[\"publishers\"] || {};\n let leaving = msg[\"leaving\"];\n let kicked = msg[\"kicked\"];\n let substream = msg[\"substream\"];\n let temporal = msg[\"temporal\"];\n\n //let joining = msg[\"joining\"];\n let unpublished = msg[\"unpublished\"];\n let error = msg[\"error\"];\n if (event === \"joined\") {\n var _decodeJanusDisplay3, _decodeJanusDisplay4;\n this.id = msg[\"id\"];\n this.privateId = msg[\"private_id\"];\n this.isConnected = true;\n this._log('We have successfully joined Room');\n this.emit('joined', true, this.constructId);\n this.emit('addLocalParticipant', {\n tid: Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"generateUUID\"])(),\n id: handle.handleId,\n constructId: this.constructId,\n userId: (_decodeJanusDisplay3 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay3 === void 0 ? void 0 : _decodeJanusDisplay3.userId,\n role: (_decodeJanusDisplay4 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(this.display)) === null || _decodeJanusDisplay4 === void 0 ? void 0 : _decodeJanusDisplay4.role,\n track: null,\n stream: null,\n streamMap: {},\n source: null,\n adding: false,\n removing: false,\n hasAudioTrack: false,\n hasVideoTrack: false\n });\n for (let f in list) {\n let userId = list[f][\"display\"];\n let streams = list[f][\"streams\"] || [];\n let id = list[f][\"id\"];\n for (let i in streams) {\n streams[i][\"id\"] = id;\n streams[i][\"display\"] = userId;\n }\n this._log('Remote userId: ', userId);\n this._pushToRemoteUsersCache(userId, streams, id);\n if (this._participantShouldSubscribe(userId)) {\n this._log('Creating user: ', userId);\n this._createParticipant(userId, id).then(handle => {\n this._updateParticipantsTrackData(handle.handleId, streams);\n const subscribe = streams.filter(s => !s.disabled && this._intercomSubscribe(s)).map(stream => ({\n feed: stream.id,\n mid: stream.mid\n }));\n handle.webrtcStuff.subscribeMap = structuredClone(subscribe);\n return this.sendMessage(handle.handleId, {\n body: {\n \"request\": \"join\",\n \"room\": this.roomId,\n \"ptype\": \"subscriber\",\n \"private_id\": this.privateId,\n streams: subscribe,\n //\"feed\": id,\n ...(this.webrtcVersion > 1000 ? {\n id: this.userId\n } : {}),\n pin: this.pin\n }\n });\n }).catch(err => {\n this.emit('error', err);\n });\n }\n }\n } else if (event === \"event\") {\n if (substream !== undefined && substream !== null) {\n this._log('Substream event:', substream, sender);\n }\n if (temporal !== undefined && temporal !== null) {\n this._log('Temporal event:', temporal);\n }\n if (msg[\"streams\"] !== undefined && msg[\"streams\"] !== null) {\n this._log('Got my own streams back', msg[\"streams\"]);\n }\n for (let f in list) {\n let userId = list[f][\"display\"];\n let streams = list[f][\"streams\"] || [];\n let id = list[f][\"id\"];\n for (let i in streams) {\n streams[i][\"id\"] = id;\n streams[i][\"display\"] = userId;\n }\n this._log('Remote userId: ', userId);\n this._pushToRemoteUsersCache(userId, streams, id);\n if (this._participantShouldSubscribe(userId)) {\n let handle = this._getHandle(null, id);\n if (handle) {\n this._updateParticipantsTrackData(handle.handleId, streams);\n let subscribe = streams.filter(stream => !stream.disabled && this._intercomSubscribe(stream) && !this._isAlreadySubscribed(handle.handleId, stream.id, stream.mid)).map(s => ({\n feed: s.id,\n mid: s.mid\n }));\n let unsubscribe = streams.filter(stream => stream.disabled || !this._intercomSubscribe(stream)).map(s => ({\n feed: s.id,\n mid: s.mid\n }));\n this._updateSubscribeMap(handle.handleId, subscribe, unsubscribe);\n this._log('Already subscribed to user: ', userId, 'Update streams', subscribe, unsubscribe);\n if (subscribe.length || unsubscribe.length) {\n this.sendMessage(handle.handleId, {\n body: {\n \"request\": \"update\",\n ...(subscribe.length ? {\n subscribe\n } : {}),\n ...(unsubscribe.length ? {\n unsubscribe\n } : {})\n }\n });\n }\n } else {\n this._log('Creating user: ', userId, streams);\n this._createParticipant(userId, id).then(handle => {\n this._updateParticipantsTrackData(handle.handleId, streams);\n const subscribe = streams.filter(s => !s.disabled && this._intercomSubscribe(s)).map(stream => ({\n feed: stream.id,\n mid: stream.mid\n }));\n handle.webrtcStuff.subscribeMap = structuredClone(subscribe);\n return this.sendMessage(handle.handleId, {\n body: {\n \"request\": \"join\",\n \"room\": this.roomId,\n \"ptype\": \"subscriber\",\n \"private_id\": this.privateId,\n streams: subscribe,\n ...(this.webrtcVersion > 1000 ? {\n id: this.userId\n } : {}),\n pin: this.pin\n }\n });\n }).catch(err => {\n this.emit('error', err);\n });\n }\n }\n }\n if (leaving === 'ok') {\n this._log('leaving', this.handleId, 'this is us');\n this._removeParticipant(this.handleId);\n if (msg['reason'] === 'kicked') {\n this.emit('kicked');\n this.disconnect().catch(() => {});\n }\n } else if (leaving) {\n //TODO: in 1 PeerConnection case we only unsubscribe from streams, this may not be true, check janus docs\n this._log('leaving', leaving);\n this._removeFromRemoteUsersCache(leaving);\n this._removeParticipant(null, leaving, true);\n }\n if (unpublished === 'ok') {\n this._log('unpublished', this.handleId, 'this is us');\n this._removeParticipant(this.handleId, null, false); // we do just hangup\n } else if (unpublished) {\n //TODO: in 1 PeerConnection case we only unsubscribe from streams\n this._log('unpublished', unpublished);\n this._removeFromRemoteUsersCache(unpublished);\n this._removeParticipant(null, unpublished, true); // we do hangup and detach\n }\n\n if (kicked === 'ok') {\n // this case shouldn't exist\n } else if (kicked) {\n this._log('kicked', kicked);\n this._removeFromRemoteUsersCache(kicked);\n this._removeParticipant(null, kicked, true); // we do hangup and detach\n }\n\n if (error) {\n this.emit('error', {\n type: 'error',\n id: 7,\n message: 'local participant error',\n data: [sender, msg]\n });\n }\n }\n\n // Streaming related\n else if (result && result[\"status\"]) {\n this.emit('streamingStatus', result[\"status\"]);\n if (result[\"status\"] === 'stopped') {\n this.stopStream();\n }\n if (result[\"status\"] === 'started') {\n this.emit('streaming', true);\n this.isStreaming = true;\n }\n }\n if (jsep !== undefined && jsep !== null) {\n if (this.sessiontype === 'reactooroom') {\n this._webrtcPeer(this.handleId, jsep).catch(err => {\n this.emit('error', err);\n });\n } else if (this.sessiontype === 'streaming') {\n this._publishRemote(this.handleId, jsep).catch(err => {\n this.emit('error', err);\n });\n }\n }\n } else if (type === \"webrtcup\") {\n if (this.simulcast) {\n return;\n }\n this._log('Configuring bitrate: ' + this.initialBitrate);\n if (this.initialBitrate > 0) {\n this.sendMessage(this.handleId, {\n \"body\": {\n \"request\": \"configure\",\n \"bitrate\": this.initialBitrate\n }\n }).catch(() => null);\n }\n }\n }\n\n //REMOTE\n else {\n let plugindata = json[\"plugindata\"] || {};\n let msg = plugindata[\"data\"] || {};\n let jsep = json[\"jsep\"];\n let event = msg[\"videoroom\"];\n let error = msg[\"error\"];\n let substream = msg[\"substream\"];\n let mid = msg[\"mid\"];\n let temporal = msg[\"temporal\"];\n if (substream !== undefined && substream !== null) {\n this._log('Substream: ', sender, mid, substream);\n this._setSelectedSubstream(sender, mid, substream);\n this._resetStats(sender, mid);\n this.requestKeyFrame(sender, mid);\n }\n if (temporal !== undefined && temporal !== null) {\n this._log('Temporal: ', temporal);\n }\n if (type === \"webrtcup\") {\n this.requestKeyFrame(handle.handleId);\n }\n if (event === \"updated\") {\n this._log('Remote has updated tracks', msg);\n if (msg[\"streams\"]) {\n this._updateTransceiverMap(handle.handleId, msg[\"streams\"]);\n }\n }\n if (event === \"attached\") {\n var _decodeJanusDisplay5, _decodeJanusDisplay6, _handle$webrtcStuff, _handle$webrtcStuff2, _handle$webrtcStuff3;\n this._log('Remote have successfully joined Room', msg);\n if (msg[\"streams\"]) {\n this._updateTransceiverMap(handle.handleId, msg[\"streams\"] || []);\n }\n this.emit(this._getAddParticipantEventName(handle.handleId), {\n tid: Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"generateUUID\"])(),\n id: handle.handleId,\n userId: (_decodeJanusDisplay5 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay5 === void 0 ? void 0 : _decodeJanusDisplay5.userId,\n role: (_decodeJanusDisplay6 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay6 === void 0 ? void 0 : _decodeJanusDisplay6.role,\n stream: null,\n streamMap: structuredClone((_handle$webrtcStuff = handle.webrtcStuff) === null || _handle$webrtcStuff === void 0 ? void 0 : _handle$webrtcStuff.streamMap),\n tracksMap: structuredClone((_handle$webrtcStuff2 = handle.webrtcStuff) === null || _handle$webrtcStuff2 === void 0 ? void 0 : _handle$webrtcStuff2.tracksMap),\n transceiverMap: structuredClone((_handle$webrtcStuff3 = handle.webrtcStuff) === null || _handle$webrtcStuff3 === void 0 ? void 0 : _handle$webrtcStuff3.transceiverMap),\n source: null,\n track: null,\n adding: false,\n removing: false,\n constructId: this.constructId,\n hasAudioTrack: false,\n hasVideoTrack: false\n });\n }\n if (error) {\n this.emit('error', {\n type: 'warning',\n id: 8,\n message: 'remote participant error',\n data: [sender, msg]\n });\n }\n if (jsep) {\n this._publishRemote(handle.handleId, jsep).catch(err => {\n this.emit('error', err);\n });\n }\n }\n }\n _handleDataEvents(handleId, type, data) {\n let handle = this._getHandle(handleId);\n if (type === 'state') {\n this._log(` - Data channel status - `, `UID: ${handleId}`, `STATUS: ${JSON.stringify(data)}`, `ME: ${handleId === this.handleId}`);\n if (handle) {\n let config = handle.webrtcStuff;\n config.dataChannelOpen = this.defaultDataChannelLabel === (data === null || data === void 0 ? void 0 : data.label) && (data === null || data === void 0 ? void 0 : data.state) === 'open';\n }\n if (handleId === this.handleId && this.defaultDataChannelLabel === (data === null || data === void 0 ? void 0 : data.label)) {\n this._isDataChannelOpen = (data === null || data === void 0 ? void 0 : data.state) === 'open';\n this.emit('dataChannel', (data === null || data === void 0 ? void 0 : data.state) === 'open');\n }\n }\n if (type === 'error') {\n this.emit('error', {\n type: 'warning',\n id: 9,\n message: 'data event warning',\n data: [handleId, data]\n });\n if (handle) {\n let config = handle.webrtcStuff;\n if (this.defaultDataChannelLabel === data.label) {\n config.dataChannelOpen = false;\n }\n }\n if (handleId === this.handleId && this.defaultDataChannelLabel === data.label) {\n this._isDataChannelOpen = false;\n this.emit('dataChannel', false);\n }\n }\n if (handleId === this.handleId && type === 'message') {\n let d = null;\n try {\n d = JSON.parse(data);\n } catch (e) {\n this.emit('error', {\n type: 'warning',\n id: 10,\n message: 'data message parse error',\n data: [handleId, e]\n });\n return;\n }\n this.emit('data', d);\n }\n }\n\n //removeHandle === true -> hangup, detach, removeHandle === false -> hangup\n _removeParticipant(handleId, rfid) {\n let removeHandle = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;\n let handle = this._getHandle(handleId, rfid);\n if (!handle) {\n return Promise.resolve();\n } else {\n handleId = handle.handleId;\n }\n return this._send({\n \"janus\": \"hangup\",\n \"handle_id\": handleId\n }, true).then(() => removeHandle ? this._send({\n \"janus\": \"detach\",\n \"handle_id\": handleId\n }, true) : Promise.resolve()).finally(() => {\n try {\n if (handle.webrtcStuff.stream) {\n if (!this.isRestarting) {\n var _handle$webrtcStuff$s;\n (_handle$webrtcStuff$s = handle.webrtcStuff.stream) === null || _handle$webrtcStuff$s === void 0 ? void 0 : _handle$webrtcStuff$s.getTracks().forEach(track => track.stop());\n } else {\n var _handle$webrtcStuff$s2;\n (_handle$webrtcStuff$s2 = handle.webrtcStuff.stream) === null || _handle$webrtcStuff$s2 === void 0 ? void 0 : _handle$webrtcStuff$s2.getTracks().forEach(track => track.onended = null);\n }\n }\n } catch (e) {\n // Do nothing\n }\n if (handle.webrtcStuff.stream) {\n handle.webrtcStuff.stream.onremovetrack = null;\n handle.webrtcStuff.stream = null;\n }\n if (handle.webrtcStuff.dataChannel) {\n Object.keys(handle.webrtcStuff.dataChannel).forEach(label => {\n handle.webrtcStuff.dataChannel[label].onmessage = null;\n handle.webrtcStuff.dataChannel[label].onopen = null;\n handle.webrtcStuff.dataChannel[label].onclose = null;\n handle.webrtcStuff.dataChannel[label].onerror = null;\n });\n }\n if (handle.webrtcStuff.pc) {\n handle.webrtcStuff.pc.onicecandidate = null;\n handle.webrtcStuff.pc.ontrack = null;\n handle.webrtcStuff.pc.ondatachannel = null;\n handle.webrtcStuff.pc.onconnectionstatechange = null;\n handle.webrtcStuff.pc.oniceconnectionstatechange = null;\n }\n try {\n handle.webrtcStuff.pc.close();\n } catch (e) {}\n handle.webrtcStuff = {\n stream: null,\n streamMap: {},\n tracksMap: [],\n transceiverMap: [],\n subscribeMap: [],\n mySdp: null,\n mediaConstraints: null,\n pc: null,\n dataChannelOpen: false,\n dataChannel: null,\n dtmfSender: null,\n trickle: true,\n iceDone: false,\n isIceRestarting: false,\n stats: {},\n selectedSubstream: {},\n initialSimulcastSubstreamBeenSet: {},\n forcedBrowserControlledMode: {}\n };\n if (handleId === this.handleId) {\n var _decodeJanusDisplay7, _decodeJanusDisplay8;\n this._isDataChannelOpen = false;\n this.isPublished = false;\n this.emit('published', {\n status: false,\n hasStream: false\n });\n this.emit('removeLocalParticipant', {\n id: handleId,\n userId: (_decodeJanusDisplay7 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay7 === void 0 ? void 0 : _decodeJanusDisplay7.userId,\n role: (_decodeJanusDisplay8 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay8 === void 0 ? void 0 : _decodeJanusDisplay8.role\n });\n } else {\n var _decodeJanusDisplay9, _decodeJanusDisplay10;\n this.emit(this._getRemoveParticipantEventName(handleId), {\n id: handleId,\n userId: (_decodeJanusDisplay9 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay9 === void 0 ? void 0 : _decodeJanusDisplay9.userId,\n role: (_decodeJanusDisplay10 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay10 === void 0 ? void 0 : _decodeJanusDisplay10.role\n });\n }\n if (removeHandle) {\n let handleIndex = this._participants.findIndex(p => p.handleId === handleId);\n this._participants.splice(handleIndex, 1);\n }\n return true;\n });\n }\n _createParticipant() {\n let userId = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;\n let rfid = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;\n return this._send({\n \"janus\": \"attach\",\n \"plugin\": this.pluginName\n }).then(json => {\n let handleId = json.data[\"id\"];\n let handle = {\n handleId,\n rfid,\n userId,\n webrtcStuff: {\n stream: null,\n streamMap: {},\n tracksMap: [],\n transceiverMap: [],\n subscribeMap: [],\n mySdp: null,\n mediaConstraints: null,\n pc: null,\n dataChannelOpen: false,\n dataChannel: null,\n dtmfSender: null,\n trickle: true,\n iceDone: false,\n isIceRestarting: false,\n stats: {},\n selectedSubstream: {},\n initialSimulcastSubstreamBeenSet: {},\n forcedBrowserControlledMode: {}\n }\n };\n this._participants.push(handle);\n return handle;\n });\n }\n _updateSubscribeMap(handleId, subscribe, unsubscribe) {\n let handle = this._getHandle(handleId);\n if (!handle) {\n this.emit('error', {\n type: 'warning',\n id: 15,\n message: 'id non-existent',\n data: [handleId, 'updateSubscribeMap']\n });\n return;\n }\n let currentSubscribeMap = handle.webrtcStuff.subscribeMap;\n subscribe.forEach(s => {\n if (!currentSubscribeMap.find(c => c.feed === s.feed && c.mid === s.mid)) {\n currentSubscribeMap.push(s);\n }\n });\n unsubscribe.forEach(s => {\n let index = currentSubscribeMap.findIndex(c => c.feed === s.feed && c.mid === s.mid);\n if (index > -1) {\n currentSubscribeMap.splice(index, 1);\n }\n });\n }\n _isAlreadySubscribed(handleId, feed, mid) {\n let handle = this._getHandle(handleId);\n if (!handle) {\n this.emit('error', {\n type: 'warning',\n id: 15,\n message: 'id non-existent',\n data: [handleId, 'isAlreadySubscribed']\n });\n return false;\n }\n return handle.webrtcStuff.subscribeMap.findIndex(t => t.mid === mid && t.feed === feed) > -1;\n }\n _updateTransceiverMap(handleId, streams) {\n this._log('Updating current transceiver map', handleId, streams);\n let handle = this._getHandle(handleId);\n if (!handle) {\n this.emit('error', {\n type: 'warning',\n id: 15,\n message: 'id non-existent',\n data: [handleId, 'updateTransceiverMap']\n });\n return;\n }\n let config = handle.webrtcStuff;\n config.transceiverMap = structuredClone(streams);\n }\n _updateParticipantsTrackData(handleId, streams) {\n this._log('Updating participants track data', handleId, streams);\n let handle = this._getHandle(handleId);\n if (!handle) {\n this.emit('error', {\n type: 'warning',\n id: 15,\n message: 'id non-existent',\n data: [handleId, 'updateParticipantsTrackData']\n });\n return;\n }\n let config = handle.webrtcStuff;\n config.tracksMap = structuredClone(streams.map(s => {\n let source = null;\n let simulcastBitrates = null;\n try {\n const description = JSON.parse(s.description);\n source = description === null || description === void 0 ? void 0 : description.source;\n simulcastBitrates = description === null || description === void 0 ? void 0 : description.simulcastBitrates;\n } catch (e) {}\n return {\n active: !s.disabled,\n description: s.description,\n source: source,\n simulcastBitrates: simulcastBitrates,\n display: s.display,\n id: s.id,\n mid: s.mid,\n mindex: s.mindex,\n codec: s.codec,\n type: s.type\n };\n }));\n }\n _updateRemoteParticipantStreamMap(handleId) {\n this._log('Updating participants stream map', handleId);\n let handle = this._getHandle(handleId);\n if (!handle) {\n this.emit('error', {\n type: 'warning',\n id: 15,\n message: 'id non-existent',\n data: [handleId, 'updateRemoteParticipantStreamMap']\n });\n return;\n }\n let config = handle.webrtcStuff;\n config.streamMap = {};\n config.transceiverMap.forEach(tItem => {\n var _JSON$parse2, _config$pc$getTransce, _config$pc$getTransce2, _config$pc$getTransce3;\n if (tItem.type === 'data') {\n return;\n }\n if (tItem.active === false) {\n return;\n }\n const source = (_JSON$parse2 = JSON.parse(tItem.feed_description)) === null || _JSON$parse2 === void 0 ? void 0 : _JSON$parse2.source;\n if (!config.streamMap[source]) {\n config.streamMap[source] = [];\n }\n let trackId = (_config$pc$getTransce = config.pc.getTransceivers().find(t => t.mid === tItem.mid)) === null || _config$pc$getTransce === void 0 ? void 0 : (_config$pc$getTransce2 = _config$pc$getTransce.receiver) === null || _config$pc$getTransce2 === void 0 ? void 0 : (_config$pc$getTransce3 = _config$pc$getTransce2.track) === null || _config$pc$getTransce3 === void 0 ? void 0 : _config$pc$getTransce3.id;\n if (trackId) {\n config.streamMap[source].push(trackId);\n }\n });\n }\n _joinRoom(roomId, pin, userId, display) {\n return this.sendMessage(this.handleId, {\n body: {\n \"request\": \"join\",\n \"room\": roomId,\n \"pin\": pin,\n \"ptype\": \"publisher\",\n \"display\": display,\n ...(this.webrtcVersion > 1000 ? {\n id: userId\n } : {})\n }\n }, false, true);\n }\n _watchStream(id) {\n return this.sendMessage(this.handleId, {\n body: {\n \"request\": \"watch\",\n id: String(id)\n }\n }, false, true);\n }\n _leaveRoom() {\n let dontWait = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;\n return this.isConnected ? this.sendMessage(this.handleId, {\n body: {\n \"request\": \"leave\"\n }\n }, dontWait).finally(() => {\n this.isConnected = false;\n this.emit('joined', false);\n }) : Promise.resolve();\n }\n\n // internal reconnect\n\n _reconnect() {\n if (this.isReclaiming) {\n return Promise.resolve();\n }\n if (this.ws) {\n this._wipeListeners();\n if (this.ws.readyState === 1) {\n this.ws.close();\n }\n }\n this._stopKeepAlive();\n this.isReclaiming = true;\n this.emit('joining', true);\n return new Promise((resolve, reject) => {\n let abortReconnect = () => {\n this._abortController.signal.removeEventListener('abort', abortReconnect);\n this.ws.removeEventListener('close', this.__connectionClosedBoundFn);\n this.ws.removeEventListener('message', this.__handleWsEventsBoundFn);\n this.ws.onopen = null;\n this.ws.onerror = null;\n this.isReclaiming = false;\n this.emit('joining', false);\n reject({\n type: 'warning',\n id: 17,\n message: 'Connection cancelled',\n data: e\n });\n };\n this.ws = new WebSocket(this.server, 'janus-protocol');\n this.__connectionClosedBoundFn = this._connectionClosed.bind(this);\n this.__handleWsEventsBoundFn = this._handleWsEvents.bind(this);\n this.ws.addEventListener('close', this.__connectionClosedBoundFn);\n this.ws.addEventListener('message', this.__handleWsEventsBoundFn);\n this.ws.onopen = () => {\n this._abortController.signal.removeEventListener('abort', abortReconnect);\n this._send({\n \"janus\": \"claim\"\n }).then(json => {\n this.sessionId = json[\"session_id\"] ? json[\"session_id\"] : json.data[\"id\"];\n this._startKeepAlive();\n this.isReclaiming = false;\n this.emit('joining', false);\n this._retries = 0;\n resolve(json);\n }).catch(error => {\n this.isReclaiming = false;\n this.emit('joining', false);\n reject({\n type: 'error',\n id: 11,\n message: 'reconnection error',\n data: error\n });\n });\n };\n\n // this is called before 'close' event callback so it doesn't break reconnect loop\n this.ws.onerror = e => {\n this._abortController.signal.removeEventListener('abort', abortReconnect);\n this.isReclaiming = false;\n this.emit('joining', false);\n reject({\n type: 'warning',\n id: 12,\n message: 'ws reconnection error',\n data: e\n });\n };\n this._abortController.signal.addEventListener('abort', abortReconnect);\n });\n }\n connect(roomId, pin, server, iceServers, token, display, userId) {\n let webrtcVersion = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : 0;\n let initialBitrate = arguments.length > 8 && arguments[8] !== undefined ? arguments[8] : 0;\n let recordingFilename = arguments.length > 9 ? arguments[9] : undefined;\n let simulcast = arguments.length > 10 && arguments[10] !== undefined ? arguments[10] : false;\n let simulcastBitrates = arguments.length > 11 && arguments[11] !== undefined ? arguments[11] : this.simulcastBitrates;\n let simulcastMode = arguments.length > 12 && arguments[12] !== undefined ? arguments[12] : this.simulcastMode;\n let simulcastDefaultManualSubstream = arguments.length > 13 && arguments[13] !== undefined ? arguments[13] : this.simulcastDefaultManualSubstream;\n let enableDtx = arguments.length > 14 && arguments[14] !== undefined ? arguments[14] : false;\n if (this.isConnecting) {\n return Promise.reject({\n type: 'warning',\n id: 16,\n message: 'connection already in progress'\n });\n }\n if (this.ws) {\n this._wipeListeners();\n }\n this._stopKeepAlive();\n this._abortController = new AbortController();\n this.sessionId = null;\n this.server = server;\n this.iceServers = iceServers;\n this.token = token;\n this.roomId = roomId;\n this.pin = pin;\n this.display = display;\n this.userId = userId;\n this.webrtcVersion = webrtcVersion;\n this.initialBitrate = initialBitrate;\n this.recordingFilename = recordingFilename;\n this.isConnecting = true;\n this.enableDtx = enableDtx;\n this.simulcast = simulcast;\n this.simulcastMode = simulcastMode;\n this.simulcastDefaultManualSubstream = simulcastDefaultManualSubstream;\n if (simulcastBitrates !== null) {\n this.simulcastBitrates = structuredClone(simulcastBitrates).sort((a, b) => {\n if (a.maxBitrate === b.maxBitrate) {\n return a.maxFramerate - b.maxFramerate;\n }\n return a.maxBitrate - b.maxBitrate;\n });\n }\n this.emit('joining', true);\n return new Promise((resolve, reject) => {\n this.ws = new WebSocket(this.server, 'janus-protocol');\n this.__connectionClosedBoundFn = this._connectionClosed.bind(this);\n this.__handleWsEventsBoundFn = this._handleWsEvents.bind(this);\n let abortConnect = () => {\n this._abortController.signal.removeEventListener('abort', abortConnect);\n this.ws.removeEventListener('close', this.__connectionClosedBoundFn);\n this.ws.removeEventListener('message', this.__handleWsEventsBoundFn);\n this.ws.onopen = null;\n this.ws.onerror = null;\n this.isConnecting = false;\n this.emit('joining', false);\n reject({\n type: 'warning',\n id: 17,\n message: 'Connection cancelled'\n });\n };\n this.ws.addEventListener('close', this.__connectionClosedBoundFn);\n this.ws.addEventListener('message', this.__handleWsEventsBoundFn);\n this.ws.onopen = () => {\n this._abortController.signal.removeEventListener('abort', abortConnect);\n this._retries = 0;\n this._send({\n \"janus\": \"create\"\n }).then(json => {\n this.sessionId = json[\"session_id\"] ? json[\"session_id\"] : json.data[\"id\"];\n this._startKeepAlive();\n return 1;\n }).then(() => this._createParticipant(userId)).then(handle => {\n this.handleId = handle.handleId;\n return 1;\n }).then(() => this._joinRoom(roomId, pin, userId, display)).then(() => {\n this._enableStatsWatch();\n this._enableSubstreamAutoSelect();\n this.isConnecting = false;\n this.emit('joining', false);\n resolve(this);\n }).catch(error => {\n this.isConnecting = false;\n this.emit('joining', false);\n reject({\n type: (error === null || error === void 0 ? void 0 : error.type) === 'warning' ? 'warning' : 'error',\n id: 13,\n message: 'connection error',\n data: error\n });\n });\n };\n this.ws.onerror = e => {\n this._abortController.signal.removeEventListener('abort', abortConnect);\n this.isConnecting = false;\n this.emit('joining', false);\n reject({\n type: 'error',\n id: 14,\n message: 'ws connection error',\n data: e\n });\n };\n this._abortController.signal.addEventListener('abort', abortConnect);\n });\n }\n disconnect() {\n var _this$_abortControlle, _this$_abortControlle2;\n if (this.isDisconnecting) {\n return Promise.resolve();\n }\n (_this$_abortControlle = this._abortController) === null || _this$_abortControlle === void 0 ? void 0 : (_this$_abortControlle2 = _this$_abortControlle.abort) === null || _this$_abortControlle2 === void 0 ? void 0 : _this$_abortControlle2.call(_this$_abortControlle);\n this.isDisconnecting = true;\n this._stopKeepAlive();\n this._disableStatsWatch();\n this._disableSubstreamAutoSelect();\n let isConnected = this.isConnected;\n return Promise.all(this._participants.map(p => this._removeParticipant(p.handleId))).finally(() => {\n this._wipeListeners();\n if (this.ws && this.ws.readyState === 1) {\n this._send({\n \"janus\": \"destroy\"\n }, true);\n this.ws.close();\n }\n this.sessionId = null;\n this.isPublished = false;\n this.isConnected = false;\n this.isDisconnecting = false;\n this.emit('publishing', false);\n this.emit('published', {\n status: false,\n hasStream: false\n });\n this.emit('joining', false);\n this.emit('joined', false);\n this.emit('disconnect', isConnected);\n return Promise.resolve('Disconnected');\n });\n }\n startStream(streamId, server, iceServers, token, userId) {\n if (this.isConnecting) {\n return Promise.reject({\n type: 'warning',\n id: 16,\n message: 'connection error',\n data: 'Connection is in progress'\n });\n }\n if (this.ws) {\n this._wipeListeners();\n }\n this._stopKeepAlive();\n this._abortController = new AbortController();\n this.server = server;\n this.iceServers = iceServers;\n this.token = token;\n this.streamId = streamId;\n this.userId = userId;\n this.sessionId = null;\n this.isConnecting = true;\n this.emit('streamStarting', true);\n return new Promise((resolve, reject) => {\n this.ws = new WebSocket(this.server, 'janus-protocol');\n this.__connectionClosedBoundFn = this._connectionClosed.bind(this);\n this.__handleWsEventsBoundFn = this._handleWsEvents.bind(this);\n let abortConnect = () => {\n this._abortController.signal.removeEventListener('abort', abortConnect);\n this.ws.removeEventListener('close', this.__connectionClosedBoundFn);\n this.ws.removeEventListener('message', this.__handleWsEventsBoundFn);\n this.ws.onopen = null;\n this.ws.onerror = null;\n this.isConnecting = false;\n this.emit('streamStarting', false);\n reject({\n type: 'warning',\n id: 17,\n message: 'Connection cancelled'\n });\n };\n this.ws.addEventListener('close', this.__connectionClosedBoundFn);\n this.ws.addEventListener('message', this.__handleWsEventsBoundFn);\n this.ws.onopen = () => {\n this._abortController.signal.removeEventListener('abort', abortConnect);\n this._retries = 0;\n this._send({\n \"janus\": \"create\"\n }).then(json => {\n this.sessionId = json[\"session_id\"] ? json[\"session_id\"] : json.data[\"id\"];\n this._startKeepAlive();\n return 1;\n }).then(() => this._createParticipant(userId)).then(handle => {\n this.handleId = handle.handleId;\n return 1;\n }).then(() => this._watchStream(streamId)).then(() => {\n this.isConnecting = false;\n this.emit('streamStarting', false);\n resolve(this);\n }).catch(error => {\n this.isConnecting = false;\n this.emit('streamStarting', false);\n reject({\n type: 'error',\n id: 13,\n message: 'connection error',\n data: error\n });\n });\n };\n this.ws.onerror = e => {\n this._abortController.signal.removeEventListener('abort', abortConnect);\n this.isConnecting = false;\n this.emit('streamStarting', false);\n reject({\n type: 'error',\n id: 14,\n message: 'ws connection error',\n data: e\n });\n };\n this._abortController.signal.addEventListener('abort', abortConnect);\n });\n }\n stopStream() {\n var _this$_abortControlle3, _this$_abortControlle4;\n if (this.isDisconnecting) {\n return Promise.resolve();\n }\n (_this$_abortControlle3 = this._abortController) === null || _this$_abortControlle3 === void 0 ? void 0 : (_this$_abortControlle4 = _this$_abortControlle3.abort) === null || _this$_abortControlle4 === void 0 ? void 0 : _this$_abortControlle4.call(_this$_abortControlle3);\n this._stopKeepAlive();\n let isStreaming = this.isStreaming;\n this.isDisconnecting = true;\n return this._removeParticipant(this.handleId).finally(() => {\n this.sendMessage(this.handleId, {\n body: {\n \"request\": \"stop\"\n }\n }, true);\n this._wipeListeners();\n this._send({\n \"janus\": \"destroy\"\n }, true);\n if (this.ws && this.ws.readyState === 1) {\n this.ws.close();\n }\n this.sessionId = null;\n this.isDisconnecting = false;\n this.isStreaming = false;\n this.emit('streamStarting', false);\n this.emit('streaming', false);\n this.emit('disconnect', isStreaming);\n return Promise.resolve('Disconnected');\n });\n }\n destroy() {\n if (this.sessiontype === 'reactooroom') {\n return this.disconnect().then(() => {\n this.clear();\n return true;\n });\n } else if (this.sessiontype === 'streaming') {\n return this.stopStream().then(() => {\n this.clear();\n return true;\n });\n }\n }\n _enableDebug() {\n this._log = console.log.bind(console);\n }\n _getHandle(handleId) {\n let rfid = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;\n let userId = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;\n return this._participants.find(p => {\n var _decodeJanusDisplay11;\n return p.handleId === handleId || rfid && p.rfid === rfid || userId && ((_decodeJanusDisplay11 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(p.userId)) === null || _decodeJanusDisplay11 === void 0 ? void 0 : _decodeJanusDisplay11.userId) === userId;\n });\n }\n _disableStatsWatch() {\n if (this._statsTimeoutId) {\n clearInterval(this._statsTimeout);\n this._statsTimeoutStopped = true;\n this._statsTimeoutId = null;\n }\n }\n _enableStatsWatch() {\n if (this._statsTimeoutId) {\n clearTimeout(this._statsTimeoutId);\n this._statsTimeoutId = null;\n }\n this._statsTimeoutStopped = false;\n const loop = () => {\n let startTime = performance.now();\n let endTime = null;\n this._getStats('video').then(participantsStats => {\n endTime = performance.now();\n this._parseVideoStats(participantsStats);\n }).finally(() => {\n if (!this._statsTimeoutStopped) {\n this._statsTimeoutId = setTimeout(loop, this._statsInterval - Math.min(endTime - startTime, this._statsInterval));\n }\n });\n };\n loop();\n }\n\n // This method completely ignores temporal layers\n // We prefer higher fps and lower resolution so if the fps in not in the range of 0.7 of the max fps we go to the next lower resolution\n\n _enableSubstreamAutoSelect() {\n if (!this.simulcast) {\n return;\n }\n if (this._aqTimeoutId) {\n clearTimeout(this._aqTimeoutId);\n this._aqTimeoutId = null;\n }\n this._aqTimeoutId = setInterval(() => {\n this._participants.forEach(p => {\n if (p.handleId !== this.handleId) {\n var _p$webrtcStuff, _p$webrtcStuff$pc, _transceivers$filter;\n const transceivers = (_p$webrtcStuff = p.webrtcStuff) === null || _p$webrtcStuff === void 0 ? void 0 : (_p$webrtcStuff$pc = _p$webrtcStuff.pc) === null || _p$webrtcStuff$pc === void 0 ? void 0 : _p$webrtcStuff$pc.getTransceivers();\n const mids = (transceivers === null || transceivers === void 0 ? void 0 : (_transceivers$filter = transceivers.filter(t => t.receiver.track.kind === \"video\")) === null || _transceivers$filter === void 0 ? void 0 : _transceivers$filter.map(t => t.mid)) || [];\n mids.forEach(mid => {\n const {\n source,\n simulcastBitrates\n } = p.webrtcStuff.tracksMap.find(t => t.mid === mid) || {};\n if (!simulcastBitrates) {\n return;\n }\n const initialSubstreamBeenSet = !!p.webrtcStuff.initialSimulcastSubstreamBeenSet[mid];\n const defaultSelectedSubstream = typeof this.simulcastDefaultManualSubstream === 'object' ? this.simulcastDefaultManualSubstream[source] !== undefined ? this.simulcastDefaultManualSubstream[source] : this.simulcastDefaultManualSubstream['default'] : this.simulcastDefaultManualSubstream;\n const simulcastMode = typeof this.simulcastMode === 'object' ? this.simulcastMode[source] !== undefined ? this.simulcastMode[source] : this.simulcastMode['default'] : this.simulcastMode;\n if (simulcastMode === 'browserControlled' || p.webrtcStuff.forcedBrowserControlledMode[mid]) {\n // do nothing\n } else if (simulcastMode === 'manual' || !initialSubstreamBeenSet) {\n p.webrtcStuff.initialSimulcastSubstreamBeenSet[mid] = true;\n const currentSubstream = p.webrtcStuff.selectedSubstream[mid];\n if (defaultSelectedSubstream !== undefined && defaultSelectedSubstream !== null && defaultSelectedSubstream !== currentSubstream) {\n this._log('Attempting to force substream quality', defaultSelectedSubstream);\n this.selectSubStream(p.handleId, defaultSelectedSubstream, undefined, mid, false).catch(reason => this._log(`Changing substream for mid: ${mid} failed. Reason: ${reason}`));\n }\n } else if (simulcastMode === 'controlled') {\n var _p$webrtcStuff2, _p$webrtcStuff2$stats, _p$webrtcStuff2$stats2, _p$webrtcStuff3, _p$webrtcStuff3$stats, _p$webrtcStuff3$stats2;\n const currentSubstream = p.webrtcStuff.selectedSubstream[mid];\n const settingsForCurrentSubstream = simulcastBitrates === null || simulcastBitrates === void 0 ? void 0 : simulcastBitrates[simulcastBitrates.length - 1 - currentSubstream];\n let directionDecision = 0;\n if (((_p$webrtcStuff2 = p.webrtcStuff) === null || _p$webrtcStuff2 === void 0 ? void 0 : (_p$webrtcStuff2$stats = _p$webrtcStuff2.stats) === null || _p$webrtcStuff2$stats === void 0 ? void 0 : (_p$webrtcStuff2$stats2 = _p$webrtcStuff2$stats[mid]) === null || _p$webrtcStuff2$stats2 === void 0 ? void 0 : _p$webrtcStuff2$stats2.length) > this._upStatsLength) {\n const upMedianStats = this._calculateMedianStats(p.webrtcStuff.stats[mid].slice(this._upStatsLength * -1));\n if ((upMedianStats === null || upMedianStats === void 0 ? void 0 : upMedianStats.framesPerSecond) >= Math.floor(((settingsForCurrentSubstream === null || settingsForCurrentSubstream === void 0 ? void 0 : settingsForCurrentSubstream.maxFramerate) || 30) * 0.7) && (upMedianStats === null || upMedianStats === void 0 ? void 0 : upMedianStats.freezeDurationSinceLast) < this._upStatsLength * this._statsInterval * 0.33 / 1000 && (upMedianStats === null || upMedianStats === void 0 ? void 0 : upMedianStats.freezeCountSinceLast) < 3) {\n directionDecision = 1;\n }\n }\n if (((_p$webrtcStuff3 = p.webrtcStuff) === null || _p$webrtcStuff3 === void 0 ? void 0 : (_p$webrtcStuff3$stats = _p$webrtcStuff3.stats) === null || _p$webrtcStuff3$stats === void 0 ? void 0 : (_p$webrtcStuff3$stats2 = _p$webrtcStuff3$stats[mid]) === null || _p$webrtcStuff3$stats2 === void 0 ? void 0 : _p$webrtcStuff3$stats2.length) > this._downStatsLength) {\n const downMedianStats = this._calculateMedianStats(p.webrtcStuff.stats[mid].slice(this._downStatsLength * -1));\n if ((downMedianStats === null || downMedianStats === void 0 ? void 0 : downMedianStats.framesPerSecond) < Math.floor(((settingsForCurrentSubstream === null || settingsForCurrentSubstream === void 0 ? void 0 : settingsForCurrentSubstream.maxFramerate) || 30) * 0.7) || (downMedianStats === null || downMedianStats === void 0 ? void 0 : downMedianStats.freezeDurationSinceLast) > this._downStatsLength * this._statsInterval * 0.33 / 1000 || (downMedianStats === null || downMedianStats === void 0 ? void 0 : downMedianStats.freezeCountSinceLast) > 5 /* || downMedianStats?.jitter > maxJitter(settingsForCurrentSubstream.maxFramerate) */) {\n directionDecision = -1;\n }\n }\n if (directionDecision === -1) {\n if (currentSubstream < simulcastBitrates.length - 1) {\n this._log('Attempting to down the quality for mid: ', mid, ' quality:', currentSubstream + 1);\n this._resetStats(p.handleId, mid);\n this.selectSubStream(p.handleId, currentSubstream + 1, undefined, mid, false).catch(reason => this._log(`Changing substream for mid: ${mid} failed. Reason: ${reason}`));\n }\n } else if (directionDecision === 1) {\n if (currentSubstream > 0) {\n this._log('Attempting to up the quality for mid: ', mid, ' quality:', currentSubstream - 1);\n this._resetStats(p.handleId, mid);\n this.selectSubStream(p.handleId, currentSubstream - 1, undefined, mid, false).catch(reason => this._log(`Changing substream for mid: ${mid} failed. Reason: ${reason}`));\n }\n } else {\n this._log('No quality change for mid: ', mid);\n }\n }\n });\n }\n });\n }, this._aqInterval);\n }\n _disableSubstreamAutoSelect() {\n if (this._aqTimeoutId) {\n clearTimeout(this._aqTimeoutId);\n this._aqTimeoutId = null;\n }\n }\n _calculateMedianStats(stats) {\n let medianStats = {\n framesPerSecond: null,\n jitter: null,\n roundTripTime: null,\n freezeDurationSinceLast: null,\n freezeCountSinceLast: null\n };\n let keys = Object.keys(medianStats);\n keys.forEach(key => {\n if (key === 'freezeDurationSinceLast' || key === 'freezeCountSinceLast') {\n medianStats[key] = stats.reduce((acc, cur) => acc + cur[key], 0);\n }\n // median but ignore first value of stats array\n else {\n let values = stats.map(s => s[key]);\n medianStats[key] = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"median\"])(values);\n }\n });\n medianStats.statsLength = stats.length;\n return medianStats;\n }\n _parseVideoStats(participantsStats) {\n participantsStats.forEach(sourceStats => {\n sourceStats.forEach(participantStats => {\n var _participantStats$han;\n if (participantStats !== null && (participantStats === null || participantStats === void 0 ? void 0 : (_participantStats$han = participantStats.handle) === null || _participantStats$han === void 0 ? void 0 : _participantStats$han.handleId) !== this.handleId) {\n let handle = this._getHandle(participantStats.handle.handleId);\n if (handle) {\n var _decodeJanusDisplay12;\n if (!handle.webrtcStuff.stats[participantStats.mid]) {\n handle.webrtcStuff.stats[participantStats.mid] = [];\n }\n const stats = {\n framesPerSecond: null,\n framesDropped: null,\n totalFreezesDuration: null,\n freezeDurationSinceLast: null,\n freezeCount: null,\n jitter: null,\n packetsLost: null,\n nackCount: null,\n roundTripTime: null,\n width: null,\n height: null,\n networkType: null,\n powerEfficientDecoder: null\n };\n participantStats.stats.forEach(report => {\n if (report.type === 'inbound-rtp' && report.kind === 'video') {\n var _handle$webrtcStuff$s3, _handle$webrtcStuff$s4, _handle$webrtcStuff$s5, _handle$webrtcStuff$s6, _handle$webrtcStuff$s7, _handle$webrtcStuff$s8, _handle$webrtcStuff$s9, _handle$webrtcStuff$s10, _handle$webrtcStuff$s11, _handle$webrtcStuff$s12;\n stats.framesPerSecond = report.framesPerSecond || 0;\n stats.framesDropped = report.framesDropped || 0;\n stats.totalFreezesDuration = report.totalFreezesDuration || 0;\n stats.freezeDurationSinceLast = (report.totalFreezesDuration || 0) - (((_handle$webrtcStuff$s3 = handle.webrtcStuff.stats) === null || _handle$webrtcStuff$s3 === void 0 ? void 0 : (_handle$webrtcStuff$s4 = _handle$webrtcStuff$s3[participantStats.mid]) === null || _handle$webrtcStuff$s4 === void 0 ? void 0 : (_handle$webrtcStuff$s5 = _handle$webrtcStuff$s4[((_handle$webrtcStuff$s6 = handle.webrtcStuff.stats) === null || _handle$webrtcStuff$s6 === void 0 ? void 0 : (_handle$webrtcStuff$s7 = _handle$webrtcStuff$s6[participantStats.mid]) === null || _handle$webrtcStuff$s7 === void 0 ? void 0 : _handle$webrtcStuff$s7.length) - 1]) === null || _handle$webrtcStuff$s5 === void 0 ? void 0 : _handle$webrtcStuff$s5.totalFreezesDuration) || 0);\n stats.freezeCount = report.freezeCount || 0;\n stats.freezeCountSinceLast = (report.freezeCount || 0) - (((_handle$webrtcStuff$s8 = handle.webrtcStuff.stats) === null || _handle$webrtcStuff$s8 === void 0 ? void 0 : (_handle$webrtcStuff$s9 = _handle$webrtcStuff$s8[participantStats.mid]) === null || _handle$webrtcStuff$s9 === void 0 ? void 0 : (_handle$webrtcStuff$s10 = _handle$webrtcStuff$s9[((_handle$webrtcStuff$s11 = handle.webrtcStuff.stats) === null || _handle$webrtcStuff$s11 === void 0 ? void 0 : (_handle$webrtcStuff$s12 = _handle$webrtcStuff$s11[participantStats.mid]) === null || _handle$webrtcStuff$s12 === void 0 ? void 0 : _handle$webrtcStuff$s12.length) - 1]) === null || _handle$webrtcStuff$s10 === void 0 ? void 0 : _handle$webrtcStuff$s10.freezeCount) || 0);\n stats.jitter = report.jitter;\n stats.packetsLost = report.packetsLost;\n stats.nackCount = report.nackCount;\n stats.width = report.frameWidth;\n stats.height = report.frameHeight;\n stats.powerEfficientDecoder = report.powerEfficientDecoder;\n }\n if (report.type === 'candidate-pair') {\n stats.roundTripTime = report.currentRoundTripTime;\n }\n if (report.type === 'local-candidate') {\n stats.networkType = report.networkType;\n }\n stats.selectedSubstream = handle.webrtcStuff.selectedSubstream[participantStats.mid];\n if (handle.webrtcStuff.forcedBrowserControlledMode[participantStats.mid]) {\n stats.simulcastMode = 'browserControlled';\n } else {\n stats.simulcastMode = typeof this.simulcastMode === 'object' ? this.simulcastMode[participantStats.source] !== undefined ? this.simulcastMode[participantStats.source] : this.simulcastMode['default'] : this.simulcastMode;\n }\n });\n\n // pushing stats into handle stats array but keeping only 6 last stats\n handle.webrtcStuff.stats[participantStats.mid].push(stats);\n if (handle.webrtcStuff.stats[participantStats.mid].length > this._statsMaxLength) {\n handle.webrtcStuff.stats[participantStats.mid].shift();\n }\n this.emit('rtcStats', {\n handleId: participantStats.handle.handleId,\n stats,\n userId: (_decodeJanusDisplay12 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(participantStats.handle.userId)) === null || _decodeJanusDisplay12 === void 0 ? void 0 : _decodeJanusDisplay12.userId,\n source: participantStats.source,\n mid: participantStats.mid\n });\n }\n }\n });\n });\n }\n _getStats() {\n let type = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;\n return Promise.all(this._participants.map(participant => {\n let mediaTrack = [];\n if (type === 'video') {\n var _participant$webrtcSt, _participant$webrtcSt2;\n mediaTrack = (participant === null || participant === void 0 ? void 0 : (_participant$webrtcSt = participant.webrtcStuff) === null || _participant$webrtcSt === void 0 ? void 0 : (_participant$webrtcSt2 = _participant$webrtcSt.stream) === null || _participant$webrtcSt2 === void 0 ? void 0 : _participant$webrtcSt2.getVideoTracks()) || [];\n } else if (type === 'audio') {\n var _participant$webrtcSt3, _participant$webrtcSt4;\n mediaTrack = (participant === null || participant === void 0 ? void 0 : (_participant$webrtcSt3 = participant.webrtcStuff) === null || _participant$webrtcSt3 === void 0 ? void 0 : (_participant$webrtcSt4 = _participant$webrtcSt3.stream) === null || _participant$webrtcSt4 === void 0 ? void 0 : _participant$webrtcSt4.getAudioTracks()) || [];\n }\n if (type !== null) {\n var _participant$webrtcSt5, _participant$webrtcSt6;\n const transceivers = participant === null || participant === void 0 ? void 0 : (_participant$webrtcSt5 = participant.webrtcStuff) === null || _participant$webrtcSt5 === void 0 ? void 0 : (_participant$webrtcSt6 = _participant$webrtcSt5.pc) === null || _participant$webrtcSt6 === void 0 ? void 0 : _participant$webrtcSt6.getTransceivers();\n return Promise.all(mediaTrack.map(track => {\n var _transceivers$find;\n const source = Object.keys(participant.webrtcStuff.streamMap).find(s => participant.webrtcStuff.streamMap[s].find(t => t === track.id));\n const mid = (_transceivers$find = transceivers.find(t => {\n var _t$receiver, _t$receiver$track, _t$sender, _t$sender$track;\n return ((_t$receiver = t.receiver) === null || _t$receiver === void 0 ? void 0 : (_t$receiver$track = _t$receiver.track) === null || _t$receiver$track === void 0 ? void 0 : _t$receiver$track.id) === track.id || ((_t$sender = t.sender) === null || _t$sender === void 0 ? void 0 : (_t$sender$track = _t$sender.track) === null || _t$sender$track === void 0 ? void 0 : _t$sender$track.id) === track.id;\n })) === null || _transceivers$find === void 0 ? void 0 : _transceivers$find.mid;\n return participant.webrtcStuff.pc.getStats(track).then(r => ({\n stats: r,\n source,\n mid,\n handle: participant\n })).catch(e => Promise.reject({\n stats: null,\n error: e,\n handle: participant,\n source,\n mid\n }));\n }));\n } else {\n var _participant$webrtcSt7, _participant$webrtcSt8;\n return participant === null || participant === void 0 ? void 0 : (_participant$webrtcSt7 = participant.webrtcStuff) === null || _participant$webrtcSt7 === void 0 ? void 0 : (_participant$webrtcSt8 = _participant$webrtcSt7.pc) === null || _participant$webrtcSt8 === void 0 ? void 0 : _participant$webrtcSt8.getStats(null).then(r => ({\n handle: participant,\n stats: r\n })).catch(e => Promise.reject({\n handle: participant,\n error: e\n }));\n }\n }));\n }\n _resetStats(handleId, mid) {\n let handle = this._getHandle(handleId);\n if (handle) {\n let config = handle.webrtcStuff;\n if (!mid) {\n Object.keys(config.stats).forEach(mid => {\n config.stats[mid] = [config.stats[mid][config.stats[mid].length - 1]];\n });\n } else {\n // clearing stats for the new substream\n if (config.stats[mid]) {\n config.stats[mid] = [config.stats[mid][config.stats[mid].length - 1]];\n }\n }\n }\n }\n _sendTrickleCandidate(handleId, candidate) {\n return this._send({\n \"janus\": \"trickle\",\n \"candidate\": candidate,\n \"handle_id\": handleId\n }, false, false, 5);\n }\n _webrtc(handleId) {\n let enableOntrack = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;\n let handle = this._getHandle(handleId);\n if (!handle) {\n this.emit('error', {\n type: 'error',\n id: 15,\n message: 'id non-existent',\n data: [handleId, 'create rtc connection']\n });\n return;\n }\n let config = handle.webrtcStuff;\n if (!config.pc) {\n let pc_config = {\n \"iceServers\": this.iceServers,\n \"iceTransportPolicy\": 'all',\n \"bundlePolicy\": undefined\n };\n pc_config[\"sdpSemantics\"] = \"unified-plan\";\n let pc_constraints = {};\n if (webrtc_adapter__WEBPACK_IMPORTED_MODULE_0__[\"default\"].browserDetails.browser === \"edge\") {\n // This is Edge, enable BUNDLE explicitly\n pc_config.bundlePolicy = \"max-bundle\";\n }\n\n // pc_config.bundlePolicy = 'balanced';\n // pc_config.iceTransportPolicy = 'relay';\n // pc_config.rtcpMuxPolicy = \"negotiate\";\n\n this._log('new RTCPeerConnection', pc_config, pc_constraints);\n config.pc = new RTCPeerConnection(pc_config, pc_constraints);\n config.pc.onnegotiationneeded = () => {\n this._log('onnegotiationneeded');\n };\n config.pc.onconnectionstatechange = () => {\n if (config.pc.connectionState === 'failed') {\n this._log('connectionState failed');\n this._iceRestart(handleId);\n }\n this.emit('connectionState', [handleId, handleId === this.handleId, config.pc.connectionState]);\n if (handleId !== this.handleId && config.pc.connectionState === 'connected') {\n var _decodeJanusDisplay13, _decodeJanusDisplay14;\n this.emit(this._getAddParticipantEventName(handle.handleId), {\n tid: Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"generateUUID\"])(),\n id: handle.handleId,\n userId: (_decodeJanusDisplay13 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay13 === void 0 ? void 0 : _decodeJanusDisplay13.userId,\n role: (_decodeJanusDisplay14 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay14 === void 0 ? void 0 : _decodeJanusDisplay14.role,\n stream: config.stream,\n streamMap: structuredClone(config.streamMap),\n tracksMap: structuredClone(config.tracksMap),\n transceiverMap: structuredClone(config.transceiverMap),\n track: null,\n source: null,\n constructId: this.constructId,\n adding: false,\n removing: false,\n hasAudioTrack: !!(config.stream && config.stream.getAudioTracks().length),\n hasVideoTrack: !!(config.stream && config.stream.getVideoTracks().length)\n });\n }\n };\n config.pc.oniceconnectionstatechange = () => {\n if (config.pc.iceConnectionState === 'failed') {\n this._log('iceConnectionState failed');\n this._iceRestart(handleId);\n }\n this.emit('iceState', [handleId, handleId === this.handleId, config.pc.iceConnectionState]);\n if (handleId !== this.handleId && (config.pc.iceConnectionState === 'completed' || config.pc.iceConnectionState === 'connected')) {\n var _decodeJanusDisplay15, _decodeJanusDisplay16;\n this.emit(this._getAddParticipantEventName(handle.handleId), {\n tid: Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"generateUUID\"])(),\n id: handle.handleId,\n userId: (_decodeJanusDisplay15 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay15 === void 0 ? void 0 : _decodeJanusDisplay15.userId,\n role: (_decodeJanusDisplay16 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay16 === void 0 ? void 0 : _decodeJanusDisplay16.role,\n stream: config.stream,\n streamMap: structuredClone(config.streamMap),\n tracksMap: structuredClone(config.tracksMap),\n transceiverMap: structuredClone(config.transceiverMap),\n track: null,\n source: null,\n constructId: this.constructId,\n adding: false,\n hasAudioTrack: !!(config.stream && config.stream.getAudioTracks().length),\n hasVideoTrack: !!(config.stream && config.stream.getVideoTracks().length)\n });\n }\n };\n config.pc.onicecandidate = event => {\n if (event.candidate == null || webrtc_adapter__WEBPACK_IMPORTED_MODULE_0__[\"default\"].browserDetails.browser === 'edge' && event.candidate.candidate.indexOf('endOfCandidates') > 0) {\n config.iceDone = true;\n this._sendTrickleCandidate(handleId, {\n \"completed\": true\n }).catch(e => {\n this.emit('error', e);\n });\n } else {\n // JSON.stringify doesn't work on some WebRTC objects anymore\n // See https://code.google.com/p/chromium/issues/detail?id=467366\n var candidate = {\n \"candidate\": event.candidate.candidate,\n \"sdpMid\": event.candidate.sdpMid,\n \"sdpMLineIndex\": event.candidate.sdpMLineIndex\n };\n this._sendTrickleCandidate(handleId, candidate).catch(e => {\n this.emit('error', e);\n });\n }\n };\n if (enableOntrack) {\n config.pc.ontrack = event => {\n var _event$streams, _event$streams$;\n if (!event.streams) return;\n if (!config.stream) {\n config.stream = new MediaStream();\n }\n if (!((_event$streams = event.streams) !== null && _event$streams !== void 0 && (_event$streams$ = _event$streams[0]) !== null && _event$streams$ !== void 0 && _event$streams$.onremovetrack)) {\n event.streams[0].onremovetrack = ev => {\n var _config$stream, _config$pc, _config$pc$getTransce4, _decodeJanusDisplay17, _decodeJanusDisplay18;\n this._log('Remote track removed', ev);\n (_config$stream = config.stream) === null || _config$stream === void 0 ? void 0 : _config$stream.removeTrack(ev.track);\n\n // check if handle still exists\n if (!this._getHandle(handle.handleId)) {\n return;\n }\n this._updateRemoteParticipantStreamMap(handle.handleId);\n let transceiver = (_config$pc = config.pc) === null || _config$pc === void 0 ? void 0 : (_config$pc$getTransce4 = _config$pc.getTransceivers()) === null || _config$pc$getTransce4 === void 0 ? void 0 : _config$pc$getTransce4.find(t => t.receiver.track === ev.track);\n let mid = (transceiver === null || transceiver === void 0 ? void 0 : transceiver.mid) || ev.track.id;\n let source = Object.keys(config.streamMap).find(key => config.streamMap[key].includes(ev.track.id));\n this.emit(this._getAddParticipantEventName(handle.handleId), {\n tid: Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"generateUUID\"])(),\n id: handle.handleId,\n mid,\n constructId: this.constructId,\n userId: (_decodeJanusDisplay17 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay17 === void 0 ? void 0 : _decodeJanusDisplay17.userId,\n role: (_decodeJanusDisplay18 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay18 === void 0 ? void 0 : _decodeJanusDisplay18.role,\n stream: config.stream,\n streamMap: structuredClone(config.streamMap),\n tracksMap: structuredClone(config.tracksMap),\n transceiverMap: structuredClone(config.transceiverMap),\n source,\n track: ev.track,\n adding: false,\n removing: true,\n hasAudioTrack: !!(config.stream && config.stream.getAudioTracks().length),\n hasVideoTrack: !!(config.stream && config.stream.getVideoTracks().length)\n });\n };\n }\n if (event.track) {\n var _config$stream2, _decodeJanusDisplay19, _decodeJanusDisplay20;\n (_config$stream2 = config.stream) === null || _config$stream2 === void 0 ? void 0 : _config$stream2.addTrack(event.track);\n this._updateRemoteParticipantStreamMap(handle.handleId);\n let mid = event.transceiver ? event.transceiver.mid : event.track.id;\n let source = Object.keys(config.streamMap).find(key => config.streamMap[key].includes(event.track.id));\n if (event.track.kind === 'video') {\n this.requestKeyFrame(handle.handleId, mid);\n }\n this.emit(this._getAddParticipantEventName(handle.handleId), {\n tid: Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"generateUUID\"])(),\n mid,\n id: handle.handleId,\n userId: (_decodeJanusDisplay19 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay19 === void 0 ? void 0 : _decodeJanusDisplay19.userId,\n role: (_decodeJanusDisplay20 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay20 === void 0 ? void 0 : _decodeJanusDisplay20.role,\n stream: config.stream,\n streamMap: structuredClone(config.streamMap),\n tracksMap: structuredClone(config.tracksMap),\n transceiverMap: structuredClone(config.transceiverMap),\n source,\n track: event.track,\n constructId: this.constructId,\n adding: true,\n removing: false,\n hasAudioTrack: !!(config.stream && config.stream.getAudioTracks().length),\n hasVideoTrack: !!(config.stream && config.stream.getVideoTracks().length)\n });\n if (event.track.onended) return;\n event.track.onended = ev => {\n var _config$stream3, _config$pc2, _config$pc2$getTransc, _decodeJanusDisplay21, _decodeJanusDisplay22;\n this._log('Remote track ended');\n (_config$stream3 = config.stream) === null || _config$stream3 === void 0 ? void 0 : _config$stream3.removeTrack(ev.target);\n // check if handle still exists\n if (!this._getHandle(handle.handleId)) {\n return;\n }\n this._updateRemoteParticipantStreamMap(handle.handleId);\n let transceiver = (_config$pc2 = config.pc) === null || _config$pc2 === void 0 ? void 0 : (_config$pc2$getTransc = _config$pc2.getTransceivers()) === null || _config$pc2$getTransc === void 0 ? void 0 : _config$pc2$getTransc.find(t => t.receiver.track === ev.target);\n let mid = (transceiver === null || transceiver === void 0 ? void 0 : transceiver.mid) || ev.target.id;\n let source = Object.keys(config.streamMap).find(key => config.streamMap[key].includes(ev.target.id));\n this.emit(this._getAddParticipantEventName(handle.handleId), {\n tid: Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"generateUUID\"])(),\n id: handle.handleId,\n mid,\n constructId: this.constructId,\n userId: (_decodeJanusDisplay21 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay21 === void 0 ? void 0 : _decodeJanusDisplay21.userId,\n role: (_decodeJanusDisplay22 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay22 === void 0 ? void 0 : _decodeJanusDisplay22.role,\n stream: config.stream,\n streamMap: structuredClone(config.streamMap),\n tracksMap: structuredClone(config.tracksMap),\n transceiverMap: structuredClone(config.transceiverMap),\n source,\n track: ev.target,\n adding: false,\n removing: true,\n hasAudioTrack: !!(config.stream && config.stream.getAudioTracks().length),\n hasVideoTrack: !!(config.stream && config.stream.getVideoTracks().length)\n });\n };\n event.track.onmute = ev => {\n var _decodeJanusDisplay23, _decodeJanusDisplay24;\n this._log('Remote track muted');\n let transceiver = config.pc.getTransceivers().find(t => t.receiver.track === ev.target);\n let mid = transceiver.mid || ev.target.id;\n let source = Object.keys(config.streamMap).find(key => config.streamMap[key].includes(ev.target.id));\n this.emit('remoteTrackMuted', {\n id: handle.handleId,\n mid,\n constructId: this.constructId,\n userId: (_decodeJanusDisplay23 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay23 === void 0 ? void 0 : _decodeJanusDisplay23.userId,\n role: (_decodeJanusDisplay24 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay24 === void 0 ? void 0 : _decodeJanusDisplay24.role,\n stream: config.stream,\n streamMap: structuredClone(config.streamMap),\n source,\n kind: ev.target.kind,\n track: ev.target,\n muted: true\n });\n\n // questionable hotfix\n // when a track is muted, we try to switch to lower quality substream\n\n if (!this.simulcast) {\n return;\n }\n const simulcastMode = typeof this.simulcastMode === 'object' ? this.simulcastMode[source] !== undefined ? this.simulcastMode[source] : this.simulcastMode['default'] : this.simulcastMode;\n const {\n simulcastBitrates\n } = handle.webrtcStuff.tracksMap.find(t => t.mid === mid) || {};\n const currentSubstream = handle.webrtcStuff.selectedSubstream[mid];\n if (!(simulcastMode === 'browserControlled' || handle.webrtcStuff.forcedBrowserControlledMode[mid]) && ev.target.kind === 'video' && currentSubstream < simulcastBitrates.length - 1) {\n this.selectSubStream(handle.handleId, currentSubstream + 1, undefined, mid, false).catch(reason => this._log(`Changing substream for mid: ${mid} failed. Reason: ${reason}`));\n }\n };\n event.track.onunmute = ev => {\n var _decodeJanusDisplay25, _decodeJanusDisplay26;\n this._log('Remote track unmuted');\n let transceiver = config.pc.getTransceivers().find(t => t.receiver.track === ev.target);\n let mid = transceiver.mid || ev.target.id;\n let source = Object.keys(config.streamMap).find(key => config.streamMap[key].includes(ev.target.id));\n this.emit('remoteTrackMuted', {\n id: handle.handleId,\n mid,\n constructId: this.constructId,\n userId: (_decodeJanusDisplay25 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay25 === void 0 ? void 0 : _decodeJanusDisplay25.userId,\n role: (_decodeJanusDisplay26 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay26 === void 0 ? void 0 : _decodeJanusDisplay26.role,\n stream: config.stream,\n streamMap: structuredClone(config.streamMap),\n source,\n kind: ev.target.kind,\n track: ev.target,\n muted: false\n });\n };\n }\n };\n }\n }\n if (!config.dataChannel || !config.dataChannelOpen) {\n config.dataChannel = {};\n var onDataChannelMessage = event => {\n this._handleDataEvents(handleId, 'message', event.data);\n };\n var onDataChannelStateChange = event => {\n let label = event.target.label;\n let protocol = event.target.protocol;\n let state = config.dataChannel[label] ? config.dataChannel[label].readyState : \"null\";\n this._handleDataEvents(handleId, 'state', {\n state,\n label\n });\n };\n var onDataChannelError = error => {\n var _error$channel;\n this._handleDataEvents(handleId, 'error', {\n label: error === null || error === void 0 ? void 0 : (_error$channel = error.channel) === null || _error$channel === void 0 ? void 0 : _error$channel.label,\n error\n });\n };\n const createDataChannel = (label, protocol, incoming) => {\n let options = {\n ordered: true\n };\n if (!incoming) {\n if (protocol) {\n options = {\n ...options,\n protocol\n };\n }\n config.dataChannel[label] = config.pc.createDataChannel(label, options);\n } else {\n config.dataChannel[label] = incoming;\n }\n config.dataChannel[label].onmessage = onDataChannelMessage;\n config.dataChannel[label].onopen = onDataChannelStateChange;\n config.dataChannel[label].onclose = onDataChannelStateChange;\n config.dataChannel[label].onerror = onDataChannelError;\n };\n createDataChannel(this.defaultDataChannelLabel, null, null);\n config.pc.ondatachannel = function (event) {\n createDataChannel(event.channel.label, event.channel.protocol, event.channel);\n };\n }\n }\n _webrtcPeer(handleId, jsep) {\n let handle = this._getHandle(handleId);\n if (!handle) {\n return Promise.reject({\n type: 'warning',\n id: 15,\n message: 'id non-existent',\n data: [handleId, 'rtc peer']\n });\n }\n var config = handle.webrtcStuff;\n if (jsep !== undefined && jsep !== null) {\n if (config.pc === null) {\n this._log(\"No PeerConnection: if this is an answer, use createAnswer and not _webrtcPeer\");\n return Promise.resolve(null);\n }\n return config.pc.setRemoteDescription(jsep).then(() => {\n config.remoteSdp = jsep.sdp;\n // Any trickle candidate we cached?\n if (config.candidates && config.candidates.length > 0) {\n for (var i = 0; i < config.candidates.length; i++) {\n var candidate = config.candidates[i];\n if (!candidate || candidate.completed === true) {\n config.pc.addIceCandidate(null);\n } else {\n config.pc.addIceCandidate(candidate);\n }\n }\n config.candidates = [];\n }\n // Done\n return true;\n }).catch(e => {\n return Promise.reject({\n type: 'warning',\n id: 32,\n message: 'rtc peer',\n data: [handleId, e]\n });\n });\n } else {\n return Promise.reject({\n type: 'warning',\n id: 22,\n message: 'rtc peer',\n data: [handleId, 'invalid jsep']\n });\n }\n }\n _iceRestart(handleId) {\n let handle = this._getHandle(handleId);\n if (!handle) {\n return;\n }\n var config = handle.webrtcStuff;\n\n // Already restarting;\n if (config.isIceRestarting) {\n return;\n }\n config.isIceRestarting = true;\n if (this.handleId === handleId) {\n this._log('Performing local ICE restart');\n let hasAudio = !!(config.stream && config.stream.getAudioTracks().length > 0);\n let hasVideo = !!(config.stream && config.stream.getVideoTracks().length > 0);\n this._createAO('offer', handleId, true).then(jsep => {\n if (!jsep) {\n return null;\n }\n return this.sendMessage(handleId, {\n body: {\n \"request\": \"configure\",\n \"keyframe\": true,\n \"audio\": hasAudio,\n \"video\": hasVideo,\n \"data\": true,\n ...(this.recordingFilename ? {\n filename: this.recordingFilename\n } : {})\n },\n jsep\n }, false, false, 5);\n }).then(r => {\n config.isIceRestarting = false;\n this._log('ICE restart success');\n }).catch(e => {\n config.isIceRestarting = false;\n this.emit('error', {\n type: 'warning',\n id: 28,\n message: 'iceRestart failed',\n data: e\n });\n });\n } else {\n this._log('Performing remote ICE restart', handleId);\n return this.sendMessage(handleId, {\n body: {\n \"request\": \"configure\",\n \"restart\": true\n }\n }, false, false, 5).then(() => {}).then(() => {\n config.isIceRestarting = false;\n this._log('ICE restart success');\n }).catch(() => {\n config.isIceRestarting = false;\n });\n }\n }\n _setupTransceivers(handleId, _ref) {\n let [audioSend, audioRecv, videoSend, videoRecv, audioTransceiver = null, videoTransceiver = null] = _ref;\n //TODO: this should be refactored to use handle's trackMap so we dont have to pass any parameters\n\n let handle = this._getHandle(handleId);\n if (!handle) {\n return null;\n }\n let config = handle.webrtcStuff;\n const setTransceiver = function (transceiver, send, recv) {\n let kind = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'audio';\n if (!send && !recv) {\n // disabled: have we removed it?\n if (transceiver) {\n if (transceiver.setDirection) {\n transceiver.setDirection(\"inactive\");\n } else {\n transceiver.direction = \"inactive\";\n }\n }\n } else {\n if (send && recv) {\n if (transceiver) {\n if (transceiver.setDirection) {\n transceiver.setDirection(\"sendrecv\");\n } else {\n transceiver.direction = \"sendrecv\";\n }\n }\n } else if (send && !recv) {\n if (transceiver) {\n if (transceiver.setDirection) {\n transceiver.setDirection(\"sendonly\");\n } else {\n transceiver.direction = \"sendonly\";\n }\n }\n } else if (!send && recv) {\n if (transceiver) {\n if (transceiver.setDirection) {\n transceiver.setDirection(\"recvonly\");\n } else {\n transceiver.direction = \"recvonly\";\n }\n } else {\n // In theory, this is the only case where we might not have a transceiver yet\n config.pc.addTransceiver(kind, {\n direction: \"recvonly\"\n });\n }\n }\n }\n };\n\n // if we're passing any transceivers, we work only on them, doesn't matter if one of them is null\n if (audioTransceiver || videoTransceiver) {\n if (audioTransceiver) {\n setTransceiver(audioTransceiver, audioSend, audioRecv, 'audio');\n }\n if (videoTransceiver) {\n setTransceiver(videoTransceiver, videoSend, videoRecv, 'video');\n }\n }\n // else we work on all transceivers\n else {\n let transceivers = config.pc.getTransceivers();\n if (transceivers && transceivers.length > 0) {\n for (let i in transceivers) {\n let t = transceivers[i];\n if (t.sender && t.sender.track && t.sender.track.kind === \"audio\" || t.receiver && t.receiver.track && t.receiver.track.kind === \"audio\") {\n setTransceiver(t, audioSend, audioRecv, 'audio');\n }\n if (t.sender && t.sender.track && t.sender.track.kind === \"video\" || t.receiver && t.receiver.track && t.receiver.track.kind === \"video\") {\n setTransceiver(t, videoSend, videoRecv, 'video');\n }\n }\n }\n }\n }\n _createAO() {\n let type = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'offer';\n let handleId = arguments.length > 1 ? arguments[1] : undefined;\n let iceRestart = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;\n let handle = this._getHandle(handleId);\n if (!handle) {\n return Promise.reject({\n type: 'warning',\n id: 15,\n message: 'id non-existent',\n data: [handleId, 'createAO', type]\n });\n }\n let methodName = null;\n if (type === 'offer') {\n methodName = 'createOffer';\n } else {\n methodName = 'createAnswer';\n }\n let config = handle.webrtcStuff;\n let mediaConstraints = {};\n if (iceRestart) {\n mediaConstraints[\"iceRestart\"] = true;\n }\n return config.pc[methodName](mediaConstraints).then(response => {\n // if type offer and its me and we want dtx we mungle the sdp\n if (handleId === this.handleId && type === 'offer' && this.enableDtx) {\n // enable DTX\n response.sdp = response.sdp.replace(\"useinbandfec=1\", \"useinbandfec=1;usedtx=1\");\n }\n config.mySdp = response.sdp;\n let _p = config.pc.setLocalDescription(response).catch(e => {\n return Promise.reject({\n type: 'warning',\n id: 24,\n message: 'setLocalDescription',\n data: [handleId, e]\n });\n });\n config.mediaConstraints = mediaConstraints;\n if (!config.iceDone && !config.trickle) {\n // Don't do anything until we have all candidates\n return Promise.resolve(null);\n }\n\n // JSON.stringify doesn't work on some WebRTC objects anymore\n // See https://code.google.com/p/chromium/issues/detail?id=467366\n var jsep = {\n \"type\": response.type,\n \"sdp\": response.sdp\n };\n if (response.e2ee) jsep.e2ee = true;\n if (response.rid_order === \"hml\" || response.rid_order === \"lmh\") jsep.rid_order = response.rid_order;\n if (response.force_relay) jsep.force_relay = true;\n return _p.then(() => jsep);\n }, e => {\n return Promise.reject({\n type: 'warning',\n id: 25,\n message: methodName,\n data: [handleId, e]\n });\n });\n }\n _publishRemote(handleId, jsep) {\n let handle = this._getHandle(handleId);\n if (!handle) {\n return Promise.reject({\n type: 'warning',\n id: 15,\n message: 'id non-existent',\n data: [handleId, 'publish remote participant']\n });\n }\n this._webrtc(handleId, true);\n let config = handle.webrtcStuff;\n if (jsep) {\n return config.pc.setRemoteDescription(jsep).then(() => {\n config.remoteSdp = jsep.sdp;\n // Any trickle candidate we cached?\n if (config.candidates && config.candidates.length > 0) {\n for (var i = 0; i < config.candidates.length; i++) {\n var candidate = config.candidates[i];\n if (!candidate || candidate.completed === true) {\n // end-of-candidates\n config.pc.addIceCandidate(null);\n } else {\n // New candidate\n config.pc.addIceCandidate(candidate);\n }\n }\n config.candidates = [];\n }\n this._setupTransceivers(handleId, [false, true, false, true]);\n\n // Create the answer now\n return this._createAO('answer', handleId, false).then(_jsep => {\n if (!_jsep) {\n this.emit('error', {\n type: 'warning',\n id: 19,\n message: 'publish remote participant',\n data: [handleId, 'no jsep']\n });\n return Promise.resolve();\n }\n return this.sendMessage(handleId, {\n \"body\": {\n \"request\": \"start\",\n ...(this.roomId && {\n \"room\": this.roomId\n }),\n ...(this.pin && {\n pin: this.pin\n })\n },\n \"jsep\": _jsep\n });\n });\n }, e => Promise.reject({\n type: 'warning',\n id: 23,\n message: 'setRemoteDescription',\n data: [handleId, e]\n }));\n } else {\n return Promise.resolve();\n }\n }\n\n //Public methods\n _republishOnTrackEnded(source) {\n let handle = this._getHandle(this.handleId);\n if (!handle) {\n return;\n }\n let config = handle.webrtcStuff;\n if (!config.stream) {\n return;\n }\n let sourceTrackIds = config.streamMap[source] || [];\n let remainingTracks = [];\n for (let i = 0; i < sourceTrackIds.length; i++) {\n let foundTrack = config.stream.getTracks().find(t => t.id === sourceTrackIds[i]);\n if (foundTrack) {\n remainingTracks.push(foundTrack);\n }\n }\n if (remainingTracks.length) {\n let stream = new MediaStream();\n remainingTracks.forEach(track => stream.addTrack(track));\n return this.publishLocal(stream, source);\n } else {\n return this.publishLocal(null, source);\n }\n }\n publishLocal() {\n var _stream$getVideoTrack, _stream$getAudioTrack, _config$stream4, _config$stream4$getAu, _config$stream5, _config$stream5$getVi, _stream$getAudioTrack2, _stream$getVideoTrack2;\n let stream = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;\n let source = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'camera0';\n if (this.isDisconnecting || !this.isConnected) {\n return Promise.reject({\n type: 'warning',\n id: 18,\n message: 'Either not connected or disconnecting'\n });\n }\n if ((stream === null || stream === void 0 ? void 0 : (_stream$getVideoTrack = stream.getVideoTracks()) === null || _stream$getVideoTrack === void 0 ? void 0 : _stream$getVideoTrack.length) > 1) {\n return Promise.reject({\n type: 'warning',\n id: 30,\n message: 'multiple video tracks not supported',\n data: null\n });\n }\n if ((stream === null || stream === void 0 ? void 0 : (_stream$getAudioTrack = stream.getAudioTracks()) === null || _stream$getAudioTrack === void 0 ? void 0 : _stream$getAudioTrack.length) > 1) {\n return Promise.reject({\n type: 'warning',\n id: 30,\n message: 'multiple audio tracks not supported',\n data: null\n });\n }\n let handle = this._getHandle(this.handleId);\n if (!handle) {\n return Promise.reject({\n type: 'error',\n id: 31,\n message: 'no local id, connect before publishing',\n data: null\n });\n }\n this.emit('publishing', true);\n this._webrtc(this.handleId);\n let config = handle.webrtcStuff;\n if (!config.stream) {\n config.stream = new MediaStream();\n }\n let needsNegotiation = !this.isPublished;\n let transceivers = config.pc.getTransceivers();\n let existingTracks = [...(config.streamMap[source] || [])];\n if (stream !== null && stream !== void 0 && stream.getTracks().length) {\n var _stream$getTracks;\n config.streamMap[source] = (stream === null || stream === void 0 ? void 0 : (_stream$getTracks = stream.getTracks()) === null || _stream$getTracks === void 0 ? void 0 : _stream$getTracks.map(track => track.id)) || [];\n } else {\n delete config.streamMap[source];\n }\n\n // remove old audio track related to this source\n let oldAudioStream = config === null || config === void 0 ? void 0 : (_config$stream4 = config.stream) === null || _config$stream4 === void 0 ? void 0 : (_config$stream4$getAu = _config$stream4.getAudioTracks()) === null || _config$stream4$getAu === void 0 ? void 0 : _config$stream4$getAu.find(track => existingTracks.includes(track.id));\n if (oldAudioStream) {\n try {\n oldAudioStream.stop();\n } catch (e) {\n this._log(e);\n }\n config.stream.removeTrack(oldAudioStream);\n }\n\n // remove old video track related to this source\n let oldVideoStream = config === null || config === void 0 ? void 0 : (_config$stream5 = config.stream) === null || _config$stream5 === void 0 ? void 0 : (_config$stream5$getVi = _config$stream5.getVideoTracks()) === null || _config$stream5$getVi === void 0 ? void 0 : _config$stream5$getVi.find(track => existingTracks.includes(track.id));\n if (oldVideoStream) {\n try {\n oldVideoStream.stop();\n } catch (e) {\n this._log(e);\n }\n config.stream.removeTrack(oldVideoStream);\n }\n let audioTrackReplacePromise = Promise.resolve();\n let videoTrackReplacePromise = Promise.resolve();\n let audioTransceiver = null;\n let videoTransceiver = null;\n let replaceAudio = stream === null || stream === void 0 ? void 0 : (_stream$getAudioTrack2 = stream.getAudioTracks()) === null || _stream$getAudioTrack2 === void 0 ? void 0 : _stream$getAudioTrack2.length;\n let replaceVideo = stream === null || stream === void 0 ? void 0 : (_stream$getVideoTrack2 = stream.getVideoTracks()) === null || _stream$getVideoTrack2 === void 0 ? void 0 : _stream$getVideoTrack2.length;\n for (const transceiver of transceivers) {\n var _transceiver$sender, _transceiver$sender$t, _transceiver$sender2, _transceiver$sender2$, _transceiver$sender3, _transceiver$sender3$, _transceiver$sender4, _transceiver$sender4$, _transceiver$sender5, _transceiver$sender5$, _transceiver$sender5$2, _transceiver$sender6, _transceiver$sender6$, _transceiver$sender6$2;\n if (['sendonly', 'sendrecv'].includes(transceiver.currentDirection) && ((_transceiver$sender = transceiver.sender) === null || _transceiver$sender === void 0 ? void 0 : (_transceiver$sender$t = _transceiver$sender.track) === null || _transceiver$sender$t === void 0 ? void 0 : _transceiver$sender$t.kind) === 'audio' && existingTracks.includes((_transceiver$sender2 = transceiver.sender) === null || _transceiver$sender2 === void 0 ? void 0 : (_transceiver$sender2$ = _transceiver$sender2.track) === null || _transceiver$sender2$ === void 0 ? void 0 : _transceiver$sender2$.id)) {\n audioTransceiver = transceiver;\n } else if (['sendonly', 'sendrecv'].includes(transceiver.currentDirection) && ((_transceiver$sender3 = transceiver.sender) === null || _transceiver$sender3 === void 0 ? void 0 : (_transceiver$sender3$ = _transceiver$sender3.track) === null || _transceiver$sender3$ === void 0 ? void 0 : _transceiver$sender3$.kind) === 'video' && existingTracks.includes((_transceiver$sender4 = transceiver.sender) === null || _transceiver$sender4 === void 0 ? void 0 : (_transceiver$sender4$ = _transceiver$sender4.track) === null || _transceiver$sender4$ === void 0 ? void 0 : _transceiver$sender4$.id)) {\n videoTransceiver = transceiver;\n }\n\n // Reusing existing transceivers\n // TODO: if we start using different codecs for different sources, we need to check for that here\n else if (transceiver.currentDirection === 'inactive' && (_transceiver$sender5 = transceiver.sender) !== null && _transceiver$sender5 !== void 0 && (_transceiver$sender5$ = _transceiver$sender5.getParameters()) !== null && _transceiver$sender5$ !== void 0 && (_transceiver$sender5$2 = _transceiver$sender5$.codecs) !== null && _transceiver$sender5$2 !== void 0 && _transceiver$sender5$2.find(c => c.mimeType.indexOf('audio') > -1) && replaceAudio && !audioTransceiver) {\n audioTransceiver = transceiver;\n needsNegotiation = true;\n } else if (transceiver.currentDirection === 'inactive' && (_transceiver$sender6 = transceiver.sender) !== null && _transceiver$sender6 !== void 0 && (_transceiver$sender6$ = _transceiver$sender6.getParameters()) !== null && _transceiver$sender6$ !== void 0 && (_transceiver$sender6$2 = _transceiver$sender6$.codecs) !== null && _transceiver$sender6$2 !== void 0 && _transceiver$sender6$2.find(c => c.mimeType.indexOf('video') > -1) && replaceVideo && !videoTransceiver) {\n videoTransceiver = transceiver;\n needsNegotiation = true;\n }\n }\n if (replaceAudio) {\n config.stream.addTrack(stream.getAudioTracks()[0]);\n if (audioTransceiver && audioTransceiver.sender) {\n audioTrackReplacePromise = audioTransceiver.sender.replaceTrack(stream.getAudioTracks()[0]);\n } else {\n config.pc.addTrack(stream.getAudioTracks()[0], config.stream);\n needsNegotiation = true;\n }\n } else {\n if (audioTransceiver && audioTransceiver.sender) {\n audioTrackReplacePromise = audioTransceiver.sender.replaceTrack(null);\n needsNegotiation = true;\n }\n }\n if (replaceVideo) {\n config.stream.addTrack(stream.getVideoTracks()[0]);\n if (videoTransceiver && videoTransceiver.sender) {\n videoTrackReplacePromise = videoTransceiver.sender.replaceTrack(stream.getVideoTracks()[0]);\n } else {\n if (!this.simulcast) {\n config.pc.addTrack(stream.getVideoTracks()[0], config.stream);\n } else {\n if (webrtc_adapter__WEBPACK_IMPORTED_MODULE_0__[\"default\"].browserDetails.browser !== 'firefox') {\n // standard\n config.pc.addTransceiver(stream.getVideoTracks()[0], {\n direction: 'sendonly',\n streams: [config.stream],\n sendEncodings: structuredClone(this.simulcastBitrates)\n });\n } else {\n // firefox\n let transceiver = config.pc.addTransceiver(stream.getVideoTracks()[0], {\n direction: 'sendonly',\n streams: [config.stream]\n });\n let sender = transceiver ? transceiver.sender : null;\n if (sender) {\n let parameters = sender.getParameters() || {};\n parameters.encodings = stream.getVideoTracks()[0].sendEncodings || structuredClone(this.simulcastBitrates);\n sender.setParameters(parameters);\n }\n }\n }\n needsNegotiation = true;\n }\n } else {\n if (videoTransceiver && videoTransceiver.sender) {\n videoTrackReplacePromise = videoTransceiver.sender.replaceTrack(null);\n needsNegotiation = true;\n }\n }\n this.isAudioEnabed = !!(config.stream && config.stream.getAudioTracks().length > 0);\n this.isVideoEnabled = !!(config.stream && config.stream.getVideoTracks().length > 0);\n\n // we possibly created new transceivers, so we need to get them again\n transceivers = config.pc.getTransceivers();\n existingTracks = [...(config.streamMap[source] || [])];\n if (!audioTransceiver) {\n audioTransceiver = transceivers.find(transceiver => transceiver.sender.track && transceiver.sender.track.kind === 'audio' && existingTracks.includes(transceiver.sender.track.id));\n }\n if (!videoTransceiver) {\n videoTransceiver = transceivers.find(transceiver => transceiver.sender.track && transceiver.sender.track.kind === 'video' && existingTracks.includes(transceiver.sender.track.id));\n }\n let hasAudio = !!(stream && stream.getAudioTracks().length > 0);\n let hasVideo = !!(stream && stream.getVideoTracks().length > 0);\n this._setupTransceivers(this.handleId, [hasAudio, false, hasVideo, false, audioTransceiver, videoTransceiver]);\n const emitEvents = () => {\n var _decodeJanusDisplay27, _decodeJanusDisplay28;\n this.isPublished = true;\n if (!config.stream.onremovetrack) {\n config.stream.onremovetrack = ev => {};\n }\n let republishTimeoutId = null;\n let tracks = config.stream.getTracks();\n this.emit('addLocalParticipant', {\n tid: Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"generateUUID\"])(),\n id: handle.handleId,\n userId: (_decodeJanusDisplay27 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay27 === void 0 ? void 0 : _decodeJanusDisplay27.userId,\n role: (_decodeJanusDisplay28 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(this.display)) === null || _decodeJanusDisplay28 === void 0 ? void 0 : _decodeJanusDisplay28.role,\n stream: tracks.length ? config.stream : null,\n // that null is there due to backward compatibility\n track: null,\n streamMap: structuredClone(config.streamMap),\n source,\n adding: false,\n removing: false,\n constructId: this.constructId,\n hasAudioTrack: hasAudio,\n hasVideoTrack: hasVideo\n });\n if (tracks.length) {\n tracks.forEach(track => {\n // used as a flag to not emit tracks that been already emitted\n if (!track.onended) {\n var _decodeJanusDisplay29, _decodeJanusDisplay30;\n this.emit('addLocalParticipant', {\n tid: Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"generateUUID\"])(),\n id: handle.handleId,\n userId: (_decodeJanusDisplay29 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(handle.userId)) === null || _decodeJanusDisplay29 === void 0 ? void 0 : _decodeJanusDisplay29.userId,\n role: (_decodeJanusDisplay30 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(this.display)) === null || _decodeJanusDisplay30 === void 0 ? void 0 : _decodeJanusDisplay30.role,\n track,\n stream: config.stream,\n streamMap: structuredClone(config.streamMap),\n source,\n adding: true,\n removing: false,\n constructId: this.constructId,\n hasAudioTrack: hasAudio,\n hasVideoTrack: hasVideo\n });\n track.onended = ev => {\n config.stream.removeTrack(track);\n clearTimeout(republishTimeoutId);\n republishTimeoutId = setTimeout(() => {\n this._republishOnTrackEnded(source);\n }, 100);\n };\n }\n });\n }\n this.isMuted = [];\n for (const source of Object.keys(config.streamMap)) {\n var _config$stream6, _config$stream6$getAu, _config$stream7, _config$stream7$getVi, _transceivers$find2, _transceivers$find3;\n const audioTrack = (_config$stream6 = config.stream) === null || _config$stream6 === void 0 ? void 0 : (_config$stream6$getAu = _config$stream6.getAudioTracks()) === null || _config$stream6$getAu === void 0 ? void 0 : _config$stream6$getAu.find(track => config.streamMap[source].includes(track.id));\n const videoTrack = (_config$stream7 = config.stream) === null || _config$stream7 === void 0 ? void 0 : (_config$stream7$getVi = _config$stream7.getVideoTracks()) === null || _config$stream7$getVi === void 0 ? void 0 : _config$stream7$getVi.find(track => config.streamMap[source].includes(track.id));\n this.isMuted.push({\n type: 'audio',\n value: !audioTrack || !audioTrack.enabled,\n source,\n mid: (_transceivers$find2 = transceivers.find(transceiver => {\n var _transceiver$sender7, _transceiver$sender7$, _transceiver$sender8, _transceiver$sender8$;\n return ((_transceiver$sender7 = transceiver.sender) === null || _transceiver$sender7 === void 0 ? void 0 : (_transceiver$sender7$ = _transceiver$sender7.track) === null || _transceiver$sender7$ === void 0 ? void 0 : _transceiver$sender7$.kind) === 'audio' && ((_transceiver$sender8 = transceiver.sender) === null || _transceiver$sender8 === void 0 ? void 0 : (_transceiver$sender8$ = _transceiver$sender8.track) === null || _transceiver$sender8$ === void 0 ? void 0 : _transceiver$sender8$.id) === (audioTrack === null || audioTrack === void 0 ? void 0 : audioTrack.id);\n })) === null || _transceivers$find2 === void 0 ? void 0 : _transceivers$find2.mid\n });\n this.isMuted.push({\n type: 'video',\n value: !videoTrack || !videoTrack.enabled,\n source,\n mid: (_transceivers$find3 = transceivers.find(transceiver => {\n var _transceiver$sender9, _transceiver$sender9$, _transceiver$sender10, _transceiver$sender11;\n return ((_transceiver$sender9 = transceiver.sender) === null || _transceiver$sender9 === void 0 ? void 0 : (_transceiver$sender9$ = _transceiver$sender9.track) === null || _transceiver$sender9$ === void 0 ? void 0 : _transceiver$sender9$.kind) === 'video' && ((_transceiver$sender10 = transceiver.sender) === null || _transceiver$sender10 === void 0 ? void 0 : (_transceiver$sender11 = _transceiver$sender10.track) === null || _transceiver$sender11 === void 0 ? void 0 : _transceiver$sender11.id) === (videoTrack === null || videoTrack === void 0 ? void 0 : videoTrack.id);\n })) === null || _transceivers$find3 === void 0 ? void 0 : _transceivers$find3.mid\n });\n this.emit('localHasVideo', !!videoTrack, source);\n this.emit('localHasAudio', !!audioTrack, source);\n }\n for (const val of this.isMuted) {\n this.emit('localMuted', {\n ...val\n });\n }\n this.emit('published', {\n status: true,\n hasStream: tracks.length > 0\n });\n this.emit('publishing', false);\n return this;\n };\n\n // this should be enough\n if (!needsNegotiation) {\n return Promise.all([audioTrackReplacePromise, videoTrackReplacePromise]).then(() => emitEvents());\n }\n this._log('Starting negotiation');\n return Promise.all([audioTrackReplacePromise, videoTrackReplacePromise]).then(() => this._createAO('offer', this.handleId, false)).then(jsep => {\n if (!jsep) {\n return null;\n }\n //HOTFIX: Temporary fix for Safari 13\n if (jsep.sdp && jsep.sdp.indexOf(\"\\r\\na=ice-ufrag\") === -1) {\n jsep.sdp = jsep.sdp.replace(\"\\na=ice-ufrag\", \"\\r\\na=ice-ufrag\");\n }\n let descriptions = [];\n Object.keys(config.streamMap).forEach(source => {\n config.streamMap[source].forEach(trackId => {\n let t = transceivers.find(transceiver => transceiver.sender.track && transceiver.sender.track.id === trackId);\n if (t) {\n descriptions.push({\n mid: t.mid,\n description: JSON.stringify({\n source,\n simulcastBitrates: this.simulcastBitrates,\n intercomGroups: this._talkIntercomChannels\n })\n });\n }\n });\n });\n return this.sendMessage(this.handleId, {\n body: {\n \"request\": \"configure\",\n \"audio\": this.isAudioEnabed,\n \"video\": this.isVideoEnabled,\n \"data\": true,\n ...(this.recordingFilename ? {\n filename: this.recordingFilename\n } : {}),\n descriptions: descriptions\n },\n jsep\n });\n }).then(r => {\n if (this._isDataChannelOpen === true) {\n return Promise.resolve(r);\n } else {\n return new Promise((resolve, reject) => {\n let dataChannelTimeoutId = null;\n let _resolve = val => {\n if (val) {\n clearTimeout(dataChannelTimeoutId);\n this._abortController.signal.removeEventListener('abort', _rejectAbort);\n this.off('dataChannel', _resolve, this);\n resolve(this);\n }\n };\n let _rejectTimeout = () => {\n this.off('dataChannel', _resolve, this);\n this._abortController.signal.removeEventListener('abort', _rejectAbort);\n reject({\n type: 'error',\n id: 27,\n message: 'Data channel did not open',\n data: null\n });\n };\n let _rejectAbort = () => {\n this._abortController.signal.removeEventListener('abort', _rejectAbort);\n clearTimeout(dataChannelTimeoutId);\n this.off('dataChannel', _resolve, this);\n reject({\n type: 'warning',\n id: 17,\n message: 'Connection cancelled'\n });\n };\n dataChannelTimeoutId = setTimeout(_rejectTimeout, 10000);\n this._abortController.signal.addEventListener('abort', _rejectAbort);\n this.on('dataChannel', _resolve, this);\n });\n }\n }).then(() => emitEvents()).catch(e => {\n this.emit('publishing', false);\n return Promise.reject(e);\n });\n }\n unpublishLocal() {\n let dontWait = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;\n return this.isPublished ? this.sendMessage(this.handleId, {\n body: {\n \"request\": \"unpublish\"\n }\n }, dontWait).finally(r => {\n this.isPublished = false;\n this.emit('published', {\n status: false,\n hasStream: false\n });\n return r;\n }) : Promise.resolve();\n }\n getUserTalkIntercomChannels(userId) {\n let talkIntercomChannels = [];\n let handle = this._getHandle(null, null, userId);\n if (handle) {\n let config = handle.webrtcStuff;\n talkIntercomChannels = config.tracksMap.reduce((acc, val) => {\n if (val.description) {\n try {\n let description = JSON.parse(val.description);\n if (description.intercomGroups) {\n description.intercomGroups.forEach(group => {\n if (!acc.includes(group)) {\n acc.push(group);\n }\n });\n }\n } catch (e) {}\n }\n return acc;\n }, []);\n }\n return talkIntercomChannels;\n }\n toggleAudio() {\n var _config$pc3;\n let value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;\n let source = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'camera0';\n let mid = arguments.length > 2 ? arguments[2] : undefined;\n let handle = this._getHandle(this.handleId);\n if (!handle) {\n this.emit('error', {\n type: 'warning',\n id: 21,\n message: 'no local id, connect first',\n data: null\n });\n return;\n }\n let config = handle.webrtcStuff;\n let transceivers = (_config$pc3 = config.pc) === null || _config$pc3 === void 0 ? void 0 : _config$pc3.getTransceivers();\n let transceiver = null;\n if (source) {\n transceiver = transceivers === null || transceivers === void 0 ? void 0 : transceivers.find(t => t.sender && t.sender.track && t.receiver.track.kind === \"audio\" && (config.streamMap[source] || []).includes(t.sender.track.id));\n } else {\n transceiver = transceivers === null || transceivers === void 0 ? void 0 : transceivers.find(t => t.sender && t.sender.track && t.receiver.track.kind === \"audio\" && (mid ? t.mid === mid : true));\n }\n if (transceiver) {\n transceiver.sender.track.enabled = value !== null ? !!value : !transceiver.sender.track.enabled;\n }\n this.isMuted = [];\n for (const source of Object.keys(config.streamMap)) {\n var _config$stream8, _config$stream8$getAu, _config$stream9, _config$stream9$getVi, _audioTransceiver$sen, _audioTransceiver$sen2, _videoTransceiver$sen, _videoTransceiver$sen2;\n const audioTrack = (_config$stream8 = config.stream) === null || _config$stream8 === void 0 ? void 0 : (_config$stream8$getAu = _config$stream8.getAudioTracks()) === null || _config$stream8$getAu === void 0 ? void 0 : _config$stream8$getAu.find(track => config.streamMap[source].includes(track.id));\n const audioTransceiver = transceivers === null || transceivers === void 0 ? void 0 : transceivers.find(transceiver => transceiver.sender.track && transceiver.sender.track.kind === 'audio' && transceiver.sender.track.id === (audioTrack === null || audioTrack === void 0 ? void 0 : audioTrack.id));\n const videoTrack = (_config$stream9 = config.stream) === null || _config$stream9 === void 0 ? void 0 : (_config$stream9$getVi = _config$stream9.getVideoTracks()) === null || _config$stream9$getVi === void 0 ? void 0 : _config$stream9$getVi.find(track => config.streamMap[source].includes(track.id));\n const videoTransceiver = transceivers === null || transceivers === void 0 ? void 0 : transceivers.find(transceiver => transceiver.sender.track && transceiver.sender.track.kind === 'video' && transceiver.sender.track.id === (videoTrack === null || videoTrack === void 0 ? void 0 : videoTrack.id));\n this.isMuted.push({\n type: 'audio',\n value: !audioTrack || !audioTransceiver || !(audioTransceiver !== null && audioTransceiver !== void 0 && (_audioTransceiver$sen = audioTransceiver.sender) !== null && _audioTransceiver$sen !== void 0 && (_audioTransceiver$sen2 = _audioTransceiver$sen.track) !== null && _audioTransceiver$sen2 !== void 0 && _audioTransceiver$sen2.enabled),\n source,\n mid: audioTransceiver === null || audioTransceiver === void 0 ? void 0 : audioTransceiver.mid\n });\n this.isMuted.push({\n type: 'video',\n value: !videoTrack || !videoTransceiver || !(videoTransceiver !== null && videoTransceiver !== void 0 && (_videoTransceiver$sen = videoTransceiver.sender) !== null && _videoTransceiver$sen !== void 0 && (_videoTransceiver$sen2 = _videoTransceiver$sen.track) !== null && _videoTransceiver$sen2 !== void 0 && _videoTransceiver$sen2.enabled),\n source,\n mid: videoTransceiver === null || videoTransceiver === void 0 ? void 0 : videoTransceiver.mid\n });\n }\n for (let val of this.isMuted) {\n this.emit('localMuted', {\n ...val\n });\n }\n }\n toggleVideo() {\n var _config$pc4;\n let value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;\n let source = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'camera0';\n let mid = arguments.length > 2 ? arguments[2] : undefined;\n let handle = this._getHandle(this.handleId);\n if (!handle) {\n this.emit('error', {\n type: 'warning',\n id: 21,\n message: 'no local id, connect first',\n data: null\n });\n return;\n }\n let config = handle.webrtcStuff;\n let transceivers = (_config$pc4 = config.pc) === null || _config$pc4 === void 0 ? void 0 : _config$pc4.getTransceivers();\n let transceiver = null;\n if (source) {\n transceiver = transceivers === null || transceivers === void 0 ? void 0 : transceivers.find(t => t.sender && t.sender.track && t.receiver.track.kind === \"video\" && (config.streamMap[source] || []).includes(t.sender.track.id));\n } else {\n transceiver = transceivers === null || transceivers === void 0 ? void 0 : transceivers.find(t => t.sender && t.sender.track && t.receiver.track.kind === \"video\" && (mid ? t.mid === mid : true));\n }\n if (transceiver) {\n transceiver.sender.track.enabled = value !== null ? !!value : !transceiver.sender.track.enabled;\n }\n this.isMuted = [];\n for (const source of Object.keys(config.streamMap)) {\n var _config$stream10, _config$stream10$getA, _config$stream11, _config$stream11$getV, _audioTransceiver$sen3, _audioTransceiver$sen4, _videoTransceiver$sen3, _videoTransceiver$sen4;\n const audioTrack = (_config$stream10 = config.stream) === null || _config$stream10 === void 0 ? void 0 : (_config$stream10$getA = _config$stream10.getAudioTracks()) === null || _config$stream10$getA === void 0 ? void 0 : _config$stream10$getA.find(track => config.streamMap[source].includes(track.id));\n const audioTransceiver = transceivers === null || transceivers === void 0 ? void 0 : transceivers.find(transceiver => transceiver.sender.track && transceiver.sender.track.kind === 'audio' && transceiver.sender.track.id === (audioTrack === null || audioTrack === void 0 ? void 0 : audioTrack.id));\n const videoTrack = (_config$stream11 = config.stream) === null || _config$stream11 === void 0 ? void 0 : (_config$stream11$getV = _config$stream11.getVideoTracks()) === null || _config$stream11$getV === void 0 ? void 0 : _config$stream11$getV.find(track => config.streamMap[source].includes(track.id));\n const videoTransceiver = transceivers === null || transceivers === void 0 ? void 0 : transceivers.find(transceiver => transceiver.sender.track && transceiver.sender.track.kind === 'video' && transceiver.sender.track.id === (videoTrack === null || videoTrack === void 0 ? void 0 : videoTrack.id));\n this.isMuted.push({\n type: 'audio',\n value: !audioTrack || !audioTransceiver || !(audioTransceiver !== null && audioTransceiver !== void 0 && (_audioTransceiver$sen3 = audioTransceiver.sender) !== null && _audioTransceiver$sen3 !== void 0 && (_audioTransceiver$sen4 = _audioTransceiver$sen3.track) !== null && _audioTransceiver$sen4 !== void 0 && _audioTransceiver$sen4.enabled),\n source,\n mid: audioTransceiver === null || audioTransceiver === void 0 ? void 0 : audioTransceiver.mid\n });\n this.isMuted.push({\n type: 'video',\n value: !videoTrack || !videoTransceiver || !(videoTransceiver !== null && videoTransceiver !== void 0 && (_videoTransceiver$sen3 = videoTransceiver.sender) !== null && _videoTransceiver$sen3 !== void 0 && (_videoTransceiver$sen4 = _videoTransceiver$sen3.track) !== null && _videoTransceiver$sen4 !== void 0 && _videoTransceiver$sen4.enabled),\n source,\n mid: videoTransceiver === null || videoTransceiver === void 0 ? void 0 : videoTransceiver.mid\n });\n }\n for (let val of this.isMuted) {\n this.emit('localMuted', {\n ...val\n });\n }\n }\n requestKeyFrame(handleId, mid) {\n this.sendMessage(handleId, {\n \"body\": {\n \"request\": \"configure\",\n \"keyframe\": true,\n ...(mid !== undefined ? {\n streams: [{\n mid,\n keyframe: true\n }]\n } : {})\n }\n }).catch(() => null);\n }\n _setSelectedSubstream(handleId, mid, substream) {\n let handle = this._getHandle(handleId);\n if (handle) {\n let config = handle.webrtcStuff;\n if (!mid) {\n Object.keys(config.selectedSubstream).forEach(mid => {\n config.selectedSubstream[mid] = substream;\n });\n } else {\n config.selectedSubstream[mid] = substream;\n }\n }\n }\n selectSubStream(handleId) {\n let substream = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 2;\n let source = arguments.length > 2 ? arguments[2] : undefined;\n let mid = arguments.length > 3 ? arguments[3] : undefined;\n let manual = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;\n this._log('Select substream called for handle:', handleId, 'Source or mid:', source ? source : mid, 'Substream:', substream);\n let handle = this._getHandle(handleId);\n if (!handle) {\n return Promise.resolve();\n }\n let config = handle.webrtcStuff;\n return new Promise((resolve, reject) => {\n let messageTimeoutId;\n let abortResponse = () => {\n clearTimeout(messageTimeoutId);\n this._abortController.signal.removeEventListener('abort', abortResponse);\n this.ws.removeEventListener('message', parseResponse);\n reject('aborted');\n };\n let parseResponse = event => {\n let json = JSON.parse(event.data);\n var sender = json[\"sender\"];\n if (sender === handleId) {\n let plugindata = json[\"plugindata\"] || {};\n let msg = plugindata[\"data\"] || {};\n let substream = msg[\"substream\"];\n if (substream !== undefined && substream !== null && (mid !== undefined ? msg[\"mid\"] === mid : true)) {\n clearTimeout(messageTimeoutId);\n this._abortController.signal.removeEventListener('abort', abortResponse);\n this.ws.removeEventListener('message', parseResponse);\n resolve({\n substream,\n sender\n });\n }\n }\n };\n if (source !== undefined || mid !== undefined) {\n if (mid === undefined) {\n let transceivers = config.pc.getTransceivers();\n for (let trackId of config.streamMap[source]) {\n let transceiver = transceivers.find(transceiver => transceiver.receiver.track && transceiver.receiver.track.kind === 'video' && transceiver.receiver.track.id === trackId);\n if (transceiver) {\n mid = transceiver.mid;\n break;\n }\n }\n }\n if (mid !== undefined) {\n if (substream === null) {\n if (manual) {\n config.forcedBrowserControlledMode[mid] = false;\n }\n resolve({\n substream,\n sender: handleId\n });\n return;\n }\n if (manual) {\n config.forcedBrowserControlledMode[mid] = true;\n }\n this.ws.addEventListener('message', parseResponse);\n this._abortController.signal.addEventListener('abort', abortResponse);\n messageTimeoutId = setTimeout(() => {\n this._abortController.signal.removeEventListener('abort', abortResponse);\n this.ws.removeEventListener('message', parseResponse);\n reject('timeout');\n }, 10000);\n this.sendMessage(handleId, {\n \"body\": {\n \"request\": \"configure\",\n \"streams\": [{\n mid,\n substream: parseInt(substream)\n }]\n }\n });\n } else {\n reject('no mid found');\n }\n } else {\n reject('no source or mid');\n }\n });\n }\n setTalkIntercomChannels() {\n let groups = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['participants'];\n if (typeof groups !== 'object' || !(\"length\" in groups)) {\n this._log('setTalkIntercomChannels: groups must be an array');\n groups = [groups];\n }\n this._talkIntercomChannels = structuredClone(groups);\n let handle = this._getHandle(this.handleId);\n if (!handle) {\n return Promise.resolve();\n }\n let config = handle.webrtcStuff;\n let transceivers = config.pc.getTransceivers();\n let descriptions = [];\n Object.keys(config.streamMap).forEach(source => {\n config.streamMap[source].forEach(trackId => {\n let t = transceivers.find(transceiver => transceiver.sender.track && transceiver.sender.track.id === trackId);\n if (t) {\n descriptions.push({\n mid: t.mid,\n description: JSON.stringify({\n simulcastBitrates: this.simulcastBitrates,\n intercomGroups: groups,\n source: source\n })\n });\n }\n });\n });\n return this.sendMessage(this.handleId, {\n body: {\n \"request\": \"configure\",\n descriptions: descriptions\n }\n });\n }\n setListenIntercomChannels() {\n let groups = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['participants'];\n if (typeof groups !== 'object' || !(\"length\" in groups)) {\n this._log('setListenIntercomChannels: groups must be an array');\n groups = [groups];\n }\n this._listenIntercomChannels = structuredClone(groups);\n let handle = this._getHandle(this.handleId);\n if (!handle) {\n return Promise.resolve();\n }\n let promises = [];\n this._participants.forEach(participant => {\n if (participant.handleId === this.handleId) {\n return;\n }\n let handle = this._getHandle(participant.handleId);\n if (handle) {\n const tracksMap = handle.webrtcStuff.tracksMap.filter(t => t.active);\n const subscribe = [];\n const unsubscribe = [];\n tracksMap.forEach(track => {\n if (track.type === 'data') {\n return;\n }\n const description = JSON.parse(track.description);\n const intercomGroups = (description === null || description === void 0 ? void 0 : description.intercomGroups) || [];\n if (this._listenIntercomChannels.some(g => intercomGroups.includes(g))) {\n if (!this._isAlreadySubscribed(participant.handleId, track.id, track.mid)) {\n subscribe.push({\n feed: track.id,\n mid: track.mid\n });\n }\n } else {\n unsubscribe.push({\n feed: track.id,\n mid: track.mid\n });\n }\n });\n this._updateSubscribeMap(participant.handleId, subscribe, unsubscribe);\n if (subscribe.length || unsubscribe.length) {\n promises.push(this.sendMessage(handle.handleId, {\n body: {\n \"request\": \"update\",\n ...(subscribe.length ? {\n subscribe\n } : {}),\n ...(unsubscribe.length ? {\n unsubscribe\n } : {})\n }\n }));\n }\n }\n });\n return Promise.all(promises);\n }\n setRoomType() {\n let type = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'watchparty';\n this._roomType = type;\n return this._roomType;\n }\n setRestrictSubscribeToUserIds() {\n let userIds = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];\n this._restrictSubscribeToUserIds = structuredClone(userIds);\n if (!this.isConnected) {\n return Promise.resolve(this._restrictSubscribeToUserIds);\n }\n // sanity check by getting listparticipants and comparing it to _remoteUsersCache\n this.sendMessage(this.handleId, {\n body: {\n request: 'listparticipants',\n room: this.roomId\n }\n }).then(r => {\n let participants = r.participants;\n let remoteUsersCache = this._remoteUsersCache;\n let handle = this._getHandle(this.handleId);\n\n // filter out my user id from response and compare it to remoteUsersCache\n participants = participants.filter(p => p.id !== handle.userId);\n\n // get rid of participants that are in participants but not in remoteUsersCache\n remoteUsersCache = remoteUsersCache.filter(r => participants.find(p => p.id === r.id));\n remoteUsersCache.forEach(r => {\n var _decodeJanusDisplay31;\n const handle = this._getHandle(null, null, (_decodeJanusDisplay31 = Object(_wt_utils__WEBPACK_IMPORTED_MODULE_2__[\"decodeJanusDisplay\"])(r.userId)) === null || _decodeJanusDisplay31 === void 0 ? void 0 : _decodeJanusDisplay31.userId);\n if (this._participantShouldSubscribe(r.userId)) {\n var _handle$webrtcStuff4;\n // todo: do a nicer flag to indicate inactive handle than just checking for pc\n if (!handle || !((_handle$webrtcStuff4 = handle.webrtcStuff) !== null && _handle$webrtcStuff4 !== void 0 && _handle$webrtcStuff4.pc)) {\n this._log('Subscribing to ', r.userId);\n this._createParticipant(r.userId, r.id).then(handle => {\n this._updateParticipantsTrackData(handle.handleId, r.streams);\n const subscribe = r.streams.filter(s => !s.disabled && this._intercomSubscribe(s)).map(stream => ({\n feed: stream.id,\n mid: stream.mid\n }));\n handle.webrtcStuff.subscribeMap = structuredClone(subscribe);\n return this.sendMessage(handle.handleId, {\n body: {\n \"request\": \"join\",\n \"room\": this.roomId,\n \"ptype\": \"subscriber\",\n \"private_id\": this.privateId,\n streams: subscribe,\n //\"feed\": id,\n ...(this.webrtcVersion > 1000 ? {\n id: this.userId\n } : {}),\n pin: this.pin\n }\n });\n }).catch(err => {\n this.emit('error', err);\n });\n } else {\n this._log('Already subscribed to ', r.userId);\n }\n } else if (handle) {\n this._log('Unsubscribing from ', r.userId);\n this._removeParticipant(handle.handleId);\n }\n });\n });\n }\n}\n_defineProperty(RoomSession, \"sessionTypes\", {\n 'reactooroom': 'janus.plugin.reactooroom',\n 'streaming': 'janus.plugin.streaming'\n});\n_defineProperty(RoomSession, \"userRoleSubscriptionRules\", {\n participant: {\n \"watchparty\": ['participant', 'talkback'],\n \"studio\": ['participant', 'talkback', 'host', 'observer'],\n \"commentary\": ['participant', 'talkback', 'host'],\n \"intercom\": ['host', 'talkback', 'observer', 'observerSolo1', 'observerSolo2', 'observerSolo3'],\n \"videowall\": ['host', 'talkback', 'observer', 'observerSolo1', 'observerSolo2', 'observerSolo3'],\n \"videowall-queue\": ['host', 'talkback', 'observer', 'observerSolo1', 'observerSolo2', 'observerSolo3'],\n \"videowall-queue-video\": ['host', 'talkback', 'observer', 'observerSolo1', 'observerSolo2', 'observerSolo3']\n },\n monitor: {\n \"watchparty\": ['participant', 'host'],\n \"studio\": ['participant', 'host', 'observer'],\n \"commentary\": ['participant', 'host'],\n \"intercom\": ['host', 'participant'],\n \"videowall\": ['host', 'participant'],\n \"videowall-queue\": ['host', 'participant'],\n \"videowall-queue-video\": ['host', 'participant']\n },\n talkback: {\n \"watchparty\": ['participant', 'host', 'talkback'],\n \"studio\": ['participant', 'host', 'observer', 'talkback'],\n \"commentary\": ['host', 'participant', 'talkback'],\n \"intercom\": ['host', 'participant', 'talkback'],\n \"videowall\": ['host', 'participant', 'talkback'],\n \"videowall-queue\": ['host', 'participant', 'talkback'],\n \"videowall-queue-video\": ['host', 'participant', 'talkback']\n },\n observer: {\n \"watchparty\": ['participant'],\n \"studio\": ['participant'],\n \"commentary\": ['participant'],\n \"intercom\": ['participant'],\n \"videowall\": ['participant'],\n \"videowall-queue\": ['participant'],\n \"videowall-queue-video\": ['participant']\n },\n observerSolo1: {\n \"watchparty\": ['participant'],\n \"studio\": ['participant'],\n \"commentary\": ['participant'],\n \"intercom\": ['participant'],\n \"videowall\": ['participant'],\n \"videowall-queue\": ['participant'],\n \"videowall-queue-video\": ['participant']\n },\n observerSolo2: {\n \"watchparty\": ['participant'],\n \"studio\": ['participant'],\n \"commentary\": ['participant'],\n \"intercom\": ['participant'],\n \"videowall\": ['participant'],\n \"videowall-queue\": ['participant'],\n \"videowall-queue-video\": ['participant']\n },\n observerSolo3: {\n \"watchparty\": ['participant'],\n \"studio\": ['participant'],\n \"commentary\": ['participant'],\n \"intercom\": ['participant'],\n \"videowall\": ['participant'],\n \"videowall-queue\": ['participant'],\n \"videowall-queue-video\": ['participant']\n },\n host: {\n \"watchparty\": [],\n \"studio\": [],\n \"commentary\": [],\n \"intercom\": [],\n \"videowall\": [],\n \"videowall-queue\": [],\n \"videowall-queue-video\": []\n },\n companionTV: {},\n companionPhone: {}\n});\n/* harmony default export */ __webpack_exports__[\"default\"] = (Room);\n\n//# sourceURL=webpack://WatchTogetherSDK/./src/modules/wt-room.js?");
|
|
8932
8932
|
|
|
8933
8933
|
/***/ }),
|
|
8934
8934
|
|