@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.
- package/dist/watchtogether-sdk.js +2 -2
- package/dist/watchtogether-sdk.min.js +2 -2
- package/example/index.html +34 -6
- package/package.json +1 -1
- package/src/modules/wt-room.js +48 -13
package/example/index.html
CHANGED
|
@@ -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
|
-
|
|
222
|
-
|
|
223
|
-
|
|
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
|
-
{
|
|
226
|
-
|
|
227
|
-
|
|
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
package/src/modules/wt-room.js
CHANGED
|
@@ -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,
|
|
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:
|
|
192
|
-
{ rid: 'h', active: true, maxBitrate:
|
|
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 =
|
|
213
|
-
this._upStatsLength =
|
|
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
|
-
|
|
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
|
-
|
|
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 === '
|
|
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.
|
|
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.
|
|
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
|
-
},
|
|
3024
|
+
}, 10000);
|
|
2990
3025
|
|
|
2991
3026
|
this.sendMessage(handleId, {
|
|
2992
3027
|
"body": {
|