@reactoo/watchtogether-sdk-js 2.7.38 → 2.7.40

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.7.38-beta.3
3
+ * @version 2.7.39
4
4
  */
5
5
  (function webpackUniversalModuleDefinition(root, factory) {
6
6
  if(typeof exports === 'object' && typeof module === 'object')
@@ -25494,7 +25494,10 @@ class Iot {
25494
25494
  }
25495
25495
 
25496
25496
  // Find a suitable topic for the connection check
25497
- const suitableTopic = Array.from(this.subscribedTopics).find(topic => topic.indexOf('user') > -1);
25497
+ let suitableTopic = Array.from(this.subscribedTopics).find(topic => topic.indexOf('user') > -1);
25498
+ if (!suitableTopic) {
25499
+ suitableTopic = Array.from(this.subscribedTopics).find(topic => topic.indexOf('room') > -1 && topic !== 'wt/instanceroom/reactooDemo');
25500
+ }
25498
25501
  if (!suitableTopic) {
25499
25502
  reject(new Error('No suitable topic found for connection check'));
25500
25503
  return;
@@ -25531,7 +25534,10 @@ class Iot {
25531
25534
  return;
25532
25535
  }
25533
25536
  // Find a suitable topic for the connection check
25534
- const suitableTopic = Array.from(this.subscribedTopics).find(topic => topic.indexOf('user') > -1);
25537
+ let suitableTopic = Array.from(this.subscribedTopics).find(topic => topic.indexOf('user') > -1);
25538
+ if (!suitableTopic) {
25539
+ suitableTopic = Array.from(this.subscribedTopics).find(topic => topic.indexOf('room') > -1 && topic !== 'wt/instanceroom/reactooDemo');
25540
+ }
25535
25541
  if (!suitableTopic) {
25536
25542
  this.log('No suitable topic found for keep alive message');
25537
25543
  return;
@@ -27167,13 +27173,13 @@ class RoomSession {
27167
27173
  let directionDecision = 0;
27168
27174
  if (((_p$webrtcStuff4 = p.webrtcStuff) === null || _p$webrtcStuff4 === void 0 ? void 0 : (_p$webrtcStuff4$stats = _p$webrtcStuff4.stats) === null || _p$webrtcStuff4$stats === void 0 ? void 0 : (_p$webrtcStuff4$stats2 = _p$webrtcStuff4$stats[mid]) === null || _p$webrtcStuff4$stats2 === void 0 ? void 0 : _p$webrtcStuff4$stats2.length) > this._upStatsLength) {
27169
27175
  const upMedianStats = this._calculateMedianStats(p.webrtcStuff.stats[mid].slice(this._upStatsLength * -1));
27170
- 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?.freezeCountSinceLast < 3 */) {
27176
+ if ((upMedianStats === null || upMedianStats === void 0 ? void 0 : upMedianStats.freezeDurationSinceLast) < this._upStatsLength * this._statsInterval * 0.33 / 1000 /* && upMedianStats?.freezeCountSinceLast < 3 */) {
27171
27177
  directionDecision = 1;
27172
27178
  }
27173
27179
  }
27174
27180
  if (((_p$webrtcStuff5 = p.webrtcStuff) === null || _p$webrtcStuff5 === void 0 ? void 0 : (_p$webrtcStuff5$stats = _p$webrtcStuff5.stats) === null || _p$webrtcStuff5$stats === void 0 ? void 0 : (_p$webrtcStuff5$stats2 = _p$webrtcStuff5$stats[mid]) === null || _p$webrtcStuff5$stats2 === void 0 ? void 0 : _p$webrtcStuff5$stats2.length) > this._downStatsLength) {
27175
27181
  const downMedianStats = this._calculateMedianStats(p.webrtcStuff.stats[mid].slice(this._downStatsLength * -1));
27176
- 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?.freezeCountSinceLast > 5 || downMedianStats?.jitter > maxJitter(settingsForCurrentSubstream.maxFramerate) */) {
27182
+ if ((downMedianStats === null || downMedianStats === void 0 ? void 0 : downMedianStats.freezeDurationSinceLast) > this._downStatsLength * this._statsInterval * 0.33 / 1000 /* || downMedianStats?.freezeCountSinceLast > 5 || downMedianStats?.jitter > maxJitter(settingsForCurrentSubstream.maxFramerate) */) {
27177
27183
  directionDecision = -1;
27178
27184
  }
27179
27185
  }
@@ -27585,10 +27591,6 @@ class RoomSession {
27585
27591
  hasVideoTrack: !!(config.stream && config.stream.getVideoTracks().length)
27586
27592
  });
27587
27593
  };
27588
- let mutedTimerId = {};
27589
- let waitPeriod = 300; // ms
27590
- let screenShareWaitPeriod = 5000; // ms
27591
-
27592
27594
  event.track.onmute = ev => {
27593
27595
  var _decodeJanusDisplay23, _decodeJanusDisplay24;
27594
27596
  this._log('Remote track muted');
@@ -27609,34 +27611,6 @@ class RoomSession {
27609
27611
  track: ev.target,
27610
27612
  muted: true
27611
27613
  });
27612
-
27613
- // when a track is muted, we try to switch to lower quality substream, but not for screen sharing
27614
-
27615
- if (!this.simulcast) {
27616
- return;
27617
- }
27618
- const wPeriod = source.indexOf('screen') > -1 ? screenShareWaitPeriod : waitPeriod;
27619
- if (!mutedTimerId[mid]) {
27620
- mutedTimerId[mid] = setTimeout(() => {
27621
- var _handle$webrtcStuff5, _handle$webrtcStuff5$;
27622
- mutedTimerId[mid] = null;
27623
- const simulcastConfigForSource = this._findSimulcastConfig(source, this.simulcastSettings);
27624
- const simulcastMode = ((_handle$webrtcStuff5 = handle.webrtcStuff) === null || _handle$webrtcStuff5 === void 0 ? void 0 : (_handle$webrtcStuff5$ = _handle$webrtcStuff5.overriddenSimulcastMode[mid]) === null || _handle$webrtcStuff5$ === void 0 ? void 0 : _handle$webrtcStuff5$.mode) || (simulcastConfigForSource === null || simulcastConfigForSource === void 0 ? void 0 : simulcastConfigForSource.mode);
27625
- const {
27626
- simulcastBitrates
27627
- } = handle.webrtcStuff.tracksMap.find(t => t.mid === mid) || {};
27628
-
27629
- // track is gone
27630
- if (!simulcastBitrates) {
27631
- return;
27632
- }
27633
- const currentSubstream = handle.webrtcStuff.selectedSubstream[mid];
27634
- if (!(simulcastMode === 'browserControlled') && ev.target.kind === 'video' && currentSubstream < simulcastBitrates.length - 1) {
27635
- this._log('Attempting to down the quality due to track muted');
27636
- this.selectSubStream(handle.handleId, currentSubstream + 1, undefined, mid, false).catch(reason => this._log(`Changing substream for mid: ${mid} failed. Reason: ${reason}`));
27637
- }
27638
- }, wPeriod);
27639
- }
27640
27614
  };
27641
27615
  event.track.onunmute = ev => {
27642
27616
  var _decodeJanusDisplay25, _decodeJanusDisplay26;
@@ -27644,10 +27618,6 @@ class RoomSession {
27644
27618
  let transceiver = config.pc.getTransceivers().find(t => t.receiver.track === ev.target);
27645
27619
  let mid = transceiver.mid || ev.target.id;
27646
27620
  let source = Object.keys(config.streamMap).find(key => config.streamMap[key].includes(ev.target.id));
27647
- if (mutedTimerId[mid]) {
27648
- clearTimeout(mutedTimerId[mid]);
27649
- mutedTimerId[mid] = null;
27650
- }
27651
27621
  this.emit('remoteTrackMuted', {
27652
27622
  id: handle.handleId,
27653
27623
  mid,
@@ -27966,6 +27936,61 @@ class RoomSession {
27966
27936
  });
27967
27937
  });
27968
27938
  }
27939
+ _addSimulcastToSDP(sdp) {
27940
+ // Split SDP into lines
27941
+ let sdpLines = sdp.split('\n');
27942
+
27943
+ // Find the index of the video m-line
27944
+ let videoIndex = sdpLines.findIndex(line => line.startsWith('m=video'));
27945
+ if (videoIndex === -1) {
27946
+ // No video m-line found
27947
+ return sdp;
27948
+ }
27949
+
27950
+ // We need to insert the lines after the mid attribute
27951
+ // Find the index of the 'a=mid' line in the video section
27952
+ let midIndex = sdpLines.findIndex((line, index) => index > videoIndex && line.startsWith('a=mid:'));
27953
+ if (midIndex === -1) {
27954
+ // No 'a=mid' line found in video m-section
27955
+ return sdp;
27956
+ }
27957
+
27958
+ // Prepare the simulcast attributes
27959
+ const simulcastLines = ['a=rid:l recv', 'a=rid:m recv', 'a=rid:h recv', 'a=simulcast:recv l;m;h'];
27960
+
27961
+ // Prepare the extmap attributes for RID and Repaired RID
27962
+ const extmapId = sdpLines.reduce((maxId, line) => {
27963
+ const match = line.match(/a=extmap:(\d+)/);
27964
+ return match ? Math.max(maxId, parseInt(match[1])) : maxId;
27965
+ }, 0);
27966
+ const extmapLines = [`a=extmap:${extmapId + 1} urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id`, `a=extmap:${extmapId + 2} urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id`];
27967
+
27968
+ // Insert the extmap lines after the last existing extmap in the video section
27969
+ let lastExtmapIndex = midIndex;
27970
+ for (let i = midIndex + 1; i < sdpLines.length; i++) {
27971
+ if (sdpLines[i].startsWith('a=extmap:')) {
27972
+ lastExtmapIndex = i;
27973
+ } else if (sdpLines[i].startsWith('a=')) {
27974
+ // Reached another attribute
27975
+ break;
27976
+ }
27977
+ }
27978
+
27979
+ // Check if the attributes are already present
27980
+ const hasSimulcast = sdpLines.some(line => line.startsWith('a=simulcast'));
27981
+ const hasRidExtmap = sdpLines.some(line => line.includes('urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id'));
27982
+ if (!hasRidExtmap) {
27983
+ // Insert the extmap lines
27984
+ sdpLines.splice(lastExtmapIndex + 1, 0, ...extmapLines);
27985
+ }
27986
+ if (!hasSimulcast) {
27987
+ // Insert the simulcast lines after the 'a=mid' line
27988
+ sdpLines.splice(midIndex + 1, 0, ...simulcastLines);
27989
+ }
27990
+
27991
+ // Return the modified SDP
27992
+ return sdpLines.join('\n');
27993
+ }
27969
27994
  _publishRemote(handleId, jsep) {
27970
27995
  let handle = this._getHandle(handleId);
27971
27996
  if (!handle) {
@@ -27979,6 +28004,12 @@ class RoomSession {
27979
28004
  this._webrtc(handleId, true);
27980
28005
  let config = handle.webrtcStuff;
27981
28006
  if (jsep) {
28007
+ // Just For Debugging
28008
+ // Munge the SDP before setting the remote description
28009
+ // if (jsep && jsep.sdp) {
28010
+ // jsep.sdp = this._addSimulcastToSDP(jsep.sdp);
28011
+ // }
28012
+
27982
28013
  return config.pc.setRemoteDescription(jsep).then(() => {
27983
28014
  config.remoteSdp = jsep.sdp;
27984
28015
  // Any trickle candidate we cached?
@@ -28822,9 +28853,9 @@ class RoomSession {
28822
28853
  remoteUsersCache.forEach(r => {
28823
28854
  const handle = this._getHandle(null, null, null, r.userId);
28824
28855
  if (this._participantShouldSubscribe(r.userId)) {
28825
- var _handle$webrtcStuff6;
28856
+ var _handle$webrtcStuff5;
28826
28857
  // todo: do a nicer flag to indicate inactive handle than just checking for pc
28827
- if (!handle || !((_handle$webrtcStuff6 = handle.webrtcStuff) !== null && _handle$webrtcStuff6 !== void 0 && _handle$webrtcStuff6.pc)) {
28858
+ if (!handle || !((_handle$webrtcStuff5 = handle.webrtcStuff) !== null && _handle$webrtcStuff5 !== void 0 && _handle$webrtcStuff5.pc)) {
28828
28859
  this._log('Subscribing to ', r.userId);
28829
28860
  this._createParticipant(r.userId, r.id).then(handle => {
28830
28861
  this._updateParticipantsTrackData(handle.handleId, r.streams);