@reactoo/watchtogether-sdk-js 2.6.99 → 2.7.1

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.
@@ -169,6 +169,10 @@
169
169
  Instance.room.getSessionByConstructId(constructId).setTalkIntercomChannels(groups)
170
170
  }
171
171
 
172
+ function setRestrictSubscribeToUserIds(userIds) {
173
+ Instance.room.getSessionByConstructId(constructId).setRestrictSubscribeToUserIds(userIds)
174
+ }
175
+
172
176
  let Instance = WatchTogetherSDK({debug:true})({instanceType:'reactooDemo'});
173
177
 
174
178
  Instance.auth.$on('login', () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reactoo/watchtogether-sdk-js",
3
- "version": "2.6.99",
3
+ "version": "2.7.1",
4
4
  "description": "Javascript SDK for Reactoo",
5
5
  "main": "src/index.js",
6
6
  "unpkg": "dist/watchtogether-sdk.min.js",
@@ -21,7 +21,7 @@ import syncModule from "../modules/sync-modules/sync-module";
21
21
  let roomSession = function ({roomId, pinHash, role, options = {}}, room, wt) {
22
22
 
23
23
  let primaryRoomId = roomId;
24
- let {simulcast = null, simulcastBitrates = null, simulcastMode = null, simulcastDefaultManualSubstream = null} = options;
24
+ let {simulcast = null, simulcastBitrates = null, simulcastMode = null, simulcastDefaultManualSubstream = null, enableDtx = null} = options;
25
25
  let publicCustomEvents = ['changePlayerSource', 'chatMessage', 'userUpdate', 'reconnecting', 'connecting', 'remoteMuted', 'scaling'];
26
26
 
27
27
  const addEvents = (events) => {
@@ -122,6 +122,7 @@ let roomSession = function ({roomId, pinHash, role, options = {}}, room, wt) {
122
122
  simulcastBitrates !== null ? simulcastBitrates : roomData?.data?.simulcast?.bitrates,
123
123
  simulcastMode !== null ? simulcastMode : roomData?.data?.simulcast?.mode,
124
124
  simulcastDefaultManualSubstream !== null ? simulcastDefaultManualSubstream : roomData?.data?.simulcast?.defaultManualSubstream,
125
+ enableDtx !== null ? enableDtx : roomData?.data?.enableDtx,
125
126
  )
126
127
  })
127
128
  .finally(() => {
@@ -339,6 +340,10 @@ let roomSession = function ({roomId, pinHash, role, options = {}}, room, wt) {
339
340
  return room.toggleVideo(value, source);
340
341
  },
341
342
 
343
+ setRestrictSubscribeToUserIds: (userIds = []) => {
344
+ return room.setRestrictSubscribeToUserIds(userIds);
345
+ },
346
+
342
347
  setTalkIntercomChannels: (groups) => {
343
348
  return room.setTalkIntercomChannels(groups);
344
349
  },
@@ -55,14 +55,16 @@ let room = function () {
55
55
  }))
56
56
  },
57
57
 
58
- createRoom: ({title, description, isPublic, isRouter, isStudioLayout, wtChannelId, isHd, disableSync, reduceRoomControls, hasStudioChat, maxParticipants, customAttributes, chatRoomId, linkedRoomId, type, dotAttribute} = {}) => {
58
+ createRoom: ({sourceRoomId, title, description, isPublic, isRouter, isStudioLayout, wtChannelId, isHd, disableSync, reduceRoomControls, hasStudioChat, maxParticipants, customAttributes, chatRoomId, linkedRoomId, type, dotAttribute} = {}) => {
59
59
  let _da = dotAttribute
60
60
  ? (Array.isArray(dotAttribute)
61
61
  ? dotAttribute.reduce((p, cv) => (p[cv.name] = cv.value) && p || p, {})
62
62
  : {[dotAttribute.name]: dotAttribute.value})
63
63
  : {};
64
64
  return this.__privates.auth.__client
65
- .then(client => client.apis.wt.createRoom({}, {
65
+ .then(client => client.apis.wt.createRoom({
66
+ sourceRoomId
67
+ }, {
66
68
  requestBody: {
67
69
  title,
68
70
  description,
@@ -182,6 +182,7 @@ class RoomSession {
182
182
  this.sessiontype = type;
183
183
  this.initialBitrate = 0;
184
184
  this.simulcast = false;
185
+ this.enableDtx = false;
185
186
  this.simulcastMode = 'controlled'; // controlled, manual, browserControlled
186
187
  this.simulcastDefaultManualSubstream = 0; // 0 = maximum quality
187
188
 
@@ -222,11 +223,13 @@ class RoomSession {
222
223
  this._maxRetries = 5;
223
224
  this._keepAliveId = null;
224
225
  this._participants = [];
226
+ this._subscribeToUserIds = []; // all if empty
225
227
  this._talkIntercomChannels = ['participants'];
226
228
  this._listenIntercomChannels = ['participants'];
227
229
  this._roomType = 'watchparty';
228
230
  this._isDataChannelOpen = false;
229
231
  this._abortController = null;
232
+ this._remoteUsersCache = [];
230
233
 
231
234
  this.userRoleSubscriptionRules = {
232
235
  ...RoomSession.userRoleSubscriptionRules,
@@ -239,12 +242,29 @@ class RoomSession {
239
242
  }
240
243
  }
241
244
 
245
+ _pushToRemoteUsersCache(userId, streams, id) {
246
+ const existingIndex = this._remoteUsersCache.findIndex(u => u.userId === userId);
247
+ if (existingIndex > -1) {
248
+ this._remoteUsersCache.splice(existingIndex, 1, {userId, streams, id})
249
+ } else {
250
+ this._remoteUsersCache.push({userId, streams, id});
251
+ }
252
+ }
253
+
254
+ _removeFromRemoteUsersCache(rfid) {
255
+ const existingIndex = this._remoteUsersCache.findIndex(u => u.id === rfid);
256
+ if (existingIndex > -1) {
257
+ this._remoteUsersCache.splice(existingIndex, 1);
258
+ }
259
+ }
260
+
242
261
  _participantShouldSubscribe(userId) {
243
262
  const myUser = decodeJanusDisplay(this.display);
244
263
  const remoteUser = decodeJanusDisplay(userId);
245
264
  let localUserRole = myUser?.role || 'participant';
246
265
  let remoteUserRole = remoteUser?.role || 'participant';
247
- return this.userRoleSubscriptionRules[localUserRole][(this._roomType || 'watchparty')].indexOf(remoteUserRole) > -1;
266
+ return this.userRoleSubscriptionRules[localUserRole][(this._roomType || 'watchparty')].indexOf(remoteUserRole) > -1
267
+ && (this._subscribeToUserIds.length === 0 || this._subscribeToUserIds.indexOf(remoteUser?.userId) > -1);
248
268
  }
249
269
 
250
270
  _intercomSubscribe = (stream) => {
@@ -582,7 +602,11 @@ class RoomSession {
582
602
  streams[i]["display"] = userId;
583
603
  }
584
604
  this._log('Remote userId: ', userId);
605
+
606
+ this._pushToRemoteUsersCache(userId, streams, id);
607
+
585
608
  if (this._participantShouldSubscribe(userId)) {
609
+
586
610
  this._log('Creating user: ', userId);
587
611
  this._createParticipant(userId, id)
588
612
  .then(handle => {
@@ -632,6 +656,9 @@ class RoomSession {
632
656
  streams[i]["display"] = userId;
633
657
  }
634
658
  this._log('Remote userId: ', userId);
659
+
660
+ this._pushToRemoteUsersCache(userId, streams, id);
661
+
635
662
  if (this._participantShouldSubscribe(userId)) {
636
663
 
637
664
  let handle = this._getHandle(null, id);
@@ -694,8 +721,9 @@ class RoomSession {
694
721
  this.disconnect().catch(() => {});
695
722
  }
696
723
  } else if (leaving) {
697
- //TODO: in 1 PeerConnection case we only unsubscribe from streams
724
+ //TODO: in 1 PeerConnection case we only unsubscribe from streams, this may not be true, check janus docs
698
725
  this._log('leaving', leaving);
726
+ this._removeFromRemoteUsersCache(leaving);
699
727
  this._removeParticipant(null, leaving, true);
700
728
  }
701
729
 
@@ -705,6 +733,7 @@ class RoomSession {
705
733
  } else if (unpublished) {
706
734
  //TODO: in 1 PeerConnection case we only unsubscribe from streams
707
735
  this._log('unpublished', unpublished);
736
+ this._removeFromRemoteUsersCache(unpublished);
708
737
  this._removeParticipant(null, unpublished, true); // we do hangup and detach
709
738
  }
710
739
 
@@ -712,6 +741,7 @@ class RoomSession {
712
741
  // this case shouldn't exist
713
742
  } else if(kicked) {
714
743
  this._log('kicked', kicked);
744
+ this._removeFromRemoteUsersCache(kicked);
715
745
  this._removeParticipant(null, kicked, true); // we do hangup and detach
716
746
  }
717
747
 
@@ -1068,7 +1098,7 @@ class RoomSession {
1068
1098
  message: 'id non-existent',
1069
1099
  data: [handleId, 'isAlreadySubscribed']
1070
1100
  });
1071
- return;
1101
+ return false;
1072
1102
  }
1073
1103
  return handle.webrtcStuff.subscribeMap.findIndex(t => t.mid === mid && t.feed === feed) > -1
1074
1104
  }
@@ -1264,7 +1294,7 @@ class RoomSession {
1264
1294
  simulcastBitrates = this.simulcastBitrates,
1265
1295
  simulcastMode = this.simulcastMode,
1266
1296
  simulcastDefaultManualSubstream = this.simulcastDefaultManualSubstream,
1267
- simulcastInitialSubstream = null
1297
+ enableDtx = false
1268
1298
  ) {
1269
1299
 
1270
1300
  if (this.isConnecting) {
@@ -1289,6 +1319,7 @@ class RoomSession {
1289
1319
  this.initialBitrate = initialBitrate;
1290
1320
  this.recordingFilename = recordingFilename;
1291
1321
  this.isConnecting = true;
1322
+ this.enableDtx = enableDtx;
1292
1323
  this.simulcast = simulcast;
1293
1324
  this.simulcastMode = simulcastMode;
1294
1325
  this.simulcastDefaultManualSubstream = simulcastDefaultManualSubstream;
@@ -2343,6 +2374,13 @@ class RoomSession {
2343
2374
 
2344
2375
  return config.pc[methodName](mediaConstraints)
2345
2376
  .then( (response) => {
2377
+
2378
+ // if type offer and its me and we want dtx we mungle the sdp
2379
+ if(handleId === this.handleId && type === 'offer' && this.enableDtx) {
2380
+ // enable DTX
2381
+ response.sdp = response.sdp.replace("useinbandfec=1", "useinbandfec=1;usedtx=1")
2382
+ }
2383
+
2346
2384
  config.mySdp = response.sdp;
2347
2385
  let _p = config.pc.setLocalDescription(response)
2348
2386
  .catch((e) => {
@@ -3140,6 +3178,42 @@ class RoomSession {
3140
3178
  return this._roomType;
3141
3179
  }
3142
3180
 
3181
+ setRestrictSubscribeToUserIds(userIds = []) {
3182
+ this._restrictSubscribeToUserIds = structuredClone(userIds);
3183
+
3184
+ // sanity check by getting listparticipants and comparing it to _remoteUsersCache
3185
+ this.sendMessage(this.handleId, {body: {request: 'listparticipants', room: this.roomId}})
3186
+ .then(r => {
3187
+ let participants = r.participants;
3188
+ let remoteUsersCache = this._remoteUsersCache;
3189
+ let handle = this._getHandle(this.handleId);
3190
+
3191
+ // filter out my user id from response and compare it to remoteUsersCache
3192
+ participants = participants.filter(p => p.id !== handle.userId);
3193
+
3194
+ // get rid of participants that are in participants but not in remoteUsersCache
3195
+ remoteUsersCache = remoteUsersCache.filter(r => participants.find(p => p.id === r.id));
3196
+
3197
+ remoteUsersCache.forEach(r => {
3198
+ if(this._participantShouldSubscribe(r.id)) {
3199
+ // if(this._getHandle(null, id)) {
3200
+ //
3201
+ // }
3202
+ }
3203
+ else {
3204
+
3205
+ }
3206
+ })
3207
+
3208
+
3209
+ console.log(participants, remoteUsersCache);
3210
+
3211
+ });
3212
+
3213
+
3214
+ return this._restrictSubscribeToUserIds;
3215
+ }
3216
+
3143
3217
 
3144
3218
  }
3145
3219