@webex/plugin-meetings 3.0.0-beta.1 → 3.0.0-beta.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.
Files changed (111) hide show
  1. package/dist/common/errors/webex-errors.js +5 -29
  2. package/dist/common/errors/webex-errors.js.map +1 -1
  3. package/dist/constants.js +15 -74
  4. package/dist/constants.js.map +1 -1
  5. package/dist/media/index.js +68 -213
  6. package/dist/media/index.js.map +1 -1
  7. package/dist/media/internal-media-core-wrapper.js +22 -0
  8. package/dist/media/internal-media-core-wrapper.js.map +1 -0
  9. package/dist/media/properties.js +20 -25
  10. package/dist/media/properties.js.map +1 -1
  11. package/dist/media/util.js +0 -27
  12. package/dist/media/util.js.map +1 -1
  13. package/dist/meeting/index.js +694 -432
  14. package/dist/meeting/index.js.map +1 -1
  15. package/dist/meeting/request.js +1 -0
  16. package/dist/meeting/request.js.map +1 -1
  17. package/dist/meeting/util.js +3 -44
  18. package/dist/meeting/util.js.map +1 -1
  19. package/dist/meetings/index.js +64 -5
  20. package/dist/meetings/index.js.map +1 -1
  21. package/dist/meetings/util.js +24 -1
  22. package/dist/meetings/util.js.map +1 -1
  23. package/dist/members/index.js +68 -0
  24. package/dist/members/index.js.map +1 -1
  25. package/dist/multistream/mediaRequestManager.js +132 -0
  26. package/dist/multistream/mediaRequestManager.js.map +1 -0
  27. package/dist/multistream/multistreamMedia.js +116 -0
  28. package/dist/multistream/multistreamMedia.js.map +1 -0
  29. package/dist/multistream/receiveSlot.js +209 -0
  30. package/dist/multistream/receiveSlot.js.map +1 -0
  31. package/dist/multistream/receiveSlotManager.js +195 -0
  32. package/dist/multistream/receiveSlotManager.js.map +1 -0
  33. package/dist/multistream/remoteMedia.js +284 -0
  34. package/dist/multistream/remoteMedia.js.map +1 -0
  35. package/dist/multistream/remoteMediaGroup.js +243 -0
  36. package/dist/multistream/remoteMediaGroup.js.map +1 -0
  37. package/dist/multistream/remoteMediaManager.js +1113 -0
  38. package/dist/multistream/remoteMediaManager.js.map +1 -0
  39. package/dist/reconnection-manager/index.js +109 -130
  40. package/dist/reconnection-manager/index.js.map +1 -1
  41. package/dist/roap/index.js +57 -240
  42. package/dist/roap/index.js.map +1 -1
  43. package/dist/roap/request.js +2 -114
  44. package/dist/roap/request.js.map +1 -1
  45. package/dist/roap/turnDiscovery.js +11 -5
  46. package/dist/roap/turnDiscovery.js.map +1 -1
  47. package/dist/statsAnalyzer/global.js +2 -0
  48. package/dist/statsAnalyzer/global.js.map +1 -1
  49. package/dist/statsAnalyzer/index.js +39 -36
  50. package/dist/statsAnalyzer/index.js.map +1 -1
  51. package/package.json +20 -19
  52. package/src/common/errors/webex-errors.js +0 -18
  53. package/src/constants.ts +139 -180
  54. package/src/media/index.js +60 -194
  55. package/src/media/internal-media-core-wrapper.ts +9 -0
  56. package/src/media/properties.js +19 -25
  57. package/src/media/util.js +0 -22
  58. package/src/meeting/index.js +565 -320
  59. package/src/meeting/request.js +1 -0
  60. package/src/meeting/util.js +3 -46
  61. package/src/meetings/index.js +30 -1
  62. package/src/meetings/util.js +23 -2
  63. package/src/members/index.js +48 -0
  64. package/src/multistream/mediaRequestManager.ts +164 -0
  65. package/src/multistream/multistreamMedia.ts +92 -0
  66. package/src/multistream/receiveSlot.ts +141 -0
  67. package/src/multistream/receiveSlotManager.ts +142 -0
  68. package/src/multistream/remoteMedia.ts +219 -0
  69. package/src/multistream/remoteMediaGroup.ts +224 -0
  70. package/src/multistream/remoteMediaManager.ts +911 -0
  71. package/src/reconnection-manager/index.js +40 -53
  72. package/src/roap/index.js +47 -207
  73. package/src/roap/request.js +1 -72
  74. package/src/roap/turnDiscovery.ts +12 -6
  75. package/src/statsAnalyzer/global.js +2 -0
  76. package/src/statsAnalyzer/index.js +32 -46
  77. package/test/integration/spec/journey.js +1 -1
  78. package/test/unit/spec/media/index.ts +223 -0
  79. package/test/unit/spec/media/properties.ts +73 -82
  80. package/test/unit/spec/meeting/effectsState.js +1 -3
  81. package/test/unit/spec/meeting/index.js +420 -228
  82. package/test/unit/spec/meeting/muteState.js +7 -0
  83. package/test/unit/spec/meeting/utils.js +61 -2
  84. package/test/unit/spec/meetings/index.js +0 -4
  85. package/test/unit/spec/members/index.js +164 -2
  86. package/test/unit/spec/multistream/mediaRequestManager.ts +511 -0
  87. package/test/unit/spec/multistream/receiveSlot.ts +104 -0
  88. package/test/unit/spec/multistream/receiveSlotManager.ts +173 -0
  89. package/test/unit/spec/multistream/remoteMedia.ts +217 -0
  90. package/test/unit/spec/multistream/remoteMediaGroup.ts +396 -0
  91. package/test/unit/spec/multistream/remoteMediaManager.ts +1251 -0
  92. package/test/unit/spec/roap/index.ts +63 -35
  93. package/test/unit/spec/stats-analyzer/index.js +19 -22
  94. package/dist/peer-connection-manager/index.js +0 -794
  95. package/dist/peer-connection-manager/index.js.map +0 -1
  96. package/dist/roap/collection.js +0 -73
  97. package/dist/roap/collection.js.map +0 -1
  98. package/dist/roap/handler.js +0 -337
  99. package/dist/roap/handler.js.map +0 -1
  100. package/dist/roap/state.js +0 -164
  101. package/dist/roap/state.js.map +0 -1
  102. package/dist/roap/util.js +0 -102
  103. package/dist/roap/util.js.map +0 -1
  104. package/src/peer-connection-manager/index.js +0 -723
  105. package/src/roap/collection.js +0 -63
  106. package/src/roap/handler.js +0 -252
  107. package/src/roap/state.js +0 -149
  108. package/src/roap/util.js +0 -93
  109. package/test/unit/spec/peerconnection-manager/index.js +0 -188
  110. package/test/unit/spec/peerconnection-manager/utils.js +0 -48
  111. package/test/unit/spec/roap/util.js +0 -30
@@ -0,0 +1 @@
1
+ {"version":3,"names":["AllEqualLayout","screenShareVideo","size","activeSpeakerVideoPaneGroups","id","numPanes","priority","SingleLayout","OnePlusFiveLayout","TwoMainPlusSixSmallLayout","RemoteScreenShareWithSmallThumbnailsLayout","Stage2x2With6ThumbnailsLayout","memberVideoPanes","csi","undefined","DefaultConfiguration","audio","numOfActiveSpeakerStreams","video","preferLiveVideo","initialLayoutId","layouts","AllEqual","OnePlusFive","Single","Stage","ScreenShareView","screenShare","Event","RemoteMediaManager","receiveSlotManager","mediaRequestManagers","config","started","media","activeSpeakerGroups","memberPanes","checkConfigValidity","slots","screenShareAudio","unused","activeSpeaker","receiverSelected","receiveSlotAllocations","LoggerProxy","logger","log","Error","forEach","layout","groupIds","paneIds","groupPriorites","group","pane","createAudioMedia","preallocateVideoReceiveSlots","setLayout","invalidateCurrentRemoteMedia","commit","slot","releaseSlot","length","push","releaseUnusedVideoSlots","currentLayout","currentLayoutId","activeSpeakerCount","reduce","sum","paneGroup","receiverSelectedCount","maxNumVideoPanesRequired","maxValue","Math","max","getRequiredNumVideoSlotsForLayout","allocateSlot","MC","MediaType","VideoMain","layoutId","updateVideoReceiveSlots","updateVideoRemoteMediaObjects","emitVideoLayoutChangedEvent","i","AudioMain","RemoteMediaGroup","emit","file","function","AudioCreated","requiredCsis","memberVideoPane","isCsiNeededByCurrentLayout","notNeededReceiverSelectedSlots","paneIndex","freeSlot","pop","memberPane","existingSlot","find","isExistingSlotAlreadyAllocated","includes","requiredNumSlots","totalNumSlots","numSlotsToCreate","trimReceiverSelectedSlots","allocateSlotsToVideoPaneGroups","groupId","paneGroupInCurrentLayout","groupInLayout","mediaGroup","resolution","warn","paneId","paneInCurrentLayout","paneInLayout","remoteMedia","RemoteMedia","sendMediaRequest","options","stop","remoteMediaGroup","VideoLayoutChanged","activeSpeakerVideoPanes","cancelMediaRequest","newPane","receiveSlot","reject","resolve","getUnderlyingReceiveSlot","index","indexOf","splice","pin","unpin","isPinned","EventsScope"],"sources":["remoteMediaManager.ts"],"sourcesContent":["import {cloneDeep, remove} from 'lodash';\nimport {EventMap} from 'typed-emitter';\nimport {MediaConnection as MC} from '@webex/internal-media-core';\n\nimport LoggerProxy from '../common/logs/logger-proxy';\nimport EventsScope from '../common/events/events-scope';\n\nimport {RemoteMedia, RemoteVideoResolution} from './remoteMedia';\nimport {ReceiveSlot, CSI} from './receiveSlot';\nimport {ReceiveSlotManager} from './receiveSlotManager';\nimport {RemoteMediaGroup} from './remoteMediaGroup';\nimport {MediaRequestManager} from './mediaRequestManager';\n\nexport type PaneSize = RemoteVideoResolution;\nexport type LayoutId = string;\nexport type PaneId = string;\nexport type PaneGroupId = string;\n\nexport interface ActiveSpeakerVideoPaneGroup {\n id: PaneGroupId;\n numPanes: number; // maximum number of panes in the group (actual number may be lower, if there are not enough participants in the meeting)\n size: PaneSize; // preferred size for all panes in the group\n priority: number; // 0-255 (255 = highest priority), each group must have a different priority from all other groups\n}\n\nexport interface MemberVideoPane {\n id: PaneId;\n size: PaneSize;\n csi?: CSI;\n}\n\nexport interface VideoLayout {\n screenShareVideo: {\n size: PaneSize | null; // null if you don't want to receive any screen share video\n };\n activeSpeakerVideoPaneGroups?: ActiveSpeakerVideoPaneGroup[]; // list of active speaker video pane groups\n memberVideoPanes?: MemberVideoPane[]; // list of video panes for specific members, CSI values can be changed later via setVideoPaneCsi()\n}\n\nexport interface Configuration {\n audio: {\n numOfActiveSpeakerStreams: number; // number of audio streams we want to receive\n };\n video: {\n preferLiveVideo: boolean; // applies to all pane groups with active speaker policy\n initialLayoutId: LayoutId;\n\n layouts: {[key: LayoutId]: VideoLayout}; // a map of all available layouts, a layout can be set via setLayout() method\n };\n screenShare: {\n audio: boolean; // whether we ever want to receive screen share audio at all\n video: boolean; // whether we ever want to receive screen share video at all\n };\n}\n\n/* Predefined layouts: */\n\n// An \"all equal\" grid, with size up to 3 x 3 = 9:\nconst AllEqualLayout: VideoLayout = {\n screenShareVideo: {size: null},\n activeSpeakerVideoPaneGroups: [\n {\n id: 'main',\n numPanes: 9,\n size: 'best',\n priority: 255,\n },\n ],\n};\n\n// A layout with just a single remote active speaker video pane:\nconst SingleLayout: VideoLayout = {\n screenShareVideo: {size: null},\n activeSpeakerVideoPaneGroups: [\n {\n id: 'main',\n numPanes: 1,\n size: 'best',\n priority: 255,\n },\n ],\n};\n\n// A layout with 1 big pane for the highest priority active speaker and 5 small panes for other active speakers:\nconst OnePlusFiveLayout: VideoLayout = {\n screenShareVideo: {size: null},\n activeSpeakerVideoPaneGroups: [\n {\n id: 'mainBigOne',\n numPanes: 1,\n size: 'large',\n priority: 255,\n },\n {\n id: 'secondarySetOfSmallPanes',\n numPanes: 5,\n size: 'very small',\n priority: 254,\n },\n ],\n};\n\n// A layout with 2 big panes for 2 main active speakers and a strip of 6 small panes for other active speakers:\nconst TwoMainPlusSixSmallLayout: VideoLayout = {\n screenShareVideo: {size: null},\n activeSpeakerVideoPaneGroups: [\n {\n id: 'mainGroupWith2BigPanes',\n numPanes: 2,\n size: 'large',\n priority: 255,\n },\n {\n id: 'secondaryGroupOfSmallPanes',\n numPanes: 6,\n size: 'small',\n priority: 254,\n },\n ],\n};\n\n// A strip of 8 small video panes (thumbnails) displayed at the top of a remote screenshare:\nconst RemoteScreenShareWithSmallThumbnailsLayout: VideoLayout = {\n screenShareVideo: {size: 'best'},\n activeSpeakerVideoPaneGroups: [\n {\n id: 'thumbnails',\n numPanes: 8,\n size: 'thumbnail',\n priority: 255,\n },\n ],\n};\n\n// A staged layout with 4 pre-selected meeting participants in the main 2x2 grid and 6 small panes for other active speakers at the top:\nconst Stage2x2With6ThumbnailsLayout: VideoLayout = {\n screenShareVideo: {size: null},\n activeSpeakerVideoPaneGroups: [\n {\n id: 'thumbnails',\n numPanes: 6,\n size: 'thumbnail',\n priority: 255,\n },\n ],\n memberVideoPanes: [\n {id: 'stage-1', size: 'medium', csi: undefined},\n {id: 'stage-2', size: 'medium', csi: undefined},\n {id: 'stage-3', size: 'medium', csi: undefined},\n {id: 'stage-4', size: 'medium', csi: undefined},\n ],\n};\n\n/**\n * Default configuration:\n * - uses 3 audio streams\n * - prefers active speakers with live video (e.g. are not audio only or video muted) over active speakers without live video\n * - has a few layouts defined, including 1 that contains remote screen share (ScreenShareView)\n */\nexport const DefaultConfiguration: Configuration = {\n audio: {\n numOfActiveSpeakerStreams: 3,\n },\n video: {\n preferLiveVideo: true,\n initialLayoutId: 'AllEqual',\n\n layouts: {\n AllEqual: AllEqualLayout,\n OnePlusFive: OnePlusFiveLayout,\n Single: SingleLayout,\n Stage: Stage2x2With6ThumbnailsLayout,\n ScreenShareView: RemoteScreenShareWithSmallThumbnailsLayout,\n },\n },\n screenShare: {\n audio: true,\n video: true,\n },\n};\n\nexport enum Event {\n // events for audio streams\n AudioCreated = 'AudioCreated',\n ScreenShareAudioCreated = 'ScreenShareCreated',\n\n // events for video streams\n VideoLayoutChanged = 'VideoLayoutChanged',\n}\n\nexport interface VideoLayoutChangedEventData {\n layoutId: LayoutId;\n activeSpeakerVideoPanes: {\n [key: PaneGroupId]: RemoteMediaGroup;\n };\n memberVideoPanes: {[key: PaneId]: RemoteMedia};\n screenShareVideo?: RemoteMedia;\n}\nexport interface Events extends EventMap {\n // audio\n [Event.AudioCreated]: (audio: RemoteMediaGroup) => void;\n [Event.ScreenShareAudioCreated]: (screenShareAudio: RemoteMedia) => void;\n\n // video\n [Event.VideoLayoutChanged]: (data: VideoLayoutChangedEventData) => void;\n}\n\n/**\n * A helper class that manages all remote audio/video streams in order to achieve a predefined set of layouts.\n * It also creates a fixed number of audio streams and these don't change during the meeting.\n *\n * Things that RemoteMediaManager does:\n * - owns the receive slots (creates them when needed, and re-uses them when switching layouts)\n * - constructs appropriate RemoteMedia and RemoteMediaGroup objects and sends appropriate mediaRequests\n */\nexport class RemoteMediaManager extends EventsScope {\n private config: Configuration;\n\n private started: boolean;\n\n private receiveSlotManager: ReceiveSlotManager;\n\n private mediaRequestManagers: {\n audio: MediaRequestManager;\n video: MediaRequestManager;\n };\n\n private currentLayout?: VideoLayout;\n\n private slots: {\n audio: ReceiveSlot[];\n screenShareAudio?: ReceiveSlot;\n screenShareVideo?: ReceiveSlot;\n video: {\n unused: ReceiveSlot[];\n activeSpeaker: ReceiveSlot[];\n receiverSelected: ReceiveSlot[];\n };\n };\n\n private media: {\n audio?: RemoteMediaGroup;\n video: {\n activeSpeakerGroups: {\n [key: PaneGroupId]: RemoteMediaGroup;\n };\n memberPanes: {[key: PaneId]: RemoteMedia};\n };\n };\n\n private receiveSlotAllocations: {\n activeSpeaker: {[key: PaneGroupId]: {slots: ReceiveSlot[]}};\n receiverSelected: {[key: PaneId]: ReceiveSlot};\n };\n\n private currentLayoutId?: LayoutId;\n\n /**\n * Constructor\n *\n * @param {ReceiveSlotManager} receiveSlotManager\n * @param {{audio: MediaRequestManager, video: mediaRequestManagers}} mediaRequestManagers\n * @param {Configuration} config Configuration describing what video layouts to use during the meeting\n */\n constructor(\n receiveSlotManager: ReceiveSlotManager,\n mediaRequestManagers: {\n audio: MediaRequestManager;\n video: MediaRequestManager;\n },\n config: Configuration = DefaultConfiguration\n ) {\n super();\n this.started = false;\n this.config = config;\n this.receiveSlotManager = receiveSlotManager;\n this.mediaRequestManagers = mediaRequestManagers;\n this.media = {\n audio: undefined,\n video: {\n activeSpeakerGroups: {},\n memberPanes: {},\n },\n };\n\n this.checkConfigValidity();\n\n this.slots = {\n audio: [],\n screenShareAudio: undefined,\n screenShareVideo: undefined,\n video: {\n unused: [],\n activeSpeaker: [],\n receiverSelected: [],\n },\n };\n\n this.receiveSlotAllocations = {activeSpeaker: {}, receiverSelected: {}};\n\n LoggerProxy.logger.log(\n `RemoteMediaManager#constructor --> RemoteMediaManager created with config: ${JSON.stringify(\n this.config\n )}`\n );\n }\n\n /**\n * Checks if configuration is valid, throws an error if it's not\n */\n private checkConfigValidity() {\n if (!(this.config.video.initialLayoutId in this.config.video.layouts)) {\n throw new Error(\n `invalid config: initialLayoutId \"${this.config.video.initialLayoutId}\" doesn't match any of the layouts`\n );\n }\n\n // check if each layout is valid\n Object.values(this.config.video.layouts).forEach((layout) => {\n const groupIds = {};\n const paneIds = {};\n const groupPriorites = {};\n\n layout.activeSpeakerVideoPaneGroups?.forEach((group) => {\n if (groupIds[group.id]) {\n throw new Error(\n `invalid config: duplicate active speaker video pane group id: ${group.id}`\n );\n }\n groupIds[group.id] = true;\n\n if (groupPriorites[group.priority]) {\n throw new Error(\n `invalid config: multiple active speaker video pane groups have same priority: ${group.priority}`\n );\n }\n groupPriorites[group.priority] = true;\n });\n\n layout.memberVideoPanes?.forEach((pane) => {\n if (paneIds[pane.id]) {\n throw new Error(`invalid config: duplicate member video pane id: ${pane.id}`);\n }\n paneIds[pane.id] = true;\n });\n });\n }\n\n /**\n * Starts the RemoteMediaManager.\n *\n * @returns {Promise}\n */\n public async start() {\n if (this.started) {\n throw new Error('start() failure: already started');\n }\n this.started = true;\n\n await this.createAudioMedia();\n\n // todo: create screen share audio remote media (SPARK-377812)\n // todo: create screen share video receive slot (SPARK-377812)\n\n await this.preallocateVideoReceiveSlots();\n\n await this.setLayout(this.config.video.initialLayoutId);\n }\n\n /**\n * Releases all the used resources (like allocated receive slots). This function needs\n * to be called when we leave the meeting, etc.\n */\n public stop() {\n // invalidate all remoteMedia objects\n this.invalidateCurrentRemoteMedia({audio: true, video: true, commit: true});\n\n // release all audio receive slots\n this.slots.audio.forEach((slot) => this.receiveSlotManager.releaseSlot(slot));\n this.slots.audio.length = 0;\n\n // todo: screenshare slots... (SPARK-377812)\n\n this.receiveSlotAllocations = {activeSpeaker: {}, receiverSelected: {}};\n\n this.slots.video.unused.push(...this.slots.video.activeSpeaker);\n this.slots.video.activeSpeaker.length = 0;\n\n this.slots.video.unused.push(...this.slots.video.receiverSelected);\n this.slots.video.receiverSelected.length = 0;\n\n this.releaseUnusedVideoSlots();\n\n this.currentLayout = undefined;\n this.currentLayoutId = undefined;\n this.started = false;\n }\n\n /**\n * Returns the total number of main video panes required for a given layout\n *\n * @param {VideoLayout} layout\n * @returns {number}\n */\n private getRequiredNumVideoSlotsForLayout(layout?: VideoLayout) {\n if (!layout) {\n return 0;\n }\n\n const activeSpeakerCount =\n layout.activeSpeakerVideoPaneGroups?.reduce(\n (sum, paneGroup) => sum + paneGroup.numPanes,\n 0\n ) || 0;\n\n const receiverSelectedCount = layout.memberVideoPanes?.length || 0;\n\n return activeSpeakerCount + receiverSelectedCount;\n }\n\n /**\n * Allocates the maximum number of panes that any of the configured layouts will require.\n * We do this at the beginning, because it's more efficient (much faster) then allocating receive slots\n * later, after the SDP exchange was done.\n */\n private async preallocateVideoReceiveSlots() {\n const maxNumVideoPanesRequired = Object.values(this.config.video.layouts).reduce(\n (maxValue, layout) => Math.max(maxValue, this.getRequiredNumVideoSlotsForLayout(layout)),\n 0\n );\n\n while (this.slots.video.unused.length < maxNumVideoPanesRequired) {\n // eslint-disable-next-line no-await-in-loop\n this.slots.video.unused.push(\n await this.receiveSlotManager.allocateSlot(MC.MediaType.VideoMain)\n );\n }\n }\n\n /**\n * Changes the layout (triggers Event.VideoLayoutChanged)\n *\n * @param {LayoutId} layoutId new layout id\n * @returns {Promise}\n */\n public async setLayout(layoutId: LayoutId) {\n if (!(layoutId in this.config.video.layouts)) {\n throw new Error(\n `invalid layoutId: \"${layoutId}\" doesn't match any of the configured layouts`\n );\n }\n if (!this.started) {\n throw new Error('setLayout() called before start()');\n }\n this.currentLayoutId = layoutId;\n this.currentLayout = cloneDeep(this.config.video.layouts[this.currentLayoutId]);\n\n await this.updateVideoReceiveSlots();\n this.updateVideoRemoteMediaObjects();\n this.emitVideoLayoutChangedEvent();\n }\n\n /**\n * Returns the currently selected layout id\n *\n * @returns {LayoutId}\n */\n public getLayoutId(): LayoutId | undefined {\n return this.currentLayoutId;\n }\n\n /**\n * Creates the audio slots\n */\n private async createAudioMedia() {\n // create the audio receive slots\n for (let i = 0; i < this.config.audio.numOfActiveSpeakerStreams; i += 1) {\n // eslint-disable-next-line no-await-in-loop\n const slot = await this.receiveSlotManager.allocateSlot(MC.MediaType.AudioMain);\n\n this.slots.audio.push(slot);\n }\n\n // create a remote media group\n this.media.audio = new RemoteMediaGroup(\n this.mediaRequestManagers.audio,\n this.slots.audio,\n 255,\n true\n );\n\n this.emit(\n {file: 'multistream/remoteMediaManager', function: 'createAudioMedia'},\n Event.AudioCreated,\n this.media.audio\n );\n }\n\n /**\n * Goes over all receiver-selected slots and keeps only the ones that are required by a given layout,\n * the rest are all moved to the \"unused\" list\n */\n private trimReceiverSelectedSlots() {\n const requiredCsis = {};\n\n // fill requiredCsis with all the CSIs that the given layout requires\n this.currentLayout?.memberVideoPanes?.forEach((memberVideoPane) => {\n if (memberVideoPane.csi !== undefined) {\n requiredCsis[memberVideoPane.csi] = true;\n }\n });\n\n const isCsiNeededByCurrentLayout = (csi?: CSI): boolean => {\n if (csi === undefined) {\n return false;\n }\n\n return !!requiredCsis[csi];\n };\n\n // keep receiverSelected slots that match our new requiredCsis, move the rest of receiverSelected slots to unused\n const notNeededReceiverSelectedSlots = remove(\n this.slots.video.receiverSelected,\n (slot) => isCsiNeededByCurrentLayout(slot.csi) === false\n );\n\n this.slots.video.unused.push(...notNeededReceiverSelectedSlots);\n }\n\n /**\n * Releases all the \"unused\" video slots.\n */\n private releaseUnusedVideoSlots() {\n this.slots.video.unused.forEach((slot) => this.receiveSlotManager.releaseSlot(slot));\n this.slots.video.unused.length = 0;\n }\n\n /**\n * Allocates receive slots to all video panes in the current selected layout\n */\n private allocateSlotsToVideoPaneGroups() {\n this.receiveSlotAllocations = {activeSpeaker: {}, receiverSelected: {}};\n\n this.currentLayout?.activeSpeakerVideoPaneGroups?.forEach((group) => {\n this.receiveSlotAllocations.activeSpeaker[group.id] = {slots: []};\n\n for (let paneIndex = 0; paneIndex < group.numPanes; paneIndex += 1) {\n // allocate a slot from the \"unused\" list\n const freeSlot = this.slots.video.unused.pop();\n\n if (freeSlot) {\n this.slots.video.activeSpeaker.push(freeSlot);\n this.receiveSlotAllocations.activeSpeaker[group.id].slots.push(freeSlot);\n }\n }\n });\n\n this.currentLayout?.memberVideoPanes?.forEach((memberPane) => {\n // check if there is existing slot for this csi\n const existingSlot = this.slots.video.receiverSelected.find(\n (slot) => slot.csi === memberPane.csi\n );\n\n const isExistingSlotAlreadyAllocated = Object.values(\n this.receiveSlotAllocations.receiverSelected\n ).includes(existingSlot);\n\n if (memberPane.csi !== undefined && existingSlot && !isExistingSlotAlreadyAllocated) {\n // found it, so use it\n this.receiveSlotAllocations.receiverSelected[memberPane.id] = existingSlot;\n } else {\n // allocate a slot from the \"unused\" list\n const freeSlot = this.slots.video.unused.pop();\n\n if (freeSlot) {\n this.slots.video.receiverSelected.push(freeSlot);\n this.receiveSlotAllocations.receiverSelected[memberPane.id] = freeSlot;\n }\n }\n });\n }\n\n /**\n * Makes sure we have the right number of receive slots created for the current layout\n * and allocates them to the right video panes / pane groups\n *\n * @returns {Promise}\n */\n private async updateVideoReceiveSlots() {\n const requiredNumSlots = this.getRequiredNumVideoSlotsForLayout(this.currentLayout);\n const totalNumSlots =\n this.slots.video.unused.length +\n this.slots.video.activeSpeaker.length +\n this.slots.video.receiverSelected.length;\n\n // ensure we have enough total slots for current layout\n if (totalNumSlots < requiredNumSlots) {\n let numSlotsToCreate = requiredNumSlots - totalNumSlots;\n\n while (numSlotsToCreate > 0) {\n // eslint-disable-next-line no-await-in-loop\n this.slots.video.unused.push(\n await this.receiveSlotManager.allocateSlot(MC.MediaType.VideoMain)\n );\n numSlotsToCreate -= 1;\n }\n }\n\n // move all no longer needed receiver-selected slots to \"unused\"\n this.trimReceiverSelectedSlots();\n\n // move all active speaker slots to \"unused\"\n this.slots.video.unused.push(...this.slots.video.activeSpeaker);\n this.slots.video.activeSpeaker.length = 0;\n\n // allocate the slots to the right panes / pane groups\n this.allocateSlotsToVideoPaneGroups();\n\n LoggerProxy.logger.log(\n `RemoteMediaManager#updateVideoReceiveSlots --> receive slots updated: unused=${this.slots.video.unused.length}, activeSpeaker=${this.slots.video.activeSpeaker.length}, receiverSelected=${this.slots.video.receiverSelected.length}`\n );\n\n // If this is the initial layout, there may be some \"unused\" slots left because of the preallocation\n // done in this.preallocateVideoReceiveSlots(), so release them now\n this.releaseUnusedVideoSlots();\n }\n\n /**\n * Creates new RemoteMedia and RemoteMediaGroup objects for the current layout\n * and sends the media requests for all of them.\n */\n private updateVideoRemoteMediaObjects() {\n // invalidate all the previous remote media objects and cancel their media requests\n this.invalidateCurrentRemoteMedia({audio: false, video: true, commit: false});\n\n // create new remoteMediaGroup objects\n this.media.video.activeSpeakerGroups = {};\n this.media.video.memberPanes = {};\n\n for (const [groupId, group] of Object.entries(this.receiveSlotAllocations.activeSpeaker)) {\n const paneGroupInCurrentLayout = this.currentLayout?.activeSpeakerVideoPaneGroups?.find(\n (groupInLayout) => groupInLayout.id === groupId\n );\n\n if (paneGroupInCurrentLayout) {\n const mediaGroup = new RemoteMediaGroup(\n this.mediaRequestManagers.video,\n group.slots,\n paneGroupInCurrentLayout.priority,\n false,\n {\n preferLiveVideo: this.config.video.preferLiveVideo,\n resolution: paneGroupInCurrentLayout.size,\n }\n );\n\n this.media.video.activeSpeakerGroups[groupId] = mediaGroup;\n } else {\n // this should never happen, because this.receiveSlotAllocations are created based on current layout configuration\n LoggerProxy.logger.warn(\n `a group id ${groupId} from this.receiveSlotAllocations.activeSpeaker cannot be found in the current layout configuration`\n );\n }\n }\n\n // create new remoteMedia objects\n for (const [paneId, slot] of Object.entries(this.receiveSlotAllocations.receiverSelected)) {\n const paneInCurrentLayout = this.currentLayout?.memberVideoPanes?.find(\n (paneInLayout) => paneInLayout.id === paneId\n );\n\n if (paneInCurrentLayout) {\n const remoteMedia = new RemoteMedia(slot, this.mediaRequestManagers.video, {\n resolution: paneInCurrentLayout.size,\n });\n\n if (paneInCurrentLayout.csi) {\n remoteMedia.sendMediaRequest(paneInCurrentLayout.csi, false);\n }\n\n this.media.video.memberPanes[paneId] = remoteMedia;\n } else {\n // this should never happen, because this.receiveSlotAllocations are created based on current layout configuration\n LoggerProxy.logger.warn(\n `a pane id ${paneId} from this.receiveSlotAllocations.receiverSelected cannot be found in the current layout configuration`\n );\n }\n }\n // todo: screenshare (SPARK-377812)\n\n this.mediaRequestManagers.video.commit();\n }\n\n /**\n * Invalidates all remote media objects belonging to currently selected layout\n */\n private invalidateCurrentRemoteMedia(options: {audio: boolean; video: boolean; commit: boolean}) {\n const {audio, video, commit} = options;\n\n if (audio && this.media.audio) {\n this.media.audio.stop(commit);\n }\n if (video) {\n Object.values(this.media.video.activeSpeakerGroups).forEach((remoteMediaGroup) => {\n remoteMediaGroup.stop(false);\n });\n Object.values(this.media.video.memberPanes).forEach((remoteMedia) => {\n remoteMedia.stop(false);\n });\n if (commit) {\n this.mediaRequestManagers.video.commit();\n }\n }\n }\n\n /** emits Event.VideoLayoutChanged */\n private emitVideoLayoutChangedEvent() {\n // todo: at this point the receive slots might still be showing a participant from previous layout, we should\n // wait for our media requests to be fullfilled, but there is no API for that right now (we could wait for source updates\n // but in some cases they might never come, or would need to always make sure to use a new set of receiver slots)\n // for now it's fine to have it like this, we will re-evaluate if it needs improving after more testing\n\n this.emit(\n {\n file: 'multistream/remoteMediaManager',\n function: 'emitVideoLayoutChangedEvent',\n },\n Event.VideoLayoutChanged,\n {\n layoutId: this.currentLayoutId,\n activeSpeakerVideoPanes: this.media.video.activeSpeakerGroups,\n memberVideoPanes: this.media.video.memberPanes,\n screenShareVideo: undefined, // todo: screen share (SPARK-377812)\n }\n );\n }\n\n /**\n * Sets a new CSI on a given remote media object\n *\n * @param {RemoteMedia} remoteMedia remote Media object to modify\n * @param {CSI} csi new CSI value, can be null if we want to stop receiving media\n */\n public setRemoteVideoCsi(remoteMedia: RemoteMedia, csi: CSI | null) {\n if (!Object.values(this.media.video.memberPanes).includes(remoteMedia)) {\n throw new Error('remoteMedia not found');\n }\n\n if (csi) {\n remoteMedia.sendMediaRequest(csi, true);\n } else {\n remoteMedia.cancelMediaRequest(true);\n }\n }\n\n /**\n * Adds a new member video pane to the currently selected layout.\n *\n * Changes to the layout are lost after a layout change.\n *\n * @param {MemberVideoPane} newPane\n * @returns {Promise<RemoteMedia>}\n */\n public async addMemberVideoPane(newPane: MemberVideoPane): Promise<RemoteMedia> {\n if (!this.currentLayout) {\n throw new Error('There is no current layout selected, call start() first');\n }\n\n if (!this.currentLayout?.memberVideoPanes) {\n this.currentLayout.memberVideoPanes = [];\n }\n\n if (newPane.id in this.currentLayout.memberVideoPanes) {\n throw new Error(\n `duplicate pane id ${newPane.id} - this pane already exists in current layout's memberVideoPanes`\n );\n }\n\n this.currentLayout.memberVideoPanes.push(newPane);\n\n const receiveSlot = await this.receiveSlotManager.allocateSlot(MC.MediaType.VideoMain);\n\n this.slots.video.receiverSelected.push(receiveSlot);\n\n const remoteMedia = new RemoteMedia(receiveSlot, this.mediaRequestManagers.video, {\n resolution: newPane.size,\n });\n\n if (newPane.csi) {\n remoteMedia.sendMediaRequest(newPane.csi, true);\n }\n\n this.media.video.memberPanes[newPane.id] = remoteMedia;\n\n return remoteMedia;\n }\n\n /**\n * Removes a member video pane from the currently selected layout.\n *\n * Changes to the layout are lost after a layout change.\n *\n * @param {PaneId} paneId pane id of the pane to remove\n * @returns {Promise<void>}\n */\n public removeMemberVideoPane(paneId: PaneId): Promise<void> {\n if (!this.currentLayout) {\n return Promise.reject(new Error('There is no current layout selected, call start() first'));\n }\n\n if (!this.currentLayout.memberVideoPanes?.find((pane) => pane.id === paneId)) {\n // pane id doesn't exist, so nothing to do\n LoggerProxy.logger.log(\n `RemoteMediaManager#removeMemberVideoPane --> removeMemberVideoPane() called for a non-existent paneId: ${paneId} (pane not found in currentLayout.memberVideoPanes)`\n );\n\n return Promise.resolve();\n }\n\n if (!this.media.video.memberPanes[paneId]) {\n // pane id doesn't exist, so nothing to do\n LoggerProxy.logger.log(\n `RemoteMediaManager#removeMemberVideoPane --> removeMemberVideoPane() called for a non-existent paneId: ${paneId} (pane not found in this.media.video.memberPanes)`\n );\n\n return Promise.resolve();\n }\n\n const remoteMedia = this.media.video.memberPanes[paneId];\n\n const receiveSlot = remoteMedia.getUnderlyingReceiveSlot();\n\n if (receiveSlot) {\n this.receiveSlotManager.releaseSlot(receiveSlot);\n\n const index = this.slots.video.receiverSelected.indexOf(receiveSlot);\n\n if (index >= 0) {\n this.slots.video.receiverSelected.splice(index, 1);\n }\n }\n remoteMedia.stop();\n\n delete this.media.video.memberPanes[paneId];\n delete this.currentLayout.memberVideoPanes?.[paneId];\n\n return Promise.resolve();\n }\n\n /**\n * Pins an active speaker remote media object to the given CSI value. From that moment\n * onwards the remote media will only play audio/video from that specific CSI until\n * unpinActiveSpeakerVideoPane() is called or current layout is changed.\n *\n * @param {RemoteMedia} remoteMedia remote media object reference\n * @param {CSI} csi CSI value to pin to, if undefined, then current CSI value is used\n */\n public pinActiveSpeakerVideoPane(remoteMedia: RemoteMedia, csi?: CSI): void {\n const remoteMediaGroup = Object.values(this.media.video.activeSpeakerGroups).find((group) =>\n group.includes(remoteMedia, 'unpinned')\n );\n\n if (!remoteMediaGroup) {\n throw new Error(\n 'remoteMedia not found among the unpinned remote media from any active speaker group'\n );\n }\n\n remoteMediaGroup.pin(remoteMedia, csi);\n }\n\n /**\n * Unpins a remote media object from the fixed CSI value it was pinned to.\n *\n * @param {RemoteMedia} remoteMedia remote media object reference\n */\n public unpinActiveSpeakerVideoPane(remoteMedia: RemoteMedia) {\n const remoteMediaGroup = Object.values(this.media.video.activeSpeakerGroups).find((group) =>\n group.includes(remoteMedia, 'pinned')\n );\n\n if (!remoteMediaGroup) {\n throw new Error(\n 'remoteMedia not found among the pinned remote media from any active speaker group'\n );\n }\n\n remoteMediaGroup.unpin(remoteMedia);\n }\n\n /**\n * Returns true if a given remote media object belongs to an active speaker group and has been pinned.\n * Throws an error if the remote media object doesn't belong to any active speaker remote media group.\n *\n * @param {RemoteMedia} remoteMedia remote media object\n * @returns {boolean}\n */\n public isPinned(remoteMedia: RemoteMedia) {\n const remoteMediaGroup = Object.values(this.media.video.activeSpeakerGroups).find((group) =>\n group.includes(remoteMedia)\n );\n\n if (!remoteMediaGroup) {\n throw new Error(\n 'remoteMedia not found among any remote media (pinned or unpinned) from any active speaker group'\n );\n }\n\n return remoteMediaGroup.isPinned(remoteMedia);\n }\n}\n"],"mappings":"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"}
@@ -42,16 +42,12 @@ var _reconnection = _interopRequireDefault(require("../common/errors/reconnectio
42
42
 
43
43
  var _reconnectionInProgress = _interopRequireDefault(require("../common/errors/reconnection-in-progress"));
44
44
 
45
- var _peerConnectionManager = _interopRequireDefault(require("../peer-connection-manager"));
46
-
47
45
  var _config = require("../metrics/config");
48
46
 
49
47
  var _media = _interopRequireDefault(require("../media"));
50
48
 
51
49
  var _metrics = _interopRequireDefault(require("../metrics"));
52
50
 
53
- var _collection = _interopRequireDefault(require("../roap/collection"));
54
-
55
51
  function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = _Reflect$construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
56
52
 
57
53
  function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !_Reflect$construct) return false; if (_Reflect$construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(_Reflect$construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
@@ -178,30 +174,40 @@ var ReconnectionManager = /*#__PURE__*/function () {
178
174
  this.reset();
179
175
  }
180
176
  /**
181
- * Sets the iceState to connected and clears any disconnect timeouts and
182
- * related timeout data within the iceState.
183
- *
184
- * @returns {undefined}
185
177
  * @public
186
178
  * @memberof ReconnectionManager
179
+ * @returns {void}
187
180
  */
188
181
 
189
182
 
190
183
  (0, _createClass2.default)(ReconnectionManager, [{
184
+ key: "resetReconnectionTimer",
185
+ value: function resetReconnectionTimer() {
186
+ this.iceState.resolve();
187
+
188
+ this.iceState.resolve = function () {};
189
+
190
+ if (this.iceState.timer) {
191
+ clearTimeout(this.iceState.timer);
192
+ delete this.iceState.timer;
193
+ }
194
+ }
195
+ /**
196
+ * Sets the iceState to connected and clears any disconnect timeouts and
197
+ * related timeout data within the iceState.
198
+ *
199
+ * @returns {undefined}
200
+ * @public
201
+ * @memberof ReconnectionManager
202
+ */
203
+
204
+ }, {
191
205
  key: "iceReconnected",
192
206
  value: function iceReconnected() {
193
207
  if (this.iceState.disconnected) {
194
208
  _loggerProxy.default.logger.log('ReconnectionManager:index#iceReconnected --> ice has reconnected');
195
209
 
196
- this.iceState.resolve();
197
-
198
- this.iceState.resolve = function () {};
199
-
200
- if (this.iceState.timer) {
201
- clearTimeout(this.iceState.timer);
202
- delete this.iceState.timer;
203
- }
204
-
210
+ this.resetReconnectionTimer();
205
211
  this.iceState.disconnected = false;
206
212
  }
207
213
  }
@@ -266,6 +272,17 @@ var ReconnectionManager = /*#__PURE__*/function () {
266
272
  this.reset();
267
273
  this.meeting = null;
268
274
  }
275
+ /**
276
+ * @public
277
+ * @memberof ReconnectionManager
278
+ * @returns {Boolean} true if reconnection operation is in progress
279
+ */
280
+
281
+ }, {
282
+ key: "isReconnectInProgress",
283
+ value: function isReconnectInProgress() {
284
+ return this.status === _constants.RECONNECTION.STATE.IN_PROGRESS;
285
+ }
269
286
  /**
270
287
  * @returns {Boolean}
271
288
  * @throws {ReconnectionError}
@@ -567,7 +584,6 @@ var ReconnectionManager = /*#__PURE__*/function () {
567
584
  value: function () {
568
585
  var _rejoinMeeting = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3() {
569
586
  var wasSharing,
570
- previousCorrelationId,
571
587
  _args3 = arguments;
572
588
  return _regenerator.default.wrap(function _callee3$(_context3) {
573
589
  while (1) {
@@ -578,17 +594,14 @@ var ReconnectionManager = /*#__PURE__*/function () {
578
594
 
579
595
  _loggerProxy.default.logger.info('ReconnectionManager:index#rejoinMeeting --> attemping meeting rejoin');
580
596
 
581
- previousCorrelationId = this.meeting.correlationId;
582
- _context3.next = 6;
597
+ _context3.next = 5;
583
598
  return this.meeting.join({
584
599
  rejoin: true
585
600
  });
586
601
 
587
- case 6:
602
+ case 5:
588
603
  _loggerProxy.default.logger.info('ReconnectionManager:index#rejoinMeeting --> meeting rejoined');
589
604
 
590
- _collection.default.deleteSession(previousCorrelationId);
591
-
592
605
  if (wasSharing) {
593
606
  // Stop the share streams if user tried to rejoin
594
607
  _media.default.stopTracks(this.meeting.mediaProperties.shareTrack);
@@ -609,26 +622,26 @@ var ReconnectionManager = /*#__PURE__*/function () {
609
622
  });
610
623
  }
611
624
 
612
- _context3.next = 23;
625
+ _context3.next = 21;
613
626
  break;
614
627
 
615
- case 11:
616
- _context3.prev = 11;
628
+ case 9:
629
+ _context3.prev = 9;
617
630
  _context3.t0 = _context3["catch"](1);
618
631
  this.rejoinAttempts += 1;
619
632
 
620
633
  if (!(this.rejoinAttempts <= this.maxRejoinAttempts)) {
621
- _context3.next = 19;
634
+ _context3.next = 17;
622
635
  break;
623
636
  }
624
637
 
625
638
  _loggerProxy.default.logger.info("ReconnectionManager:index#rejoinMeeting --> Unable to rejoin meeting, attempt #".concat(this.rejoinAttempts, ", retrying."), _context3.t0);
626
639
 
627
640
  this.rejoinMeeting();
628
- _context3.next = 23;
641
+ _context3.next = 21;
629
642
  break;
630
643
 
631
- case 19:
644
+ case 17:
632
645
  _loggerProxy.default.logger.error('ReconnectionManager:index#rejoinMeeting --> Unable to rejoin meeting after max attempts.', _context3.t0);
633
646
 
634
647
  _metrics.default.sendBehavioralMetric(_constants2.default.MEETING_MAX_REJOIN_FAILURE, {
@@ -640,29 +653,29 @@ var ReconnectionManager = /*#__PURE__*/function () {
640
653
  this.status = _constants.RECONNECTION.STATE.FAILURE;
641
654
  throw _context3.t0;
642
655
 
643
- case 23:
644
- _context3.prev = 23;
645
- _context3.next = 26;
656
+ case 21:
657
+ _context3.prev = 21;
658
+ _context3.next = 24;
646
659
  return this.reconnectMedia();
647
660
 
648
- case 26:
649
- _context3.next = 32;
661
+ case 24:
662
+ _context3.next = 30;
650
663
  break;
651
664
 
652
- case 28:
653
- _context3.prev = 28;
654
- _context3.t1 = _context3["catch"](23);
665
+ case 26:
666
+ _context3.prev = 26;
667
+ _context3.t1 = _context3["catch"](21);
655
668
 
656
669
  _loggerProxy.default.logger.error('ReconnectionManager:index#rejoinMeeting --> Unable to reestablish media after rejoining.', _context3.t1);
657
670
 
658
671
  throw _context3.t1;
659
672
 
660
- case 32:
673
+ case 30:
661
674
  case "end":
662
675
  return _context3.stop();
663
676
  }
664
677
  }
665
- }, _callee3, this, [[1, 11], [23, 28]]);
678
+ }, _callee3, this, [[1, 9], [21, 26]]);
666
679
  }));
667
680
 
668
681
  function rejoinMeeting() {
@@ -679,31 +692,45 @@ var ReconnectionManager = /*#__PURE__*/function () {
679
692
 
680
693
  }, {
681
694
  key: "reconnectMedia",
682
- value: function reconnectMedia() {
683
- var _this4 = this;
695
+ value: function () {
696
+ var _reconnectMedia = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4() {
697
+ var turnServerInfo, mc;
698
+ return _regenerator.default.wrap(function _callee4$(_context4) {
699
+ while (1) {
700
+ switch (_context4.prev = _context4.next) {
701
+ case 0:
702
+ _loggerProxy.default.logger.log('ReconnectionManager:index#reconnectMedia --> Begin reestablishment of media'); // we are not simply calling this.meeting.mediaProperties.webrtcMediaConnection.reconnect(),
703
+ // but instead manually closing and creating new media connection, because we need to do the TURN discovery again
684
704
 
685
- _loggerProxy.default.logger.log('ReconnectionManager:index#reconnectMedia --> Begin reestablishment of media');
686
705
 
687
- return ReconnectionManager.setupPeerConnection(this.meeting).then(function () {
688
- return _media.default.attachMedia(_this4.meeting.mediaProperties, {
689
- meetingId: _this4.meeting.id,
690
- remoteQualityLevel: _this4.meeting.mediaProperties.remoteQualityLevel,
691
- enableRtx: _this4.meeting.config.enableRtx,
692
- enableExtmap: _this4.meeting.config.enableExtmap
693
- });
694
- }).then(function (peerConnection) {
695
- return _this4.meeting.setRemoteStream(peerConnection);
696
- }).then(function () {
697
- _loggerProxy.default.logger.log('ReconnectionManager:index#reconnectMedia --> Sending ROAP media request');
698
-
699
- return _this4.meeting.roap.sendRoapMediaRequest({
700
- sdp: _this4.meeting.mediaProperties.peerConnection.sdp,
701
- roapSeq: _this4.meeting.roapSeq,
702
- meeting: _this4.meeting,
703
- reconnect: true
704
- });
705
- });
706
- }
706
+ _context4.next = 3;
707
+ return this.meeting.closePeerConnections();
708
+
709
+ case 3:
710
+ this.meeting.mediaProperties.unsetPeerConnection();
711
+ _context4.next = 6;
712
+ return this.meeting.roap.doTurnDiscovery(this.meeting, true);
713
+
714
+ case 6:
715
+ turnServerInfo = _context4.sent;
716
+ mc = this.meeting.createMediaConnection(turnServerInfo);
717
+ this.meeting.statsAnalyzer.updateMediaConnection(mc);
718
+ return _context4.abrupt("return", mc.initiateOffer());
719
+
720
+ case 10:
721
+ case "end":
722
+ return _context4.stop();
723
+ }
724
+ }
725
+ }, _callee4, this);
726
+ }));
727
+
728
+ function reconnectMedia() {
729
+ return _reconnectMedia.apply(this, arguments);
730
+ }
731
+
732
+ return reconnectMedia;
733
+ }()
707
734
  /**
708
735
  * Attempt to Reconnect Mercury Websocket
709
736
  * @returns {Promise}
@@ -714,68 +741,68 @@ var ReconnectionManager = /*#__PURE__*/function () {
714
741
  }, {
715
742
  key: "reconnectMercuryWebSocket",
716
743
  value: function () {
717
- var _reconnectMercuryWebSocket = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4() {
718
- return _regenerator.default.wrap(function _callee4$(_context4) {
744
+ var _reconnectMercuryWebSocket = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5() {
745
+ return _regenerator.default.wrap(function _callee5$(_context5) {
719
746
  while (1) {
720
- switch (_context4.prev = _context4.next) {
747
+ switch (_context5.prev = _context5.next) {
721
748
  case 0:
722
749
  _loggerProxy.default.logger.info('ReconnectionManager:index#reconnectMercuryWebSocket --> Reconnecting websocket.'); // First, attempt to disconnect if we think we are already connected.
723
750
 
724
751
 
725
752
  if (!this.webex.internal.mercury.connected) {
726
- _context4.next = 13;
753
+ _context5.next = 13;
727
754
  break;
728
755
  }
729
756
 
730
757
  _loggerProxy.default.logger.info('ReconnectionManager:index#reconnectMercuryWebSocket --> Disconnecting existing websocket.');
731
758
 
732
- _context4.prev = 3;
733
- _context4.next = 6;
759
+ _context5.prev = 3;
760
+ _context5.next = 6;
734
761
  return this.webex.internal.mercury.disconnect();
735
762
 
736
763
  case 6:
737
764
  _loggerProxy.default.logger.info('ReconnectionManager:index#reconnectMercuryWebSocket --> Websocket disconnected successfully.');
738
765
 
739
- _context4.next = 13;
766
+ _context5.next = 13;
740
767
  break;
741
768
 
742
769
  case 9:
743
- _context4.prev = 9;
744
- _context4.t0 = _context4["catch"](3);
770
+ _context5.prev = 9;
771
+ _context5.t0 = _context5["catch"](3);
745
772
 
746
773
  // If we can't disconnect, the sdk is in such a bad state that reconnecting is not going to happen.
747
- _loggerProxy.default.logger.error('ReconnectionManager:index#reconnectMercuryWebSocket --> Unable to disconnect from websocket, giving up.', _context4.t0);
774
+ _loggerProxy.default.logger.error('ReconnectionManager:index#reconnectMercuryWebSocket --> Unable to disconnect from websocket, giving up.', _context5.t0);
748
775
 
749
- throw _context4.t0;
776
+ throw _context5.t0;
750
777
 
751
778
  case 13:
752
- _context4.prev = 13;
779
+ _context5.prev = 13;
753
780
 
754
781
  _loggerProxy.default.logger.info('ReconnectionManager:index#reconnectMercuryWebSocket --> Connecting websocket.');
755
782
 
756
- _context4.next = 17;
783
+ _context5.next = 17;
757
784
  return this.webex.internal.mercury.connect();
758
785
 
759
786
  case 17:
760
787
  _loggerProxy.default.logger.info('ReconnectionManager:index#reconnectMercuryWebSocket --> Websocket connected successfully.');
761
788
 
762
- _context4.next = 24;
789
+ _context5.next = 24;
763
790
  break;
764
791
 
765
792
  case 20:
766
- _context4.prev = 20;
767
- _context4.t1 = _context4["catch"](13);
793
+ _context5.prev = 20;
794
+ _context5.t1 = _context5["catch"](13);
768
795
 
769
- _loggerProxy.default.logger.error('ReconnectionManager:index#reconnectMercuryWebSocket --> Unable to connect to websocket, giving up.', _context4.t1);
796
+ _loggerProxy.default.logger.error('ReconnectionManager:index#reconnectMercuryWebSocket --> Unable to connect to websocket, giving up.', _context5.t1);
770
797
 
771
- throw _context4.t1;
798
+ throw _context5.t1;
772
799
 
773
800
  case 24:
774
801
  case "end":
775
- return _context4.stop();
802
+ return _context5.stop();
776
803
  }
777
804
  }
778
- }, _callee4, this, [[3, 9], [13, 20]]);
805
+ }, _callee5, this, [[3, 9], [13, 20]]);
779
806
  }));
780
807
 
781
808
  function reconnectMercuryWebSocket() {
@@ -784,54 +811,6 @@ var ReconnectionManager = /*#__PURE__*/function () {
784
811
 
785
812
  return reconnectMercuryWebSocket;
786
813
  }()
787
- /**
788
- * @param {Meeting} meeting
789
- * @returns {undefined}
790
- * @private
791
- * @memberof ReconnectionManager
792
- */
793
-
794
- }], [{
795
- key: "setupPeerConnection",
796
- value: function () {
797
- var _setupPeerConnection = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5(meeting) {
798
- var turnInfo;
799
- return _regenerator.default.wrap(function _callee5$(_context5) {
800
- while (1) {
801
- switch (_context5.prev = _context5.next) {
802
- case 0:
803
- _loggerProxy.default.logger.log('ReconnectionManager:index#setupPeerConnection --> Begin resetting peer connection'); // close pcs, unset to null and create a new one with out closing any streams
804
-
805
-
806
- _peerConnectionManager.default.close(meeting.mediaProperties.peerConnection);
807
-
808
- meeting.mediaProperties.unsetPeerConnection();
809
- _context5.next = 5;
810
- return meeting.roap.doTurnDiscovery(meeting, true);
811
-
812
- case 5:
813
- turnInfo = _context5.sent;
814
- meeting.mediaProperties.reInitiatePeerconnection(turnInfo);
815
-
816
- _peerConnectionManager.default.setPeerConnectionEvents(meeting); // update the peerconnection in the stats manager when ever we reconnect
817
-
818
-
819
- meeting.statsAnalyzer.updatePeerconnection(meeting.mediaProperties.peerConnection);
820
-
821
- case 9:
822
- case "end":
823
- return _context5.stop();
824
- }
825
- }
826
- }, _callee5);
827
- }));
828
-
829
- function setupPeerConnection(_x2) {
830
- return _setupPeerConnection.apply(this, arguments);
831
- }
832
-
833
- return setupPeerConnection;
834
- }()
835
814
  }]);
836
815
  return ReconnectionManager;
837
816
  }();