@reactoo/watchtogether-sdk-js 2.7.38 → 2.7.39

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.
@@ -32,8 +32,8 @@
32
32
 
33
33
  //https://studio.reactoo.com/room/edf441b3-7415-49c4-9557-273cb93bc746/LJj4W2Cz-nG3U-lb0R-TAaY-o7Thmb8xHSbE
34
34
 
35
- let roomId = "c22ada04-6c95-4524-91d8-e915bcef2e61"; // It will create room automatically if not set
36
- let pinHash = "OayoOVzK-XmWr-BTID-fVwH-eH44Tn3xSWeR";// '967ca05f-7fab-a205-5913-39393bbbe923';
35
+ let roomId = "d841ad58-e5a6-4cb8-aeb8-c92499a213a4"; // It will create room automatically if not set
36
+ let pinHash = null;
37
37
 
38
38
  let participants = document.querySelector('.participants');
39
39
  var video = document.querySelector('.contentVideo');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reactoo/watchtogether-sdk-js",
3
- "version": "2.7.38",
3
+ "version": "2.7.39",
4
4
  "description": "Javascript SDK for Reactoo",
5
5
  "main": "src/index.js",
6
6
  "unpkg": "dist/watchtogether-sdk.min.js",
@@ -1700,14 +1700,14 @@ class RoomSession {
1700
1700
  let directionDecision = 0;
1701
1701
  if(p.webrtcStuff?.stats?.[mid]?.length > this._upStatsLength) {
1702
1702
  const upMedianStats = this._calculateMedianStats(p.webrtcStuff.stats[mid].slice(this._upStatsLength * -1));
1703
- if(upMedianStats?.framesPerSecond >= Math.floor((settingsForCurrentSubstream?.maxFramerate || 30) * 0.7) && upMedianStats?.freezeDurationSinceLast < (this._upStatsLength * this._statsInterval * 0.33) / 1000 /* && upMedianStats?.freezeCountSinceLast < 3 */) {
1703
+ if(upMedianStats?.freezeDurationSinceLast < (this._upStatsLength * this._statsInterval * 0.33) / 1000 /* && upMedianStats?.freezeCountSinceLast < 3 */) {
1704
1704
  directionDecision = 1;
1705
1705
  }
1706
1706
  }
1707
1707
 
1708
1708
  if(p.webrtcStuff?.stats?.[mid]?.length > this._downStatsLength) {
1709
1709
  const downMedianStats = this._calculateMedianStats(p.webrtcStuff.stats[mid].slice(this._downStatsLength * -1));
1710
- if(downMedianStats?.framesPerSecond < Math.floor((settingsForCurrentSubstream?.maxFramerate || 30) * 0.7) || downMedianStats?.freezeDurationSinceLast > (this._downStatsLength * this._statsInterval * 0.33) / 1000 /* || downMedianStats?.freezeCountSinceLast > 5 || downMedianStats?.jitter > maxJitter(settingsForCurrentSubstream.maxFramerate) */) {
1710
+ if(downMedianStats?.freezeDurationSinceLast > (this._downStatsLength * this._statsInterval * 0.33) / 1000 /* || downMedianStats?.freezeCountSinceLast > 5 || downMedianStats?.jitter > maxJitter(settingsForCurrentSubstream.maxFramerate) */) {
1711
1711
  directionDecision = -1;
1712
1712
  }
1713
1713
  }
@@ -2127,10 +2127,6 @@ class RoomSession {
2127
2127
  });
2128
2128
  };
2129
2129
 
2130
- let mutedTimerId = {};
2131
- let waitPeriod = 300; // ms
2132
- let screenShareWaitPeriod = 5000; // ms
2133
-
2134
2130
  event.track.onmute = (ev) => {
2135
2131
  this._log('Remote track muted');
2136
2132
 
@@ -2153,35 +2149,6 @@ class RoomSession {
2153
2149
  muted: true
2154
2150
  });
2155
2151
 
2156
- // when a track is muted, we try to switch to lower quality substream, but not for screen sharing
2157
-
2158
- if(!this.simulcast) {
2159
- return;
2160
- }
2161
-
2162
- const wPeriod = source.indexOf('screen') > -1 ? screenShareWaitPeriod : waitPeriod;
2163
-
2164
- if(!mutedTimerId[mid]) {
2165
- mutedTimerId[mid] = setTimeout(() => {
2166
- mutedTimerId[mid] = null;
2167
- const simulcastConfigForSource = this._findSimulcastConfig(source, this.simulcastSettings);
2168
- const simulcastMode = handle.webrtcStuff?.overriddenSimulcastMode[mid]?.mode || simulcastConfigForSource?.mode;
2169
- const {simulcastBitrates} = handle.webrtcStuff.tracksMap.find(t => t.mid === mid) || {};
2170
-
2171
- // track is gone
2172
- if(!simulcastBitrates) {
2173
- return;
2174
- }
2175
-
2176
- const currentSubstream = handle.webrtcStuff.selectedSubstream[mid];
2177
- if(!(simulcastMode === 'browserControlled') && ev.target.kind === 'video' && currentSubstream < simulcastBitrates.length - 1) {
2178
- this._log('Attempting to down the quality due to track muted');
2179
- this.selectSubStream(handle.handleId, currentSubstream + 1, undefined, mid, false)
2180
- .catch((reason) => this._log(`Changing substream for mid: ${mid} failed. Reason: ${reason}`));
2181
- }
2182
- }, wPeriod);
2183
- }
2184
-
2185
2152
  };
2186
2153
 
2187
2154
  event.track.onunmute = (ev) => {
@@ -2192,11 +2159,6 @@ class RoomSession {
2192
2159
  let mid = transceiver.mid || ev.target.id;
2193
2160
  let source = Object.keys(config.streamMap).find(key => config.streamMap[key].includes(ev.target.id));
2194
2161
 
2195
- if(mutedTimerId[mid]) {
2196
- clearTimeout(mutedTimerId[mid]);
2197
- mutedTimerId[mid] = null;
2198
- }
2199
-
2200
2162
  this.emit('remoteTrackMuted', {
2201
2163
  id: handle.handleId,
2202
2164
  mid,
@@ -2507,6 +2469,77 @@ class RoomSession {
2507
2469
 
2508
2470
  }
2509
2471
 
2472
+ _addSimulcastToSDP(sdp) {
2473
+ // Split SDP into lines
2474
+ let sdpLines = sdp.split('\n');
2475
+
2476
+ // Find the index of the video m-line
2477
+ let videoIndex = sdpLines.findIndex(line => line.startsWith('m=video'));
2478
+ if (videoIndex === -1) {
2479
+ // No video m-line found
2480
+ return sdp;
2481
+ }
2482
+
2483
+ // We need to insert the lines after the mid attribute
2484
+ // Find the index of the 'a=mid' line in the video section
2485
+ let midIndex = sdpLines.findIndex((line, index) =>
2486
+ index > videoIndex && line.startsWith('a=mid:')
2487
+ );
2488
+
2489
+ if (midIndex === -1) {
2490
+ // No 'a=mid' line found in video m-section
2491
+ return sdp;
2492
+ }
2493
+
2494
+ // Prepare the simulcast attributes
2495
+ const simulcastLines = [
2496
+ 'a=rid:l recv',
2497
+ 'a=rid:m recv',
2498
+ 'a=rid:h recv',
2499
+ 'a=simulcast:recv l;m;h'
2500
+ ];
2501
+
2502
+ // Prepare the extmap attributes for RID and Repaired RID
2503
+ const extmapId = sdpLines.reduce((maxId, line) => {
2504
+ const match = line.match(/a=extmap:(\d+)/);
2505
+ return match ? Math.max(maxId, parseInt(match[1])) : maxId;
2506
+ }, 0);
2507
+
2508
+ const extmapLines = [
2509
+ `a=extmap:${extmapId + 1} urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id`,
2510
+ `a=extmap:${extmapId + 2} urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id`
2511
+ ];
2512
+
2513
+ // Insert the extmap lines after the last existing extmap in the video section
2514
+ let lastExtmapIndex = midIndex;
2515
+ for (let i = midIndex + 1; i < sdpLines.length; i++) {
2516
+ if (sdpLines[i].startsWith('a=extmap:')) {
2517
+ lastExtmapIndex = i;
2518
+ } else if (sdpLines[i].startsWith('a=')) {
2519
+ // Reached another attribute
2520
+ break;
2521
+ }
2522
+ }
2523
+
2524
+ // Check if the attributes are already present
2525
+ const hasSimulcast = sdpLines.some(line => line.startsWith('a=simulcast'));
2526
+ const hasRidExtmap = sdpLines.some(line => line.includes('urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id'));
2527
+
2528
+ if (!hasRidExtmap) {
2529
+ // Insert the extmap lines
2530
+ sdpLines.splice(lastExtmapIndex + 1, 0, ...extmapLines);
2531
+ }
2532
+
2533
+ if (!hasSimulcast) {
2534
+ // Insert the simulcast lines after the 'a=mid' line
2535
+ sdpLines.splice(midIndex + 1, 0, ...simulcastLines);
2536
+ }
2537
+
2538
+ // Return the modified SDP
2539
+ return sdpLines.join('\n');
2540
+ }
2541
+
2542
+
2510
2543
  _publishRemote(handleId, jsep) {
2511
2544
  let handle = this._getHandle(handleId);
2512
2545
  if (!handle) {
@@ -2523,6 +2556,13 @@ class RoomSession {
2523
2556
  let config = handle.webrtcStuff;
2524
2557
 
2525
2558
  if (jsep) {
2559
+
2560
+ // Just For Debugging
2561
+ // Munge the SDP before setting the remote description
2562
+ // if (jsep && jsep.sdp) {
2563
+ // jsep.sdp = this._addSimulcastToSDP(jsep.sdp);
2564
+ // }
2565
+
2526
2566
  return config.pc.setRemoteDescription(jsep)
2527
2567
  .then(() => {
2528
2568
  config.remoteSdp = jsep.sdp;