@defcomm/meetingsdk 0.3.1 → 0.3.3
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/index.d.mts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +113 -57
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +113 -57
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -512,6 +512,9 @@ var SFUClient = class {
|
|
|
512
512
|
getScreenStream() {
|
|
513
513
|
return this.screenStream;
|
|
514
514
|
}
|
|
515
|
+
getRemoteScreenStream(participantId) {
|
|
516
|
+
return this.remoteScreenStreams.get(participantId) || null;
|
|
517
|
+
}
|
|
515
518
|
setLocalStream(stream) {
|
|
516
519
|
this.localStream = stream;
|
|
517
520
|
}
|
|
@@ -931,19 +934,7 @@ var SFUClient = class {
|
|
|
931
934
|
}
|
|
932
935
|
case "screen_share_stopped": {
|
|
933
936
|
const participantId = payload.participant_id;
|
|
934
|
-
const screenStream = participantId ? this.remoteScreenStreams.get(participantId) : null;
|
|
935
937
|
const trackId = payload.track_id;
|
|
936
|
-
if (screenStream) {
|
|
937
|
-
for (const track of screenStream.getVideoTracks()) {
|
|
938
|
-
if (!trackId || this.normalizeRemoteTrackId(track.id) === String(trackId)) {
|
|
939
|
-
screenStream.removeTrack(track);
|
|
940
|
-
track.stop();
|
|
941
|
-
}
|
|
942
|
-
}
|
|
943
|
-
if (screenStream.getTracks().length === 0 && participantId) {
|
|
944
|
-
this.remoteScreenStreams.delete(participantId);
|
|
945
|
-
}
|
|
946
|
-
}
|
|
947
938
|
this.onScreenShareStopped(participantId, trackId);
|
|
948
939
|
break;
|
|
949
940
|
}
|
|
@@ -1326,11 +1317,14 @@ var SFUClient = class {
|
|
|
1326
1317
|
sdp: answer.sdp
|
|
1327
1318
|
}
|
|
1328
1319
|
});
|
|
1329
|
-
const
|
|
1330
|
-
|
|
1320
|
+
const waiter = this.subscriptionWaiters.shift();
|
|
1321
|
+
waiter?.resolve();
|
|
1331
1322
|
} catch (error) {
|
|
1332
|
-
const
|
|
1333
|
-
|
|
1323
|
+
const waiter = this.subscriptionWaiters.shift();
|
|
1324
|
+
if (waiter) {
|
|
1325
|
+
waiter.trackIds.forEach((id) => this.subscribedTracks.delete(id));
|
|
1326
|
+
waiter.reject(error);
|
|
1327
|
+
}
|
|
1334
1328
|
this.onError(
|
|
1335
1329
|
new Error(`Failed to process subscriber offer: ${String(error)}`)
|
|
1336
1330
|
);
|
|
@@ -1352,11 +1346,20 @@ var SFUClient = class {
|
|
|
1352
1346
|
if (!uniqueIds.length || !this.isSocketOpen()) return;
|
|
1353
1347
|
uniqueIds.forEach((id) => this.subscribedTracks.add(id));
|
|
1354
1348
|
return new Promise((resolve, reject) => {
|
|
1355
|
-
this.
|
|
1356
|
-
this.send({
|
|
1349
|
+
const sent = this.send({
|
|
1357
1350
|
type: "subscribe",
|
|
1358
1351
|
payload: { track_ids: uniqueIds }
|
|
1359
1352
|
});
|
|
1353
|
+
if (!sent) {
|
|
1354
|
+
uniqueIds.forEach((id) => this.subscribedTracks.delete(id));
|
|
1355
|
+
reject(new Error("Signaling socket is not open"));
|
|
1356
|
+
return;
|
|
1357
|
+
}
|
|
1358
|
+
this.subscriptionWaiters.push({
|
|
1359
|
+
trackIds: uniqueIds,
|
|
1360
|
+
resolve,
|
|
1361
|
+
reject
|
|
1362
|
+
});
|
|
1360
1363
|
});
|
|
1361
1364
|
}
|
|
1362
1365
|
async processSubscriptionQueue() {
|
|
@@ -1369,11 +1372,20 @@ var SFUClient = class {
|
|
|
1369
1372
|
continue;
|
|
1370
1373
|
}
|
|
1371
1374
|
await new Promise((resolve, reject) => {
|
|
1372
|
-
this.
|
|
1373
|
-
this.send({
|
|
1375
|
+
const sent = this.send({
|
|
1374
1376
|
type: "subscribe",
|
|
1375
1377
|
payload: { track_ids: [trackId] }
|
|
1376
1378
|
});
|
|
1379
|
+
if (!sent) {
|
|
1380
|
+
this.subscribedTracks.delete(trackId);
|
|
1381
|
+
reject(new Error("Signaling socket is not open"));
|
|
1382
|
+
return;
|
|
1383
|
+
}
|
|
1384
|
+
this.subscriptionWaiters.push({
|
|
1385
|
+
trackIds: [trackId],
|
|
1386
|
+
resolve,
|
|
1387
|
+
reject
|
|
1388
|
+
});
|
|
1377
1389
|
});
|
|
1378
1390
|
}
|
|
1379
1391
|
} finally {
|
|
@@ -1431,9 +1443,16 @@ var SFUClient = class {
|
|
|
1431
1443
|
if (!this.screenTransceiver || !this.screenSender) {
|
|
1432
1444
|
throw new Error("Screen transceiver is not initialized");
|
|
1433
1445
|
}
|
|
1434
|
-
|
|
1435
|
-
|
|
1446
|
+
const existing = this.screenStream;
|
|
1447
|
+
const existingTrack = this.screenSender.track;
|
|
1448
|
+
if (existing || existingTrack && existingTrack.readyState === "live") {
|
|
1449
|
+
return existing;
|
|
1436
1450
|
}
|
|
1451
|
+
try {
|
|
1452
|
+
await this.screenSender.replaceTrack(null);
|
|
1453
|
+
} catch {
|
|
1454
|
+
}
|
|
1455
|
+
this.screenTransceiver.direction = "inactive";
|
|
1437
1456
|
const screenStream = await navigator.mediaDevices.getDisplayMedia({
|
|
1438
1457
|
video: true,
|
|
1439
1458
|
audio: false
|
|
@@ -1443,29 +1462,33 @@ var SFUClient = class {
|
|
|
1443
1462
|
screenStream.getTracks().forEach((track) => track.stop());
|
|
1444
1463
|
throw new Error("Screen share returned no video track");
|
|
1445
1464
|
}
|
|
1465
|
+
const generation = ++this.screenShareGeneration;
|
|
1446
1466
|
this.screenStream = screenStream;
|
|
1447
1467
|
try {
|
|
1448
1468
|
await this.screenSender.replaceTrack(screenTrack);
|
|
1449
1469
|
this.screenTransceiver.direction = "sendonly";
|
|
1470
|
+
this.send({
|
|
1471
|
+
type: "start_screen_share"
|
|
1472
|
+
});
|
|
1450
1473
|
const offer = await this.publisher.createOffer();
|
|
1451
1474
|
await this.publisher.setLocalDescription(offer);
|
|
1475
|
+
const localDescription = this.publisher.localDescription;
|
|
1476
|
+
if (!localDescription?.sdp) {
|
|
1477
|
+
throw new Error("Publisher did not produce a valid screen-share SDP");
|
|
1478
|
+
}
|
|
1452
1479
|
this.send({
|
|
1453
1480
|
type: "publish_offer",
|
|
1454
1481
|
payload: {
|
|
1455
1482
|
revision: ++this.publisherRevision,
|
|
1456
|
-
sdp:
|
|
1483
|
+
sdp: localDescription.sdp
|
|
1457
1484
|
}
|
|
1458
1485
|
});
|
|
1459
|
-
this.send({ type: "start_screen_share" });
|
|
1460
1486
|
screenTrack.onended = () => {
|
|
1487
|
+
if (generation !== this.screenShareGeneration) {
|
|
1488
|
+
return;
|
|
1489
|
+
}
|
|
1461
1490
|
void this.stopScreenShare();
|
|
1462
1491
|
};
|
|
1463
|
-
console.info("[publisher] Screen track attached", {
|
|
1464
|
-
screenTrackId: screenTrack.id,
|
|
1465
|
-
cameraTrackId: this.videoSender?.track?.id,
|
|
1466
|
-
screenMid: this.screenTransceiver.mid,
|
|
1467
|
-
cameraMid: this.cameraTransceiver?.mid
|
|
1468
|
-
});
|
|
1469
1492
|
return this.screenStream;
|
|
1470
1493
|
} catch (error) {
|
|
1471
1494
|
try {
|
|
@@ -1473,19 +1496,33 @@ var SFUClient = class {
|
|
|
1473
1496
|
} catch {
|
|
1474
1497
|
}
|
|
1475
1498
|
this.screenTransceiver.direction = "inactive";
|
|
1476
|
-
|
|
1499
|
+
screenTrack.onended = null;
|
|
1500
|
+
screenStream.getTracks().forEach((track) => {
|
|
1501
|
+
try {
|
|
1502
|
+
track.stop();
|
|
1503
|
+
} catch {
|
|
1504
|
+
}
|
|
1505
|
+
});
|
|
1477
1506
|
this.screenStream = null;
|
|
1478
1507
|
try {
|
|
1479
|
-
this.send({
|
|
1508
|
+
this.send({
|
|
1509
|
+
type: "stop_screen_share"
|
|
1510
|
+
});
|
|
1480
1511
|
} catch {
|
|
1481
1512
|
}
|
|
1482
1513
|
throw error;
|
|
1483
1514
|
}
|
|
1484
1515
|
}
|
|
1485
1516
|
async stopScreenShare() {
|
|
1486
|
-
|
|
1487
|
-
const
|
|
1488
|
-
if (
|
|
1517
|
+
const stream = this.screenStream;
|
|
1518
|
+
const senderTrack = this.screenSender?.track || null;
|
|
1519
|
+
if (!stream && !senderTrack) {
|
|
1520
|
+
return;
|
|
1521
|
+
}
|
|
1522
|
+
++this.screenShareGeneration;
|
|
1523
|
+
if (senderTrack) {
|
|
1524
|
+
senderTrack.onended = null;
|
|
1525
|
+
}
|
|
1489
1526
|
try {
|
|
1490
1527
|
await this.screenSender?.replaceTrack(null);
|
|
1491
1528
|
} catch (error) {
|
|
@@ -1494,23 +1531,33 @@ var SFUClient = class {
|
|
|
1494
1531
|
if (this.screenTransceiver) {
|
|
1495
1532
|
this.screenTransceiver.direction = "inactive";
|
|
1496
1533
|
}
|
|
1497
|
-
this.send({ type: "stop_screen_share" });
|
|
1498
1534
|
try {
|
|
1499
|
-
|
|
1500
|
-
|
|
1535
|
+
if (this.publisher) {
|
|
1536
|
+
const offer = await this.publisher.createOffer();
|
|
1501
1537
|
await this.publisher.setLocalDescription(offer);
|
|
1502
|
-
this.
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1538
|
+
const localDescription = this.publisher.localDescription;
|
|
1539
|
+
if (localDescription?.sdp) {
|
|
1540
|
+
this.send({
|
|
1541
|
+
type: "publish_offer",
|
|
1542
|
+
payload: {
|
|
1543
|
+
revision: ++this.publisherRevision,
|
|
1544
|
+
sdp: localDescription.sdp
|
|
1545
|
+
}
|
|
1546
|
+
});
|
|
1547
|
+
}
|
|
1509
1548
|
}
|
|
1510
1549
|
} catch (error) {
|
|
1511
1550
|
this.onError(error);
|
|
1512
1551
|
}
|
|
1513
|
-
this.
|
|
1552
|
+
this.send({
|
|
1553
|
+
type: "stop_screen_share"
|
|
1554
|
+
});
|
|
1555
|
+
stream?.getTracks().forEach((track) => {
|
|
1556
|
+
try {
|
|
1557
|
+
track.stop();
|
|
1558
|
+
} catch {
|
|
1559
|
+
}
|
|
1560
|
+
});
|
|
1514
1561
|
this.screenStream = null;
|
|
1515
1562
|
if (this.currentParticipantId) {
|
|
1516
1563
|
this.onScreenShareStopped(this.currentParticipantId);
|
|
@@ -2274,11 +2321,11 @@ var VideoSDKCore = class {
|
|
|
2274
2321
|
// SCREEN SHARE
|
|
2275
2322
|
onScreenShareStarted: (participantId, _track) => {
|
|
2276
2323
|
console.log("[SFU] Screen share started", participantId);
|
|
2277
|
-
if (participantId === this.myId && !this.screenStream) {
|
|
2278
|
-
this.screenStream = this.sfuClient?.getScreenStream() ?? null;
|
|
2279
|
-
}
|
|
2280
|
-
this.state.setPresenterId(participantId);
|
|
2281
2324
|
if (participantId === this.myId) {
|
|
2325
|
+
if (!this.screenStream) {
|
|
2326
|
+
this.screenStream = this.sfuClient?.getScreenStream() ?? null;
|
|
2327
|
+
}
|
|
2328
|
+
this.state.setPresenterId(participantId);
|
|
2282
2329
|
this.state.updateLocalParticipant({
|
|
2283
2330
|
media: {
|
|
2284
2331
|
isScreenSharing: true,
|
|
@@ -2288,11 +2335,25 @@ var VideoSDKCore = class {
|
|
|
2288
2335
|
});
|
|
2289
2336
|
return;
|
|
2290
2337
|
}
|
|
2338
|
+
this.state.setPresenterId(participantId);
|
|
2339
|
+
const existingRemoteScreen = this.sfuClient?.getRemoteScreenStream(participantId) ?? this.remoteScreenStreams.get(participantId) ?? null;
|
|
2340
|
+
if (existingRemoteScreen) {
|
|
2341
|
+
this.remoteScreenStreams.set(participantId, existingRemoteScreen);
|
|
2342
|
+
const screenTrack = existingRemoteScreen.getVideoTracks()[0];
|
|
2343
|
+
this.state.updateParticipantMedia(participantId, {
|
|
2344
|
+
isScreenSharing: true,
|
|
2345
|
+
screenStream: existingRemoteScreen,
|
|
2346
|
+
screenTrack
|
|
2347
|
+
});
|
|
2348
|
+
this.events.onScreenShareStarted?.(participantId, existingRemoteScreen);
|
|
2349
|
+
return;
|
|
2350
|
+
}
|
|
2291
2351
|
const current = this.state.getParticipant(participantId);
|
|
2292
2352
|
if (current) {
|
|
2293
2353
|
this.state.updateParticipantMedia(participantId, {
|
|
2294
2354
|
isScreenSharing: true,
|
|
2295
|
-
screenStream: current.media?.screenStream ?? null
|
|
2355
|
+
screenStream: current.media?.screenStream ?? null,
|
|
2356
|
+
screenTrack: current.media?.screenTrack
|
|
2296
2357
|
});
|
|
2297
2358
|
}
|
|
2298
2359
|
},
|
|
@@ -2310,13 +2371,8 @@ var VideoSDKCore = class {
|
|
|
2310
2371
|
});
|
|
2311
2372
|
return;
|
|
2312
2373
|
}
|
|
2313
|
-
const screen = this.remoteScreenStreams.get(participantId);
|
|
2314
|
-
screen?.getTracks().forEach((track) => track.stop());
|
|
2315
|
-
this.remoteScreenStreams.delete(participantId);
|
|
2316
2374
|
this.state.updateParticipantMedia(participantId, {
|
|
2317
|
-
isScreenSharing: false
|
|
2318
|
-
screenStream: null,
|
|
2319
|
-
screenTrack: void 0
|
|
2375
|
+
isScreenSharing: false
|
|
2320
2376
|
});
|
|
2321
2377
|
this.events.onScreenShareStopped?.(participantId);
|
|
2322
2378
|
},
|