@reactoo/watchtogether-sdk-js 2.6.95 → 2.6.97

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.
@@ -218,13 +218,41 @@
218
218
  })
219
219
  .then(r => Instance.room.createSession({constructId, roomId:r.roomId, pinHash: r.pinHash, role:'participant', options: {
220
220
  simulcast: true,
221
- simulcastMode: {default: 'controlled', screen: 'manual'}, // controlled, manual, auto ... key is the device source (default = all)
222
- simulcastDefaultManualSubstream: {default:0, screen: 0}, // 2 lowest quality, 0 highest quality ... key is the device source (default = all)
223
- // those are for videowall (see that 4 fps preview for producer panel)
221
+ // controlled, manual, browserControlled ... key is the device source (default = all)
222
+ simulcastMode: {
223
+ "default": "controlled",
224
+ "screen": "manual"
225
+ },
226
+ // 2 lowest quality, 0 highest quality ... key is the device source (default = all)
227
+ simulcastDefaultManualSubstream: {
228
+ "screen": 0,
229
+ "default": 0
230
+ },
231
+
224
232
  simulcastBitrates: [
225
- { rid: 'l', active: true, maxBitrate: 180000, maxFramerate: 4, scaleResolutionDownBy: 4, priority: "low" },
226
- { rid: 'm', active: true, maxBitrate: 800000, maxFramerate: 30, scaleResolutionDownBy: 3, priority: "low" },
227
- { rid: 'h', active: true, maxBitrate: 1700000, maxFramerate: 30, priority: "low" }
233
+ {
234
+ "rid": "l",
235
+ "active": true,
236
+ "maxBitrate": 180000,
237
+ "maxFramerate": 20,
238
+ "scaleResolutionDownBy": 3.3333333333333335,
239
+ "priority": "low"
240
+ },
241
+ {
242
+ "rid": "m",
243
+ "active": true,
244
+ "maxBitrate": 500000,
245
+ "maxFramerate": 25,
246
+ "scaleResolutionDownBy": 1.3333333333333335,
247
+ "priority": "low"
248
+ },
249
+ {
250
+ "rid": "h",
251
+ "active": true,
252
+ "maxBitrate": 2000000,
253
+ "maxFramerate": 30,
254
+ "priority": "low"
255
+ }
228
256
  ],
229
257
  //subscriptionRules: {participant: {videoWall: [], watchTogether: []}}
230
258
  }}))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reactoo/watchtogether-sdk-js",
3
- "version": "2.6.95",
3
+ "version": "2.6.97",
4
4
  "description": "Javascript SDK for Reactoo",
5
5
  "main": "src/index.js",
6
6
  "unpkg": "dist/watchtogether-sdk.min.js",
@@ -182,14 +182,14 @@ class RoomSession {
182
182
  this.sessiontype = type;
183
183
  this.initialBitrate = 0;
184
184
  this.simulcast = false;
185
- this.simulcastMode = 'controlled'; // controlled, manual, auto
185
+ this.simulcastMode = 'controlled'; // controlled, manual, browserControlled
186
186
  this.simulcastDefaultManualSubstream = 0; // 0 = maximum quality
187
187
 
188
188
  // ordered from low to high
189
189
  this.simulcastBitrates = [
190
190
  { rid: 'l', active: true, maxBitrate: 180000, maxFramerate: 20, scaleResolutionDownBy: 3.3333333333333335, priority: "low" },
191
- { rid: 'm', active: true, maxBitrate: 800000, maxFramerate: 25, scaleResolutionDownBy: 1.3333333333333333, priority: "low" },
192
- { rid: 'h', active: true, maxBitrate: 1700000, maxFramerate: 30, priority: "low" },
191
+ { rid: 'm', active: true, maxBitrate: 500000, maxFramerate: 25, scaleResolutionDownBy: 1.3333333333333335, priority: "low" },
192
+ { rid: 'h', active: true, maxBitrate: 2000000, maxFramerate: 30, priority: "low" },
193
193
  ];
194
194
  this.recordingFilename = null;
195
195
  this.pluginName = RoomSession.sessionTypes[type];
@@ -209,8 +209,8 @@ class RoomSession {
209
209
  this.isMuted = [];
210
210
  this.isVideoEnabled = false;
211
211
  this.isAudioEnabed = false;
212
- this._statsMaxLength = 16;
213
- this._upStatsLength = 15;
212
+ this._statsMaxLength = 31;
213
+ this._upStatsLength = 30;
214
214
  this._downStatsLength = 5;
215
215
  this._statsTimeoutStopped = true;
216
216
  this._statsTimeoutId = null;
@@ -968,7 +968,7 @@ class RoomSession {
968
968
  stats: {},
969
969
  selectedSubstream: {},
970
970
  initialSimulcastSubstreamBeenSet: {},
971
- forcedAutoMode:{},
971
+ forcedBrowserControlledMode:{},
972
972
  };
973
973
 
974
974
  if (handleId === this.handleId) {
@@ -1025,7 +1025,7 @@ class RoomSession {
1025
1025
  stats: {},
1026
1026
  selectedSubstream: {},
1027
1027
  initialSimulcastSubstreamBeenSet: {},
1028
- forcedAutoMode:{},
1028
+ forcedBrowserControlledMode:{},
1029
1029
  }
1030
1030
  };
1031
1031
  this._participants.push(handle);
@@ -1553,6 +1553,9 @@ class RoomSession {
1553
1553
  loop()
1554
1554
  }
1555
1555
 
1556
+ // This method completely ignores temporal layers
1557
+ // 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
1558
+
1556
1559
  _enableSubstreamAutoSelect() {
1557
1560
 
1558
1561
  if(!this.simulcast) {
@@ -1590,7 +1593,7 @@ class RoomSession {
1590
1593
  ? (this.simulcastMode[source] !== undefined ? this.simulcastMode[source] : this.simulcastMode['default'])
1591
1594
  : this.simulcastMode;
1592
1595
 
1593
- if((simulcastMode === 'auto' || p.webrtcStuff.forcedAutoMode[mid])) {
1596
+ if((simulcastMode === 'browserControlled' || p.webrtcStuff.forcedBrowserControlledMode[mid])) {
1594
1597
  // do nothing
1595
1598
  }
1596
1599
 
@@ -1600,6 +1603,7 @@ class RoomSession {
1600
1603
  if(defaultSelectedSubstream !== undefined && defaultSelectedSubstream !== null && defaultSelectedSubstream !== currentSubstream) {
1601
1604
  this._log('Attempting to force substream quality', defaultSelectedSubstream);
1602
1605
  this.selectSubStream(p.handleId, defaultSelectedSubstream, undefined, mid, false)
1606
+ .catch((reason) => this._log(`Changing substream for mid: ${mid} failed. Reason: ${reason}`));
1603
1607
  }
1604
1608
  }
1605
1609
 
@@ -1623,18 +1627,23 @@ class RoomSession {
1623
1627
 
1624
1628
  if(directionDecision === -1) {
1625
1629
  if(currentSubstream < simulcastBitrates.length - 1) {
1626
- this._log('Attempting to down the quality', currentSubstream + 1);
1630
+ this._log('Attempting to down the quality for mid: ', mid, ' quality:', currentSubstream + 1);
1627
1631
  this._resetStats(p.handleId, mid);
1628
1632
  this.selectSubStream(p.handleId, currentSubstream + 1, undefined, mid, false)
1633
+ .catch((reason) => this._log(`Changing substream for mid: ${mid} failed. Reason: ${reason}`));
1629
1634
  }
1630
1635
  }
1631
1636
  else if (directionDecision === 1) {
1632
1637
  if(currentSubstream > 0) {
1633
- this._log('Attempting to up the quality', currentSubstream - 1);
1638
+ this._log('Attempting to up the quality for mid: ', mid, ' quality:', currentSubstream - 1);
1634
1639
  this._resetStats(p.handleId, mid);
1635
1640
  this.selectSubStream(p.handleId, currentSubstream - 1, undefined, mid, false)
1641
+ .catch((reason) => this._log(`Changing substream for mid: ${mid} failed. Reason: ${reason}`));
1636
1642
  }
1637
1643
  }
1644
+ else {
1645
+ this._log('No quality change for mid: ', mid);
1646
+ }
1638
1647
  }
1639
1648
  });
1640
1649
  }
@@ -1722,6 +1731,15 @@ class RoomSession {
1722
1731
  }
1723
1732
 
1724
1733
  stats.selectedSubstream = handle.webrtcStuff.selectedSubstream[participantStats.mid];
1734
+ if(handle.webrtcStuff.forcedBrowserControlledMode[participantStats.mid]) {
1735
+ stats.simulcastMode = 'browserControlled';
1736
+ }
1737
+ else {
1738
+ stats.simulcastMode = typeof this.simulcastMode === 'object'
1739
+ ? (this.simulcastMode[participantStats.source] !== undefined ? this.simulcastMode[participantStats.source] : this.simulcastMode['default'])
1740
+ : this.simulcastMode;
1741
+ }
1742
+
1725
1743
  });
1726
1744
 
1727
1745
  // pushing stats into handle stats array but keeping only 6 last stats
@@ -2034,6 +2052,23 @@ class RoomSession {
2034
2052
  track: ev.target,
2035
2053
  muted: true
2036
2054
  });
2055
+
2056
+ // questionable hotfix
2057
+ // when a track is muted, we try to switch to lower quality substream
2058
+
2059
+ if(!this.simulcast) {
2060
+ return;
2061
+ }
2062
+
2063
+ const simulcastMode = typeof this.simulcastMode === 'object'
2064
+ ? (this.simulcastMode[source] !== undefined ? this.simulcastMode[source] : this.simulcastMode['default'])
2065
+ : this.simulcastMode;
2066
+ const {simulcastBitrates} = handle.webrtcStuff.tracksMap.find(t => t.mid === mid) || {};
2067
+ const currentSubstream = handle.webrtcStuff.selectedSubstream[mid];
2068
+ if(!(simulcastMode === 'browserControlled' || handle.webrtcStuff.forcedBrowserControlledMode[mid]) && ev.target.kind === 'video' && currentSubstream < simulcastBitrates.length - 1) {
2069
+ this.selectSubStream(handle.handleId, currentSubstream + 1, undefined, mid, false)
2070
+ .catch((reason) => this._log(`Changing substream for mid: ${mid} failed. Reason: ${reason}`));
2071
+ }
2037
2072
  };
2038
2073
 
2039
2074
  event.track.onunmute = (ev) => {
@@ -2969,7 +3004,7 @@ class RoomSession {
2969
3004
  if(substream === null) {
2970
3005
 
2971
3006
  if(manual) {
2972
- config.forcedAutoMode[mid] = false
3007
+ config.forcedBrowserControlledMode[mid] = false
2973
3008
  }
2974
3009
 
2975
3010
  resolve({substream, sender: handleId});
@@ -2977,7 +3012,7 @@ class RoomSession {
2977
3012
  }
2978
3013
 
2979
3014
  if(manual) {
2980
- config.forcedAutoMode[mid] = true
3015
+ config.forcedBrowserControlledMode[mid] = true
2981
3016
  }
2982
3017
 
2983
3018
  this.ws.addEventListener('message', parseResponse);
@@ -2986,7 +3021,7 @@ class RoomSession {
2986
3021
  this._abortController.signal.removeEventListener('abort', abortResponse);
2987
3022
  this.ws.removeEventListener('message', parseResponse);
2988
3023
  reject('timeout');
2989
- }, 5000);
3024
+ }, 10000);
2990
3025
 
2991
3026
  this.sendMessage(handleId, {
2992
3027
  "body": {