@reactoo/watchtogether-sdk-js 2.6.73 → 2.6.75

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.
@@ -212,7 +212,7 @@
212
212
  .then(r => Instance.room.createSession({constructId, roomId:r.roomId, pinHash: r.pinHash, role:'participant', options: {
213
213
  simulcast: true,
214
214
  simulcastMode: {default: 'controlled', screen: 'manual'}, // controlled, manual, auto ... key is the device source (default = all)
215
- simulcastDefaultManualSubstream: {default:2, screen: 0}, // 2 lowest quality, 0 highest quality ... key is the device source (default = all)
215
+ simulcastDefaultManualSubstream: {default:0, screen: 0}, // 2 lowest quality, 0 highest quality ... key is the device source (default = all)
216
216
  // those are for videowall (see that 4 fps preview for producer panel)
217
217
  simulcastBitrates: [
218
218
  { rid: 'l', active: true, maxBitrate: 180000, maxFramerate: 4, scaleResolutionDownBy: 4, priority: "low" },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reactoo/watchtogether-sdk-js",
3
- "version": "2.6.73",
3
+ "version": "2.6.75",
4
4
  "description": "Javascript SDK for Reactoo",
5
5
  "main": "src/index.js",
6
6
  "unpkg": "dist/watchtogether-sdk.min.js",
@@ -209,8 +209,8 @@ class RoomSession {
209
209
  this.isMuted = [];
210
210
  this.isVideoEnabled = false;
211
211
  this.isAudioEnabed = false;
212
- this._statsMaxLength = 21;
213
- this._upStatsLength = 20;
212
+ this._statsMaxLength = 16;
213
+ this._upStatsLength = 15;
214
214
  this._downStatsLength = 5;
215
215
  this._statsTimeoutStopped = true;
216
216
  this._statsTimeoutId = null;
@@ -784,7 +784,7 @@ class RoomSession {
784
784
  let temporal = msg["temporal"];
785
785
 
786
786
  if(substream !== undefined && substream !== null) {
787
- this._log('Substream: ',substream);
787
+ this._log('Substream: ', sender, mid, substream);
788
788
  this._setSelectedSubstream(sender, mid, substream);
789
789
  this._resetStats(sender, mid);
790
790
  }
@@ -966,6 +966,7 @@ class RoomSession {
966
966
  isIceRestarting: false,
967
967
  stats: {},
968
968
  selectedSubstream: {},
969
+ initialSimulcastSubstreamBeenSet: {},
969
970
  simulcastSubstreamManualSelect: {},
970
971
  simulcastSwitchFailedAttempts: {},
971
972
  };
@@ -1023,6 +1024,7 @@ class RoomSession {
1023
1024
  isIceRestarting: false,
1024
1025
  stats: {},
1025
1026
  selectedSubstream: {},
1027
+ initialSimulcastSubstreamBeenSet: {},
1026
1028
  simulcastSubstreamManualSelect: {},
1027
1029
  simulcastSwitchFailedAttempts: {},
1028
1030
  }
@@ -1103,13 +1105,17 @@ class RoomSession {
1103
1105
  let config = handle.webrtcStuff;
1104
1106
  config.tracksMap = structuredClone(streams.map(s => {
1105
1107
  let source = null;
1108
+ let simulcastBitrates = null;
1106
1109
  try {
1107
- source = JSON.parse(s.description)?.source;
1110
+ const description = JSON.parse(s.description);
1111
+ source = description?.source;
1112
+ simulcastBitrates = description?.simulcastBitrates;
1108
1113
  } catch(e) {}
1109
1114
  return {
1110
1115
  active: !s.disabled,
1111
1116
  description: s.description,
1112
1117
  source: source,
1118
+ simulcastBitrates: simulcastBitrates,
1113
1119
  display: s.display,
1114
1120
  id: s.id,
1115
1121
  mid: s.mid,
@@ -1258,7 +1264,8 @@ class RoomSession {
1258
1264
  simulcast = false,
1259
1265
  simulcastBitrates = this.simulcastBitrates,
1260
1266
  simulcastMode = this.simulcastMode,
1261
- simulcastDefaultManualSubstream = this.simulcastDefaultManualSubstream
1267
+ simulcastDefaultManualSubstream = this.simulcastDefaultManualSubstream,
1268
+ simulcastInitialSubstream = null
1262
1269
  ) {
1263
1270
 
1264
1271
  if (this.isConnecting) {
@@ -1566,7 +1573,8 @@ class RoomSession {
1566
1573
  const mids = transceivers?.filter(t => t.receiver.track.kind === "video")?.map(t => t.mid) || [];
1567
1574
  mids.forEach(mid => {
1568
1575
 
1569
- const source = p.webrtcStuff.tracksMap.find(t => t.mid === mid)?.source;
1576
+ const {source, simulcastBitrates} = p.webrtcStuff.tracksMap.find(t => t.mid === mid) || {};
1577
+ const initialSubstreamBeenSet = !!p.webrtcStuff.initialSimulcastSubstreamBeenSet[mid];
1570
1578
  const manualSelectedSubstream = p.webrtcStuff.simulcastSubstreamManualSelect?.[mid];
1571
1579
  const defaultSelectedSubstream = typeof this.simulcastDefaultManualSubstream === 'object'
1572
1580
  ? (this.simulcastDefaultManualSubstream[source] !== undefined ? this.simulcastDefaultManualSubstream[source] : this.simulcastDefaultManualSubstream['default'])
@@ -1580,9 +1588,10 @@ class RoomSession {
1580
1588
  // do nothing
1581
1589
  }
1582
1590
 
1583
- else if(simulcastMode === 'manual' || manualSelectedSubstream) {
1591
+ else if(simulcastMode === 'manual' || manualSelectedSubstream || !initialSubstreamBeenSet) {
1592
+ p.webrtcStuff.initialSimulcastSubstreamBeenSet[mid] = true;
1584
1593
  const currentSubstream = p.webrtcStuff.selectedSubstream[mid];
1585
- if(manualSelectedSubstream && currentSubstream !== manualSelectedSubstream) {
1594
+ if(manualSelectedSubstream !== undefined && manualSelectedSubstream !== null && currentSubstream !== manualSelectedSubstream) {
1586
1595
  this.selectSubStream(p.handleId, manualSelectedSubstream, undefined, mid, false)
1587
1596
  .then(() => {
1588
1597
  p.webrtcStuff.simulcastSwitchFailedAttempts[mid] = 0
@@ -1596,7 +1605,7 @@ class RoomSession {
1596
1605
  }
1597
1606
  });
1598
1607
  }
1599
- else if(defaultSelectedSubstream !== currentSubstream) {
1608
+ else if(defaultSelectedSubstream !== undefined && defaultSelectedSubstream !== null && defaultSelectedSubstream !== currentSubstream) {
1600
1609
  this.selectSubStream(p.handleId, defaultSelectedSubstream, undefined, mid, false)
1601
1610
  .then(() => {
1602
1611
  p.webrtcStuff.simulcastSwitchFailedAttempts[mid] = 0
@@ -1614,11 +1623,11 @@ class RoomSession {
1614
1623
 
1615
1624
  else if(simulcastMode === 'controlled') {
1616
1625
  const currentSubstream = p.webrtcStuff.selectedSubstream[mid];
1617
- const settingsForCurrentSubstream = this.simulcastBitrates?.[this.simulcastBitrates.length - 1 - currentSubstream];
1626
+ const settingsForCurrentSubstream = simulcastBitrates?.[simulcastBitrates.length - 1 - currentSubstream];
1618
1627
  let directionDecision = 0;
1619
1628
  if(p.webrtcStuff?.stats?.[mid]?.length > this._upStatsLength) {
1620
1629
  const upMedianStats = this._calculateMedianStats(p.webrtcStuff.stats[mid].slice(this._upStatsLength * -1));
1621
- if(upMedianStats?.framesPerSecond > Math.floor(settingsForCurrentSubstream.maxFramerate * 0.9) || upMedianStats?.freezeDurationSinceLast < (this._upStatsLength * this._statsInterval * 0.1) / 1000 || this._upStatsLength?.freezeCountSinceLast < 3) {
1630
+ if(upMedianStats?.framesPerSecond >= Math.floor(settingsForCurrentSubstream.maxFramerate * 0.7) && upMedianStats?.freezeDurationSinceLast < (this._upStatsLength * this._statsInterval * 0.33) / 1000 && upMedianStats?.freezeCountSinceLast < 3) {
1622
1631
  directionDecision = 1;
1623
1632
  }
1624
1633
  }
@@ -1631,7 +1640,7 @@ class RoomSession {
1631
1640
  }
1632
1641
 
1633
1642
  if(directionDecision === -1) {
1634
- if(currentSubstream < this.simulcastBitrates.length - 1) {
1643
+ if(currentSubstream < simulcastBitrates.length - 1) {
1635
1644
  this._log('switching to low res', currentSubstream + 1);
1636
1645
  this.selectSubStream(p.handleId, currentSubstream + 1, undefined, mid, false)
1637
1646
  .then(() => {
@@ -2757,7 +2766,7 @@ class RoomSession {
2757
2766
  config.streamMap[source].forEach(trackId => {
2758
2767
  let t = transceivers.find(transceiver => transceiver.sender.track && transceiver.sender.track.id === trackId)
2759
2768
  if(t) {
2760
- descriptions.push({mid: t.mid, description: JSON.stringify({source, intercomGroups: this._talkIntercomChannels})});
2769
+ descriptions.push({mid: t.mid, description: JSON.stringify({source, simulcastBitrates: this.simulcastBitrates, intercomGroups: this._talkIntercomChannels})});
2761
2770
  }
2762
2771
  })
2763
2772
  });
@@ -3050,7 +3059,7 @@ class RoomSession {
3050
3059
  config.streamMap[source].forEach(trackId => {
3051
3060
  let t = transceivers.find(transceiver => transceiver.sender.track && transceiver.sender.track.id === trackId)
3052
3061
  if(t) {
3053
- descriptions.push({mid: t.mid, description: JSON.stringify({intercomGroups: groups, source:source})});
3062
+ descriptions.push({mid: t.mid, description: JSON.stringify({simulcastBitrates: this.simulcastBitrates, intercomGroups: groups, source:source})});
3054
3063
  }
3055
3064
  })
3056
3065
  });