@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.d.mts
CHANGED
|
@@ -219,7 +219,7 @@ declare class VideoSDKCore {
|
|
|
219
219
|
rejectJoinRequest(requestId: string, reason?: string): Promise<void>;
|
|
220
220
|
toggleMic(): void;
|
|
221
221
|
toggleCam(): void;
|
|
222
|
-
startScreenShare(): Promise<MediaStream>;
|
|
222
|
+
startScreenShare(): Promise<MediaStream | null>;
|
|
223
223
|
stopScreenShare(): Promise<void>;
|
|
224
224
|
startRecording(): Promise<void>;
|
|
225
225
|
stopRecording(): Promise<void>;
|
|
@@ -392,6 +392,7 @@ declare class SFUClient {
|
|
|
392
392
|
getResumeToken(): string | null;
|
|
393
393
|
getLocalStream(): MediaStream | null;
|
|
394
394
|
getScreenStream(): MediaStream | null;
|
|
395
|
+
getRemoteScreenStream(participantId: string): MediaStream | null;
|
|
395
396
|
setLocalStream(stream: MediaStream | null): void;
|
|
396
397
|
private nextRequestId;
|
|
397
398
|
private request;
|
|
@@ -436,7 +437,7 @@ declare class SFUClient {
|
|
|
436
437
|
video?: boolean | undefined;
|
|
437
438
|
}): Promise<MediaStream>;
|
|
438
439
|
private publishExistingTracks;
|
|
439
|
-
shareScreen(): Promise<MediaStream>;
|
|
440
|
+
shareScreen(): Promise<MediaStream | null>;
|
|
440
441
|
stopScreenShare(): Promise<void>;
|
|
441
442
|
muteAudio(muted: boolean): void;
|
|
442
443
|
muteVideo(muted: boolean): void;
|
package/dist/index.d.ts
CHANGED
|
@@ -219,7 +219,7 @@ declare class VideoSDKCore {
|
|
|
219
219
|
rejectJoinRequest(requestId: string, reason?: string): Promise<void>;
|
|
220
220
|
toggleMic(): void;
|
|
221
221
|
toggleCam(): void;
|
|
222
|
-
startScreenShare(): Promise<MediaStream>;
|
|
222
|
+
startScreenShare(): Promise<MediaStream | null>;
|
|
223
223
|
stopScreenShare(): Promise<void>;
|
|
224
224
|
startRecording(): Promise<void>;
|
|
225
225
|
stopRecording(): Promise<void>;
|
|
@@ -392,6 +392,7 @@ declare class SFUClient {
|
|
|
392
392
|
getResumeToken(): string | null;
|
|
393
393
|
getLocalStream(): MediaStream | null;
|
|
394
394
|
getScreenStream(): MediaStream | null;
|
|
395
|
+
getRemoteScreenStream(participantId: string): MediaStream | null;
|
|
395
396
|
setLocalStream(stream: MediaStream | null): void;
|
|
396
397
|
private nextRequestId;
|
|
397
398
|
private request;
|
|
@@ -436,7 +437,7 @@ declare class SFUClient {
|
|
|
436
437
|
video?: boolean | undefined;
|
|
437
438
|
}): Promise<MediaStream>;
|
|
438
439
|
private publishExistingTracks;
|
|
439
|
-
shareScreen(): Promise<MediaStream>;
|
|
440
|
+
shareScreen(): Promise<MediaStream | null>;
|
|
440
441
|
stopScreenShare(): Promise<void>;
|
|
441
442
|
muteAudio(muted: boolean): void;
|
|
442
443
|
muteVideo(muted: boolean): void;
|
package/dist/index.js
CHANGED
|
@@ -548,6 +548,9 @@ var SFUClient = class {
|
|
|
548
548
|
getScreenStream() {
|
|
549
549
|
return this.screenStream;
|
|
550
550
|
}
|
|
551
|
+
getRemoteScreenStream(participantId) {
|
|
552
|
+
return this.remoteScreenStreams.get(participantId) || null;
|
|
553
|
+
}
|
|
551
554
|
setLocalStream(stream) {
|
|
552
555
|
this.localStream = stream;
|
|
553
556
|
}
|
|
@@ -967,19 +970,7 @@ var SFUClient = class {
|
|
|
967
970
|
}
|
|
968
971
|
case "screen_share_stopped": {
|
|
969
972
|
const participantId = payload.participant_id;
|
|
970
|
-
const screenStream = participantId ? this.remoteScreenStreams.get(participantId) : null;
|
|
971
973
|
const trackId = payload.track_id;
|
|
972
|
-
if (screenStream) {
|
|
973
|
-
for (const track of screenStream.getVideoTracks()) {
|
|
974
|
-
if (!trackId || this.normalizeRemoteTrackId(track.id) === String(trackId)) {
|
|
975
|
-
screenStream.removeTrack(track);
|
|
976
|
-
track.stop();
|
|
977
|
-
}
|
|
978
|
-
}
|
|
979
|
-
if (screenStream.getTracks().length === 0 && participantId) {
|
|
980
|
-
this.remoteScreenStreams.delete(participantId);
|
|
981
|
-
}
|
|
982
|
-
}
|
|
983
974
|
this.onScreenShareStopped(participantId, trackId);
|
|
984
975
|
break;
|
|
985
976
|
}
|
|
@@ -1362,11 +1353,14 @@ var SFUClient = class {
|
|
|
1362
1353
|
sdp: answer.sdp
|
|
1363
1354
|
}
|
|
1364
1355
|
});
|
|
1365
|
-
const
|
|
1366
|
-
|
|
1356
|
+
const waiter = this.subscriptionWaiters.shift();
|
|
1357
|
+
waiter?.resolve();
|
|
1367
1358
|
} catch (error) {
|
|
1368
|
-
const
|
|
1369
|
-
|
|
1359
|
+
const waiter = this.subscriptionWaiters.shift();
|
|
1360
|
+
if (waiter) {
|
|
1361
|
+
waiter.trackIds.forEach((id) => this.subscribedTracks.delete(id));
|
|
1362
|
+
waiter.reject(error);
|
|
1363
|
+
}
|
|
1370
1364
|
this.onError(
|
|
1371
1365
|
new Error(`Failed to process subscriber offer: ${String(error)}`)
|
|
1372
1366
|
);
|
|
@@ -1388,11 +1382,20 @@ var SFUClient = class {
|
|
|
1388
1382
|
if (!uniqueIds.length || !this.isSocketOpen()) return;
|
|
1389
1383
|
uniqueIds.forEach((id) => this.subscribedTracks.add(id));
|
|
1390
1384
|
return new Promise((resolve, reject) => {
|
|
1391
|
-
this.
|
|
1392
|
-
this.send({
|
|
1385
|
+
const sent = this.send({
|
|
1393
1386
|
type: "subscribe",
|
|
1394
1387
|
payload: { track_ids: uniqueIds }
|
|
1395
1388
|
});
|
|
1389
|
+
if (!sent) {
|
|
1390
|
+
uniqueIds.forEach((id) => this.subscribedTracks.delete(id));
|
|
1391
|
+
reject(new Error("Signaling socket is not open"));
|
|
1392
|
+
return;
|
|
1393
|
+
}
|
|
1394
|
+
this.subscriptionWaiters.push({
|
|
1395
|
+
trackIds: uniqueIds,
|
|
1396
|
+
resolve,
|
|
1397
|
+
reject
|
|
1398
|
+
});
|
|
1396
1399
|
});
|
|
1397
1400
|
}
|
|
1398
1401
|
async processSubscriptionQueue() {
|
|
@@ -1405,11 +1408,20 @@ var SFUClient = class {
|
|
|
1405
1408
|
continue;
|
|
1406
1409
|
}
|
|
1407
1410
|
await new Promise((resolve, reject) => {
|
|
1408
|
-
this.
|
|
1409
|
-
this.send({
|
|
1411
|
+
const sent = this.send({
|
|
1410
1412
|
type: "subscribe",
|
|
1411
1413
|
payload: { track_ids: [trackId] }
|
|
1412
1414
|
});
|
|
1415
|
+
if (!sent) {
|
|
1416
|
+
this.subscribedTracks.delete(trackId);
|
|
1417
|
+
reject(new Error("Signaling socket is not open"));
|
|
1418
|
+
return;
|
|
1419
|
+
}
|
|
1420
|
+
this.subscriptionWaiters.push({
|
|
1421
|
+
trackIds: [trackId],
|
|
1422
|
+
resolve,
|
|
1423
|
+
reject
|
|
1424
|
+
});
|
|
1413
1425
|
});
|
|
1414
1426
|
}
|
|
1415
1427
|
} finally {
|
|
@@ -1467,9 +1479,16 @@ var SFUClient = class {
|
|
|
1467
1479
|
if (!this.screenTransceiver || !this.screenSender) {
|
|
1468
1480
|
throw new Error("Screen transceiver is not initialized");
|
|
1469
1481
|
}
|
|
1470
|
-
|
|
1471
|
-
|
|
1482
|
+
const existing = this.screenStream;
|
|
1483
|
+
const existingTrack = this.screenSender.track;
|
|
1484
|
+
if (existing || existingTrack && existingTrack.readyState === "live") {
|
|
1485
|
+
return existing;
|
|
1472
1486
|
}
|
|
1487
|
+
try {
|
|
1488
|
+
await this.screenSender.replaceTrack(null);
|
|
1489
|
+
} catch {
|
|
1490
|
+
}
|
|
1491
|
+
this.screenTransceiver.direction = "inactive";
|
|
1473
1492
|
const screenStream = await navigator.mediaDevices.getDisplayMedia({
|
|
1474
1493
|
video: true,
|
|
1475
1494
|
audio: false
|
|
@@ -1479,29 +1498,33 @@ var SFUClient = class {
|
|
|
1479
1498
|
screenStream.getTracks().forEach((track) => track.stop());
|
|
1480
1499
|
throw new Error("Screen share returned no video track");
|
|
1481
1500
|
}
|
|
1501
|
+
const generation = ++this.screenShareGeneration;
|
|
1482
1502
|
this.screenStream = screenStream;
|
|
1483
1503
|
try {
|
|
1484
1504
|
await this.screenSender.replaceTrack(screenTrack);
|
|
1485
1505
|
this.screenTransceiver.direction = "sendonly";
|
|
1506
|
+
this.send({
|
|
1507
|
+
type: "start_screen_share"
|
|
1508
|
+
});
|
|
1486
1509
|
const offer = await this.publisher.createOffer();
|
|
1487
1510
|
await this.publisher.setLocalDescription(offer);
|
|
1511
|
+
const localDescription = this.publisher.localDescription;
|
|
1512
|
+
if (!localDescription?.sdp) {
|
|
1513
|
+
throw new Error("Publisher did not produce a valid screen-share SDP");
|
|
1514
|
+
}
|
|
1488
1515
|
this.send({
|
|
1489
1516
|
type: "publish_offer",
|
|
1490
1517
|
payload: {
|
|
1491
1518
|
revision: ++this.publisherRevision,
|
|
1492
|
-
sdp:
|
|
1519
|
+
sdp: localDescription.sdp
|
|
1493
1520
|
}
|
|
1494
1521
|
});
|
|
1495
|
-
this.send({ type: "start_screen_share" });
|
|
1496
1522
|
screenTrack.onended = () => {
|
|
1523
|
+
if (generation !== this.screenShareGeneration) {
|
|
1524
|
+
return;
|
|
1525
|
+
}
|
|
1497
1526
|
void this.stopScreenShare();
|
|
1498
1527
|
};
|
|
1499
|
-
console.info("[publisher] Screen track attached", {
|
|
1500
|
-
screenTrackId: screenTrack.id,
|
|
1501
|
-
cameraTrackId: this.videoSender?.track?.id,
|
|
1502
|
-
screenMid: this.screenTransceiver.mid,
|
|
1503
|
-
cameraMid: this.cameraTransceiver?.mid
|
|
1504
|
-
});
|
|
1505
1528
|
return this.screenStream;
|
|
1506
1529
|
} catch (error) {
|
|
1507
1530
|
try {
|
|
@@ -1509,19 +1532,33 @@ var SFUClient = class {
|
|
|
1509
1532
|
} catch {
|
|
1510
1533
|
}
|
|
1511
1534
|
this.screenTransceiver.direction = "inactive";
|
|
1512
|
-
|
|
1535
|
+
screenTrack.onended = null;
|
|
1536
|
+
screenStream.getTracks().forEach((track) => {
|
|
1537
|
+
try {
|
|
1538
|
+
track.stop();
|
|
1539
|
+
} catch {
|
|
1540
|
+
}
|
|
1541
|
+
});
|
|
1513
1542
|
this.screenStream = null;
|
|
1514
1543
|
try {
|
|
1515
|
-
this.send({
|
|
1544
|
+
this.send({
|
|
1545
|
+
type: "stop_screen_share"
|
|
1546
|
+
});
|
|
1516
1547
|
} catch {
|
|
1517
1548
|
}
|
|
1518
1549
|
throw error;
|
|
1519
1550
|
}
|
|
1520
1551
|
}
|
|
1521
1552
|
async stopScreenShare() {
|
|
1522
|
-
|
|
1523
|
-
const
|
|
1524
|
-
if (
|
|
1553
|
+
const stream = this.screenStream;
|
|
1554
|
+
const senderTrack = this.screenSender?.track || null;
|
|
1555
|
+
if (!stream && !senderTrack) {
|
|
1556
|
+
return;
|
|
1557
|
+
}
|
|
1558
|
+
++this.screenShareGeneration;
|
|
1559
|
+
if (senderTrack) {
|
|
1560
|
+
senderTrack.onended = null;
|
|
1561
|
+
}
|
|
1525
1562
|
try {
|
|
1526
1563
|
await this.screenSender?.replaceTrack(null);
|
|
1527
1564
|
} catch (error) {
|
|
@@ -1530,23 +1567,33 @@ var SFUClient = class {
|
|
|
1530
1567
|
if (this.screenTransceiver) {
|
|
1531
1568
|
this.screenTransceiver.direction = "inactive";
|
|
1532
1569
|
}
|
|
1533
|
-
this.send({ type: "stop_screen_share" });
|
|
1534
1570
|
try {
|
|
1535
|
-
|
|
1536
|
-
|
|
1571
|
+
if (this.publisher) {
|
|
1572
|
+
const offer = await this.publisher.createOffer();
|
|
1537
1573
|
await this.publisher.setLocalDescription(offer);
|
|
1538
|
-
this.
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1574
|
+
const localDescription = this.publisher.localDescription;
|
|
1575
|
+
if (localDescription?.sdp) {
|
|
1576
|
+
this.send({
|
|
1577
|
+
type: "publish_offer",
|
|
1578
|
+
payload: {
|
|
1579
|
+
revision: ++this.publisherRevision,
|
|
1580
|
+
sdp: localDescription.sdp
|
|
1581
|
+
}
|
|
1582
|
+
});
|
|
1583
|
+
}
|
|
1545
1584
|
}
|
|
1546
1585
|
} catch (error) {
|
|
1547
1586
|
this.onError(error);
|
|
1548
1587
|
}
|
|
1549
|
-
this.
|
|
1588
|
+
this.send({
|
|
1589
|
+
type: "stop_screen_share"
|
|
1590
|
+
});
|
|
1591
|
+
stream?.getTracks().forEach((track) => {
|
|
1592
|
+
try {
|
|
1593
|
+
track.stop();
|
|
1594
|
+
} catch {
|
|
1595
|
+
}
|
|
1596
|
+
});
|
|
1550
1597
|
this.screenStream = null;
|
|
1551
1598
|
if (this.currentParticipantId) {
|
|
1552
1599
|
this.onScreenShareStopped(this.currentParticipantId);
|
|
@@ -2310,11 +2357,11 @@ var VideoSDKCore = class {
|
|
|
2310
2357
|
// SCREEN SHARE
|
|
2311
2358
|
onScreenShareStarted: (participantId, _track) => {
|
|
2312
2359
|
console.log("[SFU] Screen share started", participantId);
|
|
2313
|
-
if (participantId === this.myId && !this.screenStream) {
|
|
2314
|
-
this.screenStream = this.sfuClient?.getScreenStream() ?? null;
|
|
2315
|
-
}
|
|
2316
|
-
this.state.setPresenterId(participantId);
|
|
2317
2360
|
if (participantId === this.myId) {
|
|
2361
|
+
if (!this.screenStream) {
|
|
2362
|
+
this.screenStream = this.sfuClient?.getScreenStream() ?? null;
|
|
2363
|
+
}
|
|
2364
|
+
this.state.setPresenterId(participantId);
|
|
2318
2365
|
this.state.updateLocalParticipant({
|
|
2319
2366
|
media: {
|
|
2320
2367
|
isScreenSharing: true,
|
|
@@ -2324,11 +2371,25 @@ var VideoSDKCore = class {
|
|
|
2324
2371
|
});
|
|
2325
2372
|
return;
|
|
2326
2373
|
}
|
|
2374
|
+
this.state.setPresenterId(participantId);
|
|
2375
|
+
const existingRemoteScreen = this.sfuClient?.getRemoteScreenStream(participantId) ?? this.remoteScreenStreams.get(participantId) ?? null;
|
|
2376
|
+
if (existingRemoteScreen) {
|
|
2377
|
+
this.remoteScreenStreams.set(participantId, existingRemoteScreen);
|
|
2378
|
+
const screenTrack = existingRemoteScreen.getVideoTracks()[0];
|
|
2379
|
+
this.state.updateParticipantMedia(participantId, {
|
|
2380
|
+
isScreenSharing: true,
|
|
2381
|
+
screenStream: existingRemoteScreen,
|
|
2382
|
+
screenTrack
|
|
2383
|
+
});
|
|
2384
|
+
this.events.onScreenShareStarted?.(participantId, existingRemoteScreen);
|
|
2385
|
+
return;
|
|
2386
|
+
}
|
|
2327
2387
|
const current = this.state.getParticipant(participantId);
|
|
2328
2388
|
if (current) {
|
|
2329
2389
|
this.state.updateParticipantMedia(participantId, {
|
|
2330
2390
|
isScreenSharing: true,
|
|
2331
|
-
screenStream: current.media?.screenStream ?? null
|
|
2391
|
+
screenStream: current.media?.screenStream ?? null,
|
|
2392
|
+
screenTrack: current.media?.screenTrack
|
|
2332
2393
|
});
|
|
2333
2394
|
}
|
|
2334
2395
|
},
|
|
@@ -2346,13 +2407,8 @@ var VideoSDKCore = class {
|
|
|
2346
2407
|
});
|
|
2347
2408
|
return;
|
|
2348
2409
|
}
|
|
2349
|
-
const screen = this.remoteScreenStreams.get(participantId);
|
|
2350
|
-
screen?.getTracks().forEach((track) => track.stop());
|
|
2351
|
-
this.remoteScreenStreams.delete(participantId);
|
|
2352
2410
|
this.state.updateParticipantMedia(participantId, {
|
|
2353
|
-
isScreenSharing: false
|
|
2354
|
-
screenStream: null,
|
|
2355
|
-
screenTrack: void 0
|
|
2411
|
+
isScreenSharing: false
|
|
2356
2412
|
});
|
|
2357
2413
|
this.events.onScreenShareStopped?.(participantId);
|
|
2358
2414
|
},
|