@reactoo/watchtogether-sdk-js 2.8.0-beta.3 → 2.8.0-beta.5
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/example/index.html
CHANGED
package/package.json
CHANGED
|
@@ -156,22 +156,24 @@ let roomSession = function ({roomId, pinHash, role, options = {}}, room, wt) {
|
|
|
156
156
|
room.isRestarting = true;
|
|
157
157
|
|
|
158
158
|
let wasPublished = room.isPublished;
|
|
159
|
-
let
|
|
160
|
-
let stream = null;
|
|
161
|
-
if (handle?.webrtcStuff?.stream && wasPublished) {
|
|
162
|
-
stream = handle.webrtcStuff.stream;
|
|
163
|
-
}
|
|
159
|
+
let streams = room.getLocalStreams();
|
|
164
160
|
|
|
165
161
|
return this.disconnect()
|
|
166
162
|
.then(() => wait(1000)) //TODO: remove 1000ms wait by waiting for proper events from janus
|
|
167
163
|
.then(() => this.connect({reactooRoomId}))
|
|
168
164
|
.then(() => {
|
|
169
|
-
if
|
|
165
|
+
if(streams.length) {
|
|
166
|
+
return streams.reduce((promise, stream) => {
|
|
167
|
+
return promise.then(() => {
|
|
168
|
+
return this.publishLocal(stream.stream, stream.source);
|
|
169
|
+
});
|
|
170
|
+
}, Promise.resolve())
|
|
171
|
+
|
|
172
|
+
} else if (wasPublished) {
|
|
170
173
|
return this.publishLocal(null);
|
|
171
|
-
} else
|
|
172
|
-
return this.publishLocal(stream);
|
|
173
|
-
} else
|
|
174
|
+
} else {
|
|
174
175
|
return Promise.resolve()
|
|
176
|
+
}
|
|
175
177
|
})
|
|
176
178
|
.then(() => {
|
|
177
179
|
room.isRestarting = false;
|
|
@@ -278,6 +278,7 @@ class RoomSession {
|
|
|
278
278
|
// helper flags
|
|
279
279
|
|
|
280
280
|
this.isSupposeToBeConnected = false;
|
|
281
|
+
this.isRestarting = false; // used from outside
|
|
281
282
|
this.isConnecting = false;
|
|
282
283
|
this.isEstablishingConnection = false;
|
|
283
284
|
this.isDisconnecting = false;
|
|
@@ -406,6 +407,13 @@ class RoomSession {
|
|
|
406
407
|
}
|
|
407
408
|
}
|
|
408
409
|
|
|
410
|
+
#hasAttendeeInCache(id) {
|
|
411
|
+
if(this.#subscriberHandle) {
|
|
412
|
+
return !!this.#subscriberHandle.webrtcStuff.userIdToDisplay[id];
|
|
413
|
+
}
|
|
414
|
+
return false
|
|
415
|
+
}
|
|
416
|
+
|
|
409
417
|
#getCachedAttendeeIds() {
|
|
410
418
|
return Object.keys(this.#subscriberHandle?.webrtcStuff?.userIdToDisplay || {});
|
|
411
419
|
}
|
|
@@ -448,7 +456,7 @@ class RoomSession {
|
|
|
448
456
|
});
|
|
449
457
|
}
|
|
450
458
|
|
|
451
|
-
#emitRemoteFeedUpdate(mid, {feedRemoval = false, addingTrack = false, removingTrack = false, track = null, source = null, attendee = null} = {}) {
|
|
459
|
+
#emitRemoteFeedUpdate(mid, {forceEmit = false,feedRemoval = false, addingTrack = false, removingTrack = false, track = null, source = null, attendee = null} = {}) {
|
|
452
460
|
|
|
453
461
|
const transceiverData = this.#getTransceiverDataByMid(mid);
|
|
454
462
|
|
|
@@ -462,7 +470,7 @@ class RoomSession {
|
|
|
462
470
|
description = JSON.parse(transceiverData.feed_description);
|
|
463
471
|
} catch (e) {}
|
|
464
472
|
|
|
465
|
-
if(!this.#shouldEmitFeedUpdate(parsedDisplay)) {
|
|
473
|
+
if(!this.#shouldEmitFeedUpdate(parsedDisplay) && !forceEmit && !removingTrack) {
|
|
466
474
|
this._log('Not emitting feed update for', display, 'because of subscription rules');
|
|
467
475
|
// we don't want to emit this event
|
|
468
476
|
return;
|
|
@@ -513,7 +521,8 @@ class RoomSession {
|
|
|
513
521
|
const display = this.#getDisplayById(id);
|
|
514
522
|
const parsedDisplay = decodeJanusDisplay(display);
|
|
515
523
|
|
|
516
|
-
|
|
524
|
+
// we sometimes need to force emit, or emit when we unsubscribed and we're removing tracks
|
|
525
|
+
if(!this.#shouldEmitFeedUpdate(parsedDisplay, id) && !forceEmit && !removingTrack) {
|
|
517
526
|
this._log('Not emitting feed update for', display, 'because of subscription rules');
|
|
518
527
|
// we don't want to emit this event
|
|
519
528
|
return;
|
|
@@ -654,6 +663,7 @@ class RoomSession {
|
|
|
654
663
|
const subscribe = [];
|
|
655
664
|
const unsubscribe = [];
|
|
656
665
|
const flatSourceMap = [];
|
|
666
|
+
const forceEmitFeedRemoval = []
|
|
657
667
|
|
|
658
668
|
for (let index in publishers) {
|
|
659
669
|
if(publishers[index]["dummy"])
|
|
@@ -692,6 +702,10 @@ class RoomSession {
|
|
|
692
702
|
if(isSubscribed) {
|
|
693
703
|
unsubscribe.push({feed: id, mid: mid});
|
|
694
704
|
this.#removeFromSubscribeMap(id, mid);
|
|
705
|
+
// we need to get rid of feed if we we're subscribed to it
|
|
706
|
+
if(forceEmitFeedRemoval.indexOf(id) === -1) {
|
|
707
|
+
forceEmitFeedRemoval.push(id);
|
|
708
|
+
}
|
|
695
709
|
}
|
|
696
710
|
continue;
|
|
697
711
|
}
|
|
@@ -703,6 +717,9 @@ class RoomSession {
|
|
|
703
717
|
}
|
|
704
718
|
}
|
|
705
719
|
|
|
720
|
+
// we need to get rid of feed if we we're subscribed to it
|
|
721
|
+
forceEmitFeedRemoval.forEach(id => this.#emitRemoteFeedUpdate(null, {feedRemoval: true, forceEmit: true, attendee: {id:id}}))
|
|
722
|
+
|
|
706
723
|
// check if we're subscribed to any mid that is no longer available in sources
|
|
707
724
|
|
|
708
725
|
Object.keys(subscribedTo).forEach(id => {
|
|
@@ -784,7 +801,7 @@ class RoomSession {
|
|
|
784
801
|
// feed_id === id of participant
|
|
785
802
|
|
|
786
803
|
#updateTransceiverMap(handleId, streams = []) {
|
|
787
|
-
this._log('Updating current transceiver map', 'Is me: ' + handleId === this.#publisherHandle
|
|
804
|
+
this._log('Updating current transceiver map', 'Is me: ' + handleId === this.#publisherHandle?.handleId, handleId, streams);
|
|
788
805
|
let handle = this.#getHandle(handleId);
|
|
789
806
|
if (!handle) {
|
|
790
807
|
this.emit('error', {
|
|
@@ -1115,12 +1132,12 @@ class RoomSession {
|
|
|
1115
1132
|
} else if (type === "webrtcup") {
|
|
1116
1133
|
//none universal
|
|
1117
1134
|
} else if (type === "hangup") {
|
|
1118
|
-
this._log('hangup on', handle.handleId, handle.handleId === this
|
|
1135
|
+
this._log('hangup on', handle.handleId, handle.handleId === this.handleId, json);
|
|
1119
1136
|
if(this.#getHandle(handle.handleId)) {
|
|
1120
1137
|
this.#cleanupHandle(handle.handleId, true).catch(() => {});
|
|
1121
1138
|
}
|
|
1122
1139
|
} else if (type === "detached") {
|
|
1123
|
-
this._log('detached on', handle.handleId, handle.handleId === this
|
|
1140
|
+
this._log('detached on', handle.handleId, handle.handleId === this.handleId, json);
|
|
1124
1141
|
if(this.#getHandle(handle.handleId)) {
|
|
1125
1142
|
this.#destroyHandle(handle.handleId).catch(() => {});
|
|
1126
1143
|
}
|
|
@@ -1142,7 +1159,7 @@ class RoomSession {
|
|
|
1142
1159
|
|
|
1143
1160
|
// LOCAL
|
|
1144
1161
|
|
|
1145
|
-
if (sender === this.#publisherHandle
|
|
1162
|
+
if (sender === this.#publisherHandle?.handleId) {
|
|
1146
1163
|
if (type === "event") {
|
|
1147
1164
|
|
|
1148
1165
|
var plugindata = json["plugindata"] || {};
|
|
@@ -1213,7 +1230,7 @@ class RoomSession {
|
|
|
1213
1230
|
|
|
1214
1231
|
|
|
1215
1232
|
if (leaving === 'ok') {
|
|
1216
|
-
this._log('leaving', this.#publisherHandle
|
|
1233
|
+
this._log('leaving', this.#publisherHandle?.handleId, 'this is us');
|
|
1217
1234
|
|
|
1218
1235
|
this.#emitLocalFeedUpdate({feedRemoval: true});
|
|
1219
1236
|
|
|
@@ -1235,8 +1252,8 @@ class RoomSession {
|
|
|
1235
1252
|
}
|
|
1236
1253
|
|
|
1237
1254
|
if (unpublished === 'ok') {
|
|
1238
|
-
this._log('unpublished', this.#publisherHandle
|
|
1239
|
-
this.#cleanupHandle(this.#publisherHandle
|
|
1255
|
+
this._log('unpublished', this.#publisherHandle?.handleId, 'this is us');
|
|
1256
|
+
this.#cleanupHandle(this.#publisherHandle?.handleId, true).catch(() => {});
|
|
1240
1257
|
|
|
1241
1258
|
} else if (unpublished) {
|
|
1242
1259
|
this._log('unpublished', unpublished);
|
|
@@ -1274,7 +1291,7 @@ class RoomSession {
|
|
|
1274
1291
|
}
|
|
1275
1292
|
|
|
1276
1293
|
if (jsep !== undefined && jsep !== null) {
|
|
1277
|
-
this.#webrtcPeer(this.#publisherHandle
|
|
1294
|
+
this.#webrtcPeer(this.#publisherHandle?.handleId, jsep)
|
|
1278
1295
|
.catch(err => {
|
|
1279
1296
|
this.emit('error', err);
|
|
1280
1297
|
});
|
|
@@ -1288,7 +1305,7 @@ class RoomSession {
|
|
|
1288
1305
|
|
|
1289
1306
|
this._log('Configuring bitrate: ' + this.initialBitrate);
|
|
1290
1307
|
if (this.initialBitrate > 0) {
|
|
1291
|
-
this.sendMessage(this.#publisherHandle
|
|
1308
|
+
this.sendMessage(this.#publisherHandle?.handleId, {
|
|
1292
1309
|
"body": {
|
|
1293
1310
|
"request": "configure",
|
|
1294
1311
|
"bitrate": this.initialBitrate
|
|
@@ -1363,7 +1380,9 @@ class RoomSession {
|
|
|
1363
1380
|
config.dataChannelOpen = this.defaultDataChannelLabel === data?.label && data?.state === 'open';
|
|
1364
1381
|
}
|
|
1365
1382
|
|
|
1366
|
-
|
|
1383
|
+
|
|
1384
|
+
|
|
1385
|
+
if (handleId === this.handleId && this.defaultDataChannelLabel === data?.label) {
|
|
1367
1386
|
this._isDataChannelOpen = data?.state === 'open';
|
|
1368
1387
|
this.emit('dataChannel', data?.state === 'open');
|
|
1369
1388
|
}
|
|
@@ -1384,13 +1403,13 @@ class RoomSession {
|
|
|
1384
1403
|
config.dataChannelOpen = false;
|
|
1385
1404
|
}
|
|
1386
1405
|
}
|
|
1387
|
-
if (handleId === this
|
|
1406
|
+
if (handleId === this.handleId && this.defaultDataChannelLabel === data.label) {
|
|
1388
1407
|
this._isDataChannelOpen = false;
|
|
1389
1408
|
this.emit('dataChannel', false);
|
|
1390
1409
|
}
|
|
1391
1410
|
}
|
|
1392
1411
|
|
|
1393
|
-
if (handleId === this
|
|
1412
|
+
if (handleId === this.handleId && type === 'message') {
|
|
1394
1413
|
|
|
1395
1414
|
let d = null;
|
|
1396
1415
|
|
|
@@ -1474,18 +1493,24 @@ class RoomSession {
|
|
|
1474
1493
|
|
|
1475
1494
|
try {
|
|
1476
1495
|
if (handle.webrtcStuff.stream) {
|
|
1477
|
-
|
|
1478
|
-
|
|
1496
|
+
|
|
1497
|
+
if(this.isRestarting && handleId === this.handleId) {
|
|
1498
|
+
handle.webrtcStuff.stream?.getTracks().forEach(track => track.onended = null);
|
|
1479
1499
|
}
|
|
1480
1500
|
else {
|
|
1481
|
-
handle.webrtcStuff.stream?.getTracks().forEach(track => track.
|
|
1501
|
+
handle.webrtcStuff.stream?.getTracks().forEach(track => track.stop());
|
|
1482
1502
|
}
|
|
1503
|
+
|
|
1483
1504
|
}
|
|
1484
1505
|
if(handle.webrtcStuff?.tracks?.length > 0) {
|
|
1485
1506
|
handle.webrtcStuff.tracks.forEach(track => {
|
|
1486
1507
|
if (track) {
|
|
1487
|
-
|
|
1488
|
-
|
|
1508
|
+
if(this.isRestarting && handleId === this.handleId) {
|
|
1509
|
+
track.onended = null;
|
|
1510
|
+
}
|
|
1511
|
+
else {
|
|
1512
|
+
track.stop();
|
|
1513
|
+
}
|
|
1489
1514
|
}
|
|
1490
1515
|
});
|
|
1491
1516
|
}
|
|
@@ -1542,7 +1567,7 @@ class RoomSession {
|
|
|
1542
1567
|
lastSwitchTime : new Map(),
|
|
1543
1568
|
}
|
|
1544
1569
|
|
|
1545
|
-
if(this.#publisherHandle && handleId === this.#publisherHandle
|
|
1570
|
+
if(this.#publisherHandle && handleId === this.#publisherHandle?.handleId) {
|
|
1546
1571
|
this.#emitLocalFeedUpdate({feedRemoval: true});
|
|
1547
1572
|
}
|
|
1548
1573
|
else if(this.#subscriberHandle && handleId === this.#subscriberHandle.handleId) {
|
|
@@ -1555,7 +1580,7 @@ class RoomSession {
|
|
|
1555
1580
|
}
|
|
1556
1581
|
|
|
1557
1582
|
async #joinAsPublisher(roomId, pin, userId, display) {
|
|
1558
|
-
return this.sendMessage(this.#publisherHandle
|
|
1583
|
+
return this.sendMessage(this.#publisherHandle?.handleId, {
|
|
1559
1584
|
body: {
|
|
1560
1585
|
"request": "join", "room": roomId, "pin": pin, "ptype": "publisher", "display": display, ...(this.webrtcVersion > 1000 ? {id: userId} : {})
|
|
1561
1586
|
}
|
|
@@ -1642,7 +1667,7 @@ class RoomSession {
|
|
|
1642
1667
|
|
|
1643
1668
|
async #leaveRoom(dontWait = false) {
|
|
1644
1669
|
return this.isConnected
|
|
1645
|
-
? this.sendMessage(this.#publisherHandle
|
|
1670
|
+
? this.sendMessage(this.#publisherHandle?.handleId, {body: {"request": "leave"}}, dontWait)
|
|
1646
1671
|
.finally(() => {
|
|
1647
1672
|
this.isConnected = false;
|
|
1648
1673
|
this.emit('joined', false);
|
|
@@ -1976,6 +2001,27 @@ class RoomSession {
|
|
|
1976
2001
|
});
|
|
1977
2002
|
}
|
|
1978
2003
|
|
|
2004
|
+
getLocalStreams() {
|
|
2005
|
+
const streamMap = this.#publisherHandle?.webrtcStuff?.streamMap[this.id];
|
|
2006
|
+
if(!streamMap) {
|
|
2007
|
+
return [];
|
|
2008
|
+
}
|
|
2009
|
+
return Object.keys(streamMap).reduce((acc, source) => {
|
|
2010
|
+
const sourceTrackIds = streamMap[source] ?? [];
|
|
2011
|
+
const sourceRelatedTracks = this.#publisherHandle?.webrtcStuff?.tracks?.filter(t => sourceTrackIds.includes(t.id)) ?? [];
|
|
2012
|
+
if(sourceRelatedTracks.length) {
|
|
2013
|
+
const stream = new MediaStream();
|
|
2014
|
+
sourceRelatedTracks.forEach(track => {
|
|
2015
|
+
if(track) {
|
|
2016
|
+
stream.addTrack(track);
|
|
2017
|
+
}
|
|
2018
|
+
});
|
|
2019
|
+
acc.push({source, stream});
|
|
2020
|
+
}
|
|
2021
|
+
return acc
|
|
2022
|
+
}, [])
|
|
2023
|
+
}
|
|
2024
|
+
|
|
1979
2025
|
#enableDebug() {
|
|
1980
2026
|
this._log = console.log.bind(console);
|
|
1981
2027
|
}
|
|
@@ -2366,7 +2412,7 @@ class RoomSession {
|
|
|
2366
2412
|
// removing this so we can cache ice candidates again
|
|
2367
2413
|
config.remoteSdp = null;
|
|
2368
2414
|
|
|
2369
|
-
if (this
|
|
2415
|
+
if (this.handleId === handleId) {
|
|
2370
2416
|
this._log('Performing local ICE restart');
|
|
2371
2417
|
let hasAudio = !!(config.stream && config.stream.getAudioTracks().length > 0);
|
|
2372
2418
|
let hasVideo = !!(config.stream && config.stream.getVideoTracks().length > 0);
|
|
@@ -2515,7 +2561,7 @@ class RoomSession {
|
|
|
2515
2561
|
.then( (response) => {
|
|
2516
2562
|
|
|
2517
2563
|
// if type offer and its me and we want dtx we mungle the sdp
|
|
2518
|
-
if(handleId === this
|
|
2564
|
+
if(handleId === this.handleId && type === 'offer' && this.enableDtx) {
|
|
2519
2565
|
// enable DTX
|
|
2520
2566
|
response.sdp = response.sdp.replace("useinbandfec=1", "useinbandfec=1;usedtx=1")
|
|
2521
2567
|
}
|
|
@@ -2825,7 +2871,7 @@ class RoomSession {
|
|
|
2825
2871
|
let hasAudio = !!(stream && stream.getAudioTracks().length > 0);
|
|
2826
2872
|
let hasVideo = !!(stream && stream.getVideoTracks().length > 0);
|
|
2827
2873
|
|
|
2828
|
-
this.#setupTransceivers(this
|
|
2874
|
+
this.#setupTransceivers(this.handleId, [hasAudio, false, hasVideo, false, audioTransceiver, videoTransceiver]);
|
|
2829
2875
|
|
|
2830
2876
|
const emitEvents = () => {
|
|
2831
2877
|
this.isPublished = true;
|
|
@@ -2934,7 +2980,7 @@ class RoomSession {
|
|
|
2934
2980
|
|
|
2935
2981
|
async unpublishLocal(dontWait = false) {
|
|
2936
2982
|
return this.isPublished
|
|
2937
|
-
? this.sendMessage(this
|
|
2983
|
+
? this.sendMessage(this.handleId, {body: {"request": "unpublish"}}, dontWait)
|
|
2938
2984
|
.finally(r => {
|
|
2939
2985
|
this.isPublished = false;
|
|
2940
2986
|
this.emit('published', false);
|