@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.
- package/dist/watchtogether-sdk.js +74 -43
- package/dist/watchtogether-sdk.js.map +1 -1
- package/dist/watchtogether-sdk.min.js +2 -2
- package/example/index.html +2 -2
- package/package.json +1 -1
- package/src/modules/wt-iot.js +11 -2
- package/src/modules/wt-room.js +80 -41
package/example/index.html
CHANGED
|
@@ -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 = "
|
|
36
|
-
let pinHash =
|
|
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
package/src/modules/wt-iot.js
CHANGED
|
@@ -280,7 +280,11 @@ class Iot {
|
|
|
280
280
|
}
|
|
281
281
|
|
|
282
282
|
// Find a suitable topic for the connection check
|
|
283
|
-
|
|
283
|
+
let suitableTopic = Array.from(this.subscribedTopics).find(topic => topic.indexOf('user') > -1);
|
|
284
|
+
|
|
285
|
+
if(!suitableTopic) {
|
|
286
|
+
suitableTopic = Array.from(this.subscribedTopics).find(topic => topic.indexOf('room') > -1 && topic !== 'wt/instanceroom/reactooDemo');
|
|
287
|
+
}
|
|
284
288
|
|
|
285
289
|
if (!suitableTopic) {
|
|
286
290
|
reject(new Error('No suitable topic found for connection check'));
|
|
@@ -323,7 +327,12 @@ class Iot {
|
|
|
323
327
|
return;
|
|
324
328
|
}
|
|
325
329
|
// Find a suitable topic for the connection check
|
|
326
|
-
|
|
330
|
+
let suitableTopic = Array.from(this.subscribedTopics).find(topic => topic.indexOf('user') > -1);
|
|
331
|
+
|
|
332
|
+
if(!suitableTopic) {
|
|
333
|
+
suitableTopic = Array.from(this.subscribedTopics).find(topic => topic.indexOf('room') > -1 && topic !== 'wt/instanceroom/reactooDemo');
|
|
334
|
+
}
|
|
335
|
+
|
|
327
336
|
if (!suitableTopic) {
|
|
328
337
|
this.log('No suitable topic found for keep alive message');
|
|
329
338
|
return;
|
package/src/modules/wt-room.js
CHANGED
|
@@ -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?.
|
|
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?.
|
|
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,
|
|
@@ -2349,7 +2311,6 @@ class RoomSession {
|
|
|
2349
2311
|
config.isIceRestarting = false;
|
|
2350
2312
|
});
|
|
2351
2313
|
}
|
|
2352
|
-
|
|
2353
2314
|
}
|
|
2354
2315
|
|
|
2355
2316
|
_setupTransceivers(handleId, [audioSend, audioRecv, videoSend, videoRecv, audioTransceiver = null, videoTransceiver = null]) {
|
|
@@ -2507,6 +2468,77 @@ class RoomSession {
|
|
|
2507
2468
|
|
|
2508
2469
|
}
|
|
2509
2470
|
|
|
2471
|
+
_addSimulcastToSDP(sdp) {
|
|
2472
|
+
// Split SDP into lines
|
|
2473
|
+
let sdpLines = sdp.split('\n');
|
|
2474
|
+
|
|
2475
|
+
// Find the index of the video m-line
|
|
2476
|
+
let videoIndex = sdpLines.findIndex(line => line.startsWith('m=video'));
|
|
2477
|
+
if (videoIndex === -1) {
|
|
2478
|
+
// No video m-line found
|
|
2479
|
+
return sdp;
|
|
2480
|
+
}
|
|
2481
|
+
|
|
2482
|
+
// We need to insert the lines after the mid attribute
|
|
2483
|
+
// Find the index of the 'a=mid' line in the video section
|
|
2484
|
+
let midIndex = sdpLines.findIndex((line, index) =>
|
|
2485
|
+
index > videoIndex && line.startsWith('a=mid:')
|
|
2486
|
+
);
|
|
2487
|
+
|
|
2488
|
+
if (midIndex === -1) {
|
|
2489
|
+
// No 'a=mid' line found in video m-section
|
|
2490
|
+
return sdp;
|
|
2491
|
+
}
|
|
2492
|
+
|
|
2493
|
+
// Prepare the simulcast attributes
|
|
2494
|
+
const simulcastLines = [
|
|
2495
|
+
'a=rid:l recv',
|
|
2496
|
+
'a=rid:m recv',
|
|
2497
|
+
'a=rid:h recv',
|
|
2498
|
+
'a=simulcast:recv l;m;h'
|
|
2499
|
+
];
|
|
2500
|
+
|
|
2501
|
+
// Prepare the extmap attributes for RID and Repaired RID
|
|
2502
|
+
const extmapId = sdpLines.reduce((maxId, line) => {
|
|
2503
|
+
const match = line.match(/a=extmap:(\d+)/);
|
|
2504
|
+
return match ? Math.max(maxId, parseInt(match[1])) : maxId;
|
|
2505
|
+
}, 0);
|
|
2506
|
+
|
|
2507
|
+
const extmapLines = [
|
|
2508
|
+
`a=extmap:${extmapId + 1} urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id`,
|
|
2509
|
+
`a=extmap:${extmapId + 2} urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id`
|
|
2510
|
+
];
|
|
2511
|
+
|
|
2512
|
+
// Insert the extmap lines after the last existing extmap in the video section
|
|
2513
|
+
let lastExtmapIndex = midIndex;
|
|
2514
|
+
for (let i = midIndex + 1; i < sdpLines.length; i++) {
|
|
2515
|
+
if (sdpLines[i].startsWith('a=extmap:')) {
|
|
2516
|
+
lastExtmapIndex = i;
|
|
2517
|
+
} else if (sdpLines[i].startsWith('a=')) {
|
|
2518
|
+
// Reached another attribute
|
|
2519
|
+
break;
|
|
2520
|
+
}
|
|
2521
|
+
}
|
|
2522
|
+
|
|
2523
|
+
// Check if the attributes are already present
|
|
2524
|
+
const hasSimulcast = sdpLines.some(line => line.startsWith('a=simulcast'));
|
|
2525
|
+
const hasRidExtmap = sdpLines.some(line => line.includes('urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id'));
|
|
2526
|
+
|
|
2527
|
+
if (!hasRidExtmap) {
|
|
2528
|
+
// Insert the extmap lines
|
|
2529
|
+
sdpLines.splice(lastExtmapIndex + 1, 0, ...extmapLines);
|
|
2530
|
+
}
|
|
2531
|
+
|
|
2532
|
+
if (!hasSimulcast) {
|
|
2533
|
+
// Insert the simulcast lines after the 'a=mid' line
|
|
2534
|
+
sdpLines.splice(midIndex + 1, 0, ...simulcastLines);
|
|
2535
|
+
}
|
|
2536
|
+
|
|
2537
|
+
// Return the modified SDP
|
|
2538
|
+
return sdpLines.join('\n');
|
|
2539
|
+
}
|
|
2540
|
+
|
|
2541
|
+
|
|
2510
2542
|
_publishRemote(handleId, jsep) {
|
|
2511
2543
|
let handle = this._getHandle(handleId);
|
|
2512
2544
|
if (!handle) {
|
|
@@ -2523,6 +2555,13 @@ class RoomSession {
|
|
|
2523
2555
|
let config = handle.webrtcStuff;
|
|
2524
2556
|
|
|
2525
2557
|
if (jsep) {
|
|
2558
|
+
|
|
2559
|
+
// Just For Debugging
|
|
2560
|
+
// Munge the SDP before setting the remote description
|
|
2561
|
+
// if (jsep && jsep.sdp) {
|
|
2562
|
+
// jsep.sdp = this._addSimulcastToSDP(jsep.sdp);
|
|
2563
|
+
// }
|
|
2564
|
+
|
|
2526
2565
|
return config.pc.setRemoteDescription(jsep)
|
|
2527
2566
|
.then(() => {
|
|
2528
2567
|
config.remoteSdp = jsep.sdp;
|