@defcomm/meetingsdk 0.2.6 → 0.2.8
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 +38 -1
- package/dist/index.d.ts +38 -1
- package/dist/index.js +278 -49
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +278 -49
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -393,6 +393,7 @@ var SFUClient = class {
|
|
|
393
393
|
this.iceServers = [];
|
|
394
394
|
this.requestId = 0;
|
|
395
395
|
this.publisherRevision = 0;
|
|
396
|
+
this.screenShareGeneration = 0;
|
|
396
397
|
this.currentParticipantId = null;
|
|
397
398
|
this.token = null;
|
|
398
399
|
this.room = null;
|
|
@@ -403,6 +404,8 @@ var SFUClient = class {
|
|
|
403
404
|
this.intentionalClose = false;
|
|
404
405
|
this.leaveAcknowledged = false;
|
|
405
406
|
this.joiningWithResume = false;
|
|
407
|
+
this.desiredAudioMuted = false;
|
|
408
|
+
this.desiredVideoMuted = false;
|
|
406
409
|
this.reconnectTimer = null;
|
|
407
410
|
this.reconnectAttempt = 0;
|
|
408
411
|
this.maxReconnectAttempts = 8;
|
|
@@ -471,6 +474,14 @@ var SFUClient = class {
|
|
|
471
474
|
this.onRecordingStopped = options.onRecordingStopped || (() => {
|
|
472
475
|
});
|
|
473
476
|
this.onError = options.onError || console.error;
|
|
477
|
+
this.onChatMessage = options.onChatMessage || (() => {
|
|
478
|
+
});
|
|
479
|
+
this.onReaction = options.onReaction || (() => {
|
|
480
|
+
});
|
|
481
|
+
this.onRoomUpdate = options.onRoomUpdate || (() => {
|
|
482
|
+
});
|
|
483
|
+
this.onParticipantMediaState = options.onParticipantMediaState || (() => {
|
|
484
|
+
});
|
|
474
485
|
this.autoSubscribe = options.autoSubscribe !== false;
|
|
475
486
|
}
|
|
476
487
|
startHeartbeat() {
|
|
@@ -593,6 +604,10 @@ var SFUClient = class {
|
|
|
593
604
|
avatarUrl: options.avatarUrl
|
|
594
605
|
};
|
|
595
606
|
if (options.participantId) this.participantId = options.participantId;
|
|
607
|
+
if (typeof options.audioMuted === "boolean")
|
|
608
|
+
this.desiredAudioMuted = options.audioMuted;
|
|
609
|
+
if (typeof options.videoMuted === "boolean")
|
|
610
|
+
this.desiredVideoMuted = options.videoMuted;
|
|
596
611
|
if (!this.resumeToken) {
|
|
597
612
|
this.resumeToken = this.loadResumeToken(this.room);
|
|
598
613
|
}
|
|
@@ -659,7 +674,9 @@ var SFUClient = class {
|
|
|
659
674
|
room_code: this.room,
|
|
660
675
|
resume_token: this.resumeToken,
|
|
661
676
|
display_name: options.displayName,
|
|
662
|
-
avatar_url: options.avatarUrl
|
|
677
|
+
avatar_url: options.avatarUrl,
|
|
678
|
+
audio_muted: this.desiredAudioMuted,
|
|
679
|
+
video_muted: this.desiredVideoMuted
|
|
663
680
|
};
|
|
664
681
|
if (this.pendingJoinRequestId) {
|
|
665
682
|
this.send({
|
|
@@ -834,6 +851,16 @@ var SFUClient = class {
|
|
|
834
851
|
this.onParticipantLeft(participantId);
|
|
835
852
|
break;
|
|
836
853
|
}
|
|
854
|
+
case "participant_media_state": {
|
|
855
|
+
const participantId = payload.participant_id;
|
|
856
|
+
if (!participantId) break;
|
|
857
|
+
this.onParticipantMediaState(
|
|
858
|
+
participantId,
|
|
859
|
+
Boolean(payload.audio_muted),
|
|
860
|
+
Boolean(payload.video_muted)
|
|
861
|
+
);
|
|
862
|
+
break;
|
|
863
|
+
}
|
|
837
864
|
case "participant_presence":
|
|
838
865
|
case "participant_presence_changed": {
|
|
839
866
|
const participantId = payload.participant_id;
|
|
@@ -956,6 +983,50 @@ var SFUClient = class {
|
|
|
956
983
|
this.onScreenShareStopped(participantId, trackId);
|
|
957
984
|
break;
|
|
958
985
|
}
|
|
986
|
+
case "room_state": {
|
|
987
|
+
const participants = payload.participants || [];
|
|
988
|
+
this.onRoomStateReconciled(payload);
|
|
989
|
+
this.onRoomUpdate(payload);
|
|
990
|
+
for (const participant of participants) {
|
|
991
|
+
const pid = participant?.participant_id;
|
|
992
|
+
if (!pid) continue;
|
|
993
|
+
if (pid !== this.currentParticipantId) {
|
|
994
|
+
this.participants.set(pid, participant);
|
|
995
|
+
this.onParticipantPresence(
|
|
996
|
+
pid,
|
|
997
|
+
String(participant.presence || "connected")
|
|
998
|
+
);
|
|
999
|
+
this.onParticipantMediaState(
|
|
1000
|
+
pid,
|
|
1001
|
+
Boolean(participant.audio_muted),
|
|
1002
|
+
Boolean(participant.video_muted)
|
|
1003
|
+
);
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
for (const [pid] of this.participants) {
|
|
1007
|
+
if (!participants.some((p) => p?.participant_id === pid)) {
|
|
1008
|
+
this.participants.delete(pid);
|
|
1009
|
+
this.removeRemoteParticipant(pid);
|
|
1010
|
+
this.onParticipantLeft(pid);
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
for (const track of payload.tracks || []) this.rememberTrack(track);
|
|
1014
|
+
if (Array.isArray(payload.chat_history)) {
|
|
1015
|
+
for (const message2 of payload.chat_history)
|
|
1016
|
+
this.onChatMessage(message2);
|
|
1017
|
+
}
|
|
1018
|
+
break;
|
|
1019
|
+
}
|
|
1020
|
+
case "chat_message": {
|
|
1021
|
+
const msg = payload.message || payload;
|
|
1022
|
+
if (msg?.id) this.onChatMessage(msg);
|
|
1023
|
+
break;
|
|
1024
|
+
}
|
|
1025
|
+
case "reaction": {
|
|
1026
|
+
const reaction = payload.reaction || payload;
|
|
1027
|
+
if (reaction?.id && reaction?.emoji) this.onReaction(reaction);
|
|
1028
|
+
break;
|
|
1029
|
+
}
|
|
959
1030
|
case "error": {
|
|
960
1031
|
const message2 = payload.message || "SFU signaling error";
|
|
961
1032
|
if (this.state === "reconnecting" && message2.includes("participant session is stale")) {
|
|
@@ -978,6 +1049,16 @@ var SFUClient = class {
|
|
|
978
1049
|
console.debug("[SFU] Ignoring unknown server message", message);
|
|
979
1050
|
}
|
|
980
1051
|
}
|
|
1052
|
+
onRoomStateReconciled(payload) {
|
|
1053
|
+
const participants = payload.participants || [];
|
|
1054
|
+
const local = participants.find(
|
|
1055
|
+
(p) => p?.participant_id === this.currentParticipantId
|
|
1056
|
+
);
|
|
1057
|
+
if (local) {
|
|
1058
|
+
this.desiredAudioMuted = Boolean(local.audio_muted);
|
|
1059
|
+
this.desiredVideoMuted = Boolean(local.video_muted);
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
981
1062
|
rememberTrack(track) {
|
|
982
1063
|
this.trackMetadata.set(track.track_id, track);
|
|
983
1064
|
this.trackToParticipant.set(track.track_id, track.participant_id);
|
|
@@ -1013,8 +1094,21 @@ var SFUClient = class {
|
|
|
1013
1094
|
for (const participant of this.participants.values()) {
|
|
1014
1095
|
if (participant.participant_id !== this.currentParticipantId) {
|
|
1015
1096
|
this.onParticipantJoined(participant);
|
|
1097
|
+
this.onParticipantPresence(
|
|
1098
|
+
participant.participant_id,
|
|
1099
|
+
String(participant.presence || "connected")
|
|
1100
|
+
);
|
|
1101
|
+
this.onParticipantMediaState(
|
|
1102
|
+
participant.participant_id,
|
|
1103
|
+
Boolean(participant.audio_muted),
|
|
1104
|
+
Boolean(participant.video_muted)
|
|
1105
|
+
);
|
|
1016
1106
|
}
|
|
1017
1107
|
}
|
|
1108
|
+
if (Array.isArray(payload.chat_history)) {
|
|
1109
|
+
for (const message of payload.chat_history) this.onChatMessage(message);
|
|
1110
|
+
}
|
|
1111
|
+
this.onRoomUpdate(payload);
|
|
1018
1112
|
if (this.localStream) {
|
|
1019
1113
|
await this.publishExistingTracks();
|
|
1020
1114
|
}
|
|
@@ -1373,9 +1467,27 @@ var SFUClient = class {
|
|
|
1373
1467
|
if (!this.screenTransceiver || !this.screenSender) {
|
|
1374
1468
|
throw new Error("Screen transceiver is not initialized");
|
|
1375
1469
|
}
|
|
1376
|
-
|
|
1470
|
+
const existingTrack = this.screenSender.track;
|
|
1471
|
+
if (this.screenStream && existingTrack && existingTrack.readyState === "live") {
|
|
1377
1472
|
return this.screenStream;
|
|
1378
1473
|
}
|
|
1474
|
+
const generation = ++this.screenShareGeneration;
|
|
1475
|
+
try {
|
|
1476
|
+
await this.screenSender.replaceTrack(null);
|
|
1477
|
+
} catch (err) {
|
|
1478
|
+
console.warn("[SFU] Failed to clear previous screen track", err);
|
|
1479
|
+
}
|
|
1480
|
+
if (this.screenStream) {
|
|
1481
|
+
for (const track of this.screenStream.getTracks()) {
|
|
1482
|
+
try {
|
|
1483
|
+
track.onended = null;
|
|
1484
|
+
track.stop();
|
|
1485
|
+
} catch {
|
|
1486
|
+
}
|
|
1487
|
+
}
|
|
1488
|
+
}
|
|
1489
|
+
this.screenStream = null;
|
|
1490
|
+
this.screenTransceiver.direction = "inactive";
|
|
1379
1491
|
const screenStream = await navigator.mediaDevices.getDisplayMedia({
|
|
1380
1492
|
video: true,
|
|
1381
1493
|
audio: false
|
|
@@ -1387,83 +1499,99 @@ var SFUClient = class {
|
|
|
1387
1499
|
}
|
|
1388
1500
|
this.screenStream = screenStream;
|
|
1389
1501
|
try {
|
|
1390
|
-
if (!this.send({ type: "start_screen_share" })) {
|
|
1391
|
-
throw new Error("Failed to signal start_screen_share");
|
|
1392
|
-
}
|
|
1393
1502
|
await this.screenSender.replaceTrack(screenTrack);
|
|
1394
1503
|
this.screenTransceiver.direction = "sendonly";
|
|
1504
|
+
this.send({
|
|
1505
|
+
type: "start_screen_share"
|
|
1506
|
+
});
|
|
1507
|
+
await new Promise((resolve) => {
|
|
1508
|
+
queueMicrotask(resolve);
|
|
1509
|
+
});
|
|
1395
1510
|
const offer = await this.publisher.createOffer();
|
|
1396
1511
|
await this.publisher.setLocalDescription(offer);
|
|
1512
|
+
const localDescription = this.publisher.localDescription;
|
|
1513
|
+
if (!localDescription?.sdp) {
|
|
1514
|
+
throw new Error("Publisher did not produce a valid screen-share SDP");
|
|
1515
|
+
}
|
|
1516
|
+
const revision = ++this.publisherRevision;
|
|
1397
1517
|
this.send({
|
|
1398
1518
|
type: "publish_offer",
|
|
1399
1519
|
payload: {
|
|
1400
|
-
revision
|
|
1401
|
-
sdp:
|
|
1520
|
+
revision,
|
|
1521
|
+
sdp: localDescription.sdp
|
|
1402
1522
|
}
|
|
1403
1523
|
});
|
|
1404
1524
|
screenTrack.onended = () => {
|
|
1525
|
+
if (generation !== this.screenShareGeneration) {
|
|
1526
|
+
return;
|
|
1527
|
+
}
|
|
1405
1528
|
void this.stopScreenShare();
|
|
1406
1529
|
};
|
|
1407
|
-
|
|
1408
|
-
screenTrackId: screenTrack.id,
|
|
1409
|
-
cameraTrackId: this.videoSender?.track?.id,
|
|
1410
|
-
screenMid: this.screenTransceiver.mid,
|
|
1411
|
-
cameraMid: this.cameraTransceiver?.mid
|
|
1412
|
-
});
|
|
1413
|
-
return this.screenStream;
|
|
1530
|
+
return screenStream;
|
|
1414
1531
|
} catch (error) {
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1532
|
+
if (generation === this.screenShareGeneration) {
|
|
1533
|
+
try {
|
|
1534
|
+
await this.screenSender.replaceTrack(null);
|
|
1535
|
+
} catch {
|
|
1536
|
+
}
|
|
1537
|
+
this.screenTransceiver.direction = "inactive";
|
|
1538
|
+
screenTrack.onended = null;
|
|
1539
|
+
screenStream.getTracks().forEach((track) => {
|
|
1540
|
+
try {
|
|
1541
|
+
track.stop();
|
|
1542
|
+
} catch {
|
|
1543
|
+
}
|
|
1544
|
+
});
|
|
1545
|
+
this.screenStream = null;
|
|
1546
|
+
try {
|
|
1547
|
+
this.send({
|
|
1548
|
+
type: "stop_screen_share"
|
|
1549
|
+
});
|
|
1550
|
+
} catch {
|
|
1551
|
+
}
|
|
1425
1552
|
}
|
|
1426
1553
|
throw error;
|
|
1427
1554
|
}
|
|
1428
1555
|
}
|
|
1429
1556
|
async stopScreenShare() {
|
|
1430
|
-
|
|
1431
|
-
const
|
|
1432
|
-
if (
|
|
1557
|
+
const stream = this.screenStream;
|
|
1558
|
+
const senderTrack = this.screenSender?.track || null;
|
|
1559
|
+
if (!stream && !senderTrack) return;
|
|
1560
|
+
++this.screenShareGeneration;
|
|
1561
|
+
if (senderTrack) senderTrack.onended = null;
|
|
1433
1562
|
try {
|
|
1434
1563
|
await this.screenSender?.replaceTrack(null);
|
|
1435
1564
|
} catch (error) {
|
|
1436
1565
|
this.onError(error);
|
|
1437
1566
|
}
|
|
1438
|
-
if (this.screenTransceiver)
|
|
1439
|
-
this.screenTransceiver.direction = "inactive";
|
|
1440
|
-
}
|
|
1441
|
-
this.send({ type: "stop_screen_share" });
|
|
1567
|
+
if (this.screenTransceiver) this.screenTransceiver.direction = "inactive";
|
|
1442
1568
|
try {
|
|
1443
1569
|
const offer = await this.publisher?.createOffer();
|
|
1444
1570
|
if (offer && this.publisher) {
|
|
1445
1571
|
await this.publisher.setLocalDescription(offer);
|
|
1446
1572
|
this.send({
|
|
1447
1573
|
type: "publish_offer",
|
|
1448
|
-
payload: {
|
|
1449
|
-
revision: ++this.publisherRevision,
|
|
1450
|
-
sdp: offer.sdp
|
|
1451
|
-
}
|
|
1574
|
+
payload: { revision: ++this.publisherRevision, sdp: offer.sdp }
|
|
1452
1575
|
});
|
|
1453
1576
|
}
|
|
1454
1577
|
} catch (error) {
|
|
1455
1578
|
this.onError(error);
|
|
1456
1579
|
}
|
|
1457
|
-
this.
|
|
1580
|
+
this.send({ type: "stop_screen_share" });
|
|
1581
|
+
stream?.getTracks().forEach((track) => track.stop());
|
|
1458
1582
|
this.screenStream = null;
|
|
1459
|
-
if (this.currentParticipantId)
|
|
1583
|
+
if (this.currentParticipantId)
|
|
1460
1584
|
this.onScreenShareStopped(this.currentParticipantId);
|
|
1461
|
-
}
|
|
1462
1585
|
}
|
|
1463
1586
|
muteAudio(muted) {
|
|
1587
|
+
this.desiredAudioMuted = muted;
|
|
1464
1588
|
this.localStream?.getAudioTracks().forEach((track) => {
|
|
1465
1589
|
track.enabled = !muted;
|
|
1466
1590
|
});
|
|
1591
|
+
this.send({
|
|
1592
|
+
type: "set_media_state",
|
|
1593
|
+
payload: { audio_muted: muted, video_muted: this.desiredVideoMuted }
|
|
1594
|
+
});
|
|
1467
1595
|
const trackId = this.localTrackIds.get("audio");
|
|
1468
1596
|
if (trackId) {
|
|
1469
1597
|
this.send({
|
|
@@ -1476,9 +1604,14 @@ var SFUClient = class {
|
|
|
1476
1604
|
}
|
|
1477
1605
|
}
|
|
1478
1606
|
muteVideo(muted) {
|
|
1607
|
+
this.desiredVideoMuted = muted;
|
|
1479
1608
|
this.localStream?.getVideoTracks().forEach((track) => {
|
|
1480
1609
|
track.enabled = !muted;
|
|
1481
1610
|
});
|
|
1611
|
+
this.send({
|
|
1612
|
+
type: "set_media_state",
|
|
1613
|
+
payload: { audio_muted: this.desiredAudioMuted, video_muted: muted }
|
|
1614
|
+
});
|
|
1482
1615
|
const trackId = this.localTrackIds.get("camera");
|
|
1483
1616
|
if (trackId) {
|
|
1484
1617
|
this.send({
|
|
@@ -1490,6 +1623,16 @@ var SFUClient = class {
|
|
|
1490
1623
|
});
|
|
1491
1624
|
}
|
|
1492
1625
|
}
|
|
1626
|
+
sendChatMessage(input) {
|
|
1627
|
+
return this.send({
|
|
1628
|
+
type: "send_chat",
|
|
1629
|
+
payload: {
|
|
1630
|
+
message: input.message,
|
|
1631
|
+
reply_to: input.reply_to ?? null,
|
|
1632
|
+
target: input.target ?? null
|
|
1633
|
+
}
|
|
1634
|
+
});
|
|
1635
|
+
}
|
|
1493
1636
|
async startRecording() {
|
|
1494
1637
|
if (!this.send({ type: "start_recording" })) {
|
|
1495
1638
|
throw new Error("SFU signaling is not connected");
|
|
@@ -1541,6 +1684,12 @@ var SFUClient = class {
|
|
|
1541
1684
|
);
|
|
1542
1685
|
return true;
|
|
1543
1686
|
}
|
|
1687
|
+
sendReaction(reaction) {
|
|
1688
|
+
this.send({
|
|
1689
|
+
type: "send_reaction",
|
|
1690
|
+
reaction
|
|
1691
|
+
});
|
|
1692
|
+
}
|
|
1544
1693
|
removeRemoteParticipant(participantId) {
|
|
1545
1694
|
const stream = this.remoteStreams.get(participantId);
|
|
1546
1695
|
if (stream) {
|
|
@@ -1957,6 +2106,44 @@ var VideoSDKCore = class {
|
|
|
1957
2106
|
console.warn(`[SFU] Reconnecting, attempt ${attempt}`);
|
|
1958
2107
|
},
|
|
1959
2108
|
// ADMISSION CONTROL
|
|
2109
|
+
onRoomUpdate: (payload) => {
|
|
2110
|
+
const participants = payload?.participants || [];
|
|
2111
|
+
const local = participants.find(
|
|
2112
|
+
(p) => p?.participant_id === this.myId
|
|
2113
|
+
);
|
|
2114
|
+
if (local) {
|
|
2115
|
+
const media = this.state.localParticipant?.media;
|
|
2116
|
+
this.state.updateLocalParticipant({
|
|
2117
|
+
id: this.myId,
|
|
2118
|
+
name: this.participantName,
|
|
2119
|
+
media: {
|
|
2120
|
+
micEnabled: !Boolean(local.audio_muted),
|
|
2121
|
+
camEnabled: !Boolean(local.video_muted),
|
|
2122
|
+
isScreenSharing: Boolean(local.screen_sharing),
|
|
2123
|
+
screenStream: this.screenStream,
|
|
2124
|
+
screenTrack: this.screenStream?.getVideoTracks()[0]
|
|
2125
|
+
}
|
|
2126
|
+
});
|
|
2127
|
+
if (this.localStream) {
|
|
2128
|
+
this.localStream.getAudioTracks().forEach((track) => {
|
|
2129
|
+
track.enabled = !Boolean(local.audio_muted);
|
|
2130
|
+
});
|
|
2131
|
+
this.localStream.getVideoTracks().forEach((track) => {
|
|
2132
|
+
track.enabled = !Boolean(local.video_muted);
|
|
2133
|
+
});
|
|
2134
|
+
}
|
|
2135
|
+
if (local.screen_sharing) this.state.setPresenterId(this.myId);
|
|
2136
|
+
else if (this.state.presenterId === this.myId)
|
|
2137
|
+
this.state.setPresenterId(null);
|
|
2138
|
+
}
|
|
2139
|
+
const presenter = participants.find((p) => p?.screen_sharing);
|
|
2140
|
+
if (presenter) this.state.setPresenterId(presenter.participant_id);
|
|
2141
|
+
else if (!local?.screen_sharing) this.state.setPresenterId(null);
|
|
2142
|
+
for (const message of payload?.chat_history || []) {
|
|
2143
|
+
this.state.addChatMessage(message);
|
|
2144
|
+
}
|
|
2145
|
+
this.events.onRoomUpdate?.(payload);
|
|
2146
|
+
},
|
|
1960
2147
|
onJoinPending: (info) => {
|
|
1961
2148
|
console.log("[SFU] Join request pending", info);
|
|
1962
2149
|
},
|
|
@@ -1991,6 +2178,19 @@ var VideoSDKCore = class {
|
|
|
1991
2178
|
false
|
|
1992
2179
|
);
|
|
1993
2180
|
},
|
|
2181
|
+
onChatMessage: (message) => {
|
|
2182
|
+
const msg = {
|
|
2183
|
+
id: message.id,
|
|
2184
|
+
text: message.text,
|
|
2185
|
+
sender_id: message.sender_id,
|
|
2186
|
+
sender_name: message.sender_name,
|
|
2187
|
+
timestamp: Number(message.timestamp),
|
|
2188
|
+
reply_to: message.reply_to ?? null,
|
|
2189
|
+
target: message.target ?? null
|
|
2190
|
+
};
|
|
2191
|
+
this.state.addChatMessage(msg);
|
|
2192
|
+
this.events.onChatMessage?.(msg);
|
|
2193
|
+
},
|
|
1994
2194
|
onJoinRequested: (request) => {
|
|
1995
2195
|
const requestId = request?.request_id || request?.requestId;
|
|
1996
2196
|
const participantId = request?.user_id || request?.participantId;
|
|
@@ -2059,6 +2259,17 @@ var VideoSDKCore = class {
|
|
|
2059
2259
|
this.events.onUserLeft?.(pid);
|
|
2060
2260
|
},
|
|
2061
2261
|
// TRACKS
|
|
2262
|
+
onParticipantMediaState: (participantId, audioMuted, videoMuted) => {
|
|
2263
|
+
if (participantId === this.myId) return;
|
|
2264
|
+
const participant = this.state.getParticipant(participantId);
|
|
2265
|
+
if (!participant) return;
|
|
2266
|
+
this.state.updateParticipantMedia(participantId, {
|
|
2267
|
+
micEnabled: !audioMuted,
|
|
2268
|
+
camEnabled: !videoMuted
|
|
2269
|
+
});
|
|
2270
|
+
this.events.onMuteStateChanged?.(participantId, "audio", audioMuted);
|
|
2271
|
+
this.events.onMuteStateChanged?.(participantId, "video", videoMuted);
|
|
2272
|
+
},
|
|
2062
2273
|
onTrackPublished: (track) => {
|
|
2063
2274
|
console.log("[SFU] Track published", track);
|
|
2064
2275
|
},
|
|
@@ -2128,6 +2339,9 @@ var VideoSDKCore = class {
|
|
|
2128
2339
|
// SCREEN SHARE
|
|
2129
2340
|
onScreenShareStarted: (participantId, _track) => {
|
|
2130
2341
|
console.log("[SFU] Screen share started", participantId);
|
|
2342
|
+
if (participantId === this.myId && !this.screenStream) {
|
|
2343
|
+
this.screenStream = this.sfuClient?.getScreenStream() ?? null;
|
|
2344
|
+
}
|
|
2131
2345
|
this.state.setPresenterId(participantId);
|
|
2132
2346
|
if (participantId === this.myId) {
|
|
2133
2347
|
this.state.updateLocalParticipant({
|
|
@@ -2351,7 +2565,7 @@ var VideoSDKCore = class {
|
|
|
2351
2565
|
media: {
|
|
2352
2566
|
isScreenSharing: true,
|
|
2353
2567
|
screenStream: this.screenStream,
|
|
2354
|
-
screenTrack: this.screenStream
|
|
2568
|
+
screenTrack: this.screenStream?.getVideoTracks()[0]
|
|
2355
2569
|
}
|
|
2356
2570
|
});
|
|
2357
2571
|
return this.screenStream;
|
|
@@ -2408,18 +2622,20 @@ var VideoSDKCore = class {
|
|
|
2408
2622
|
console.warn("SFU Client not connected");
|
|
2409
2623
|
return;
|
|
2410
2624
|
}
|
|
2411
|
-
const
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
sender_name: senderName,
|
|
2416
|
-
text: payload.message.trim(),
|
|
2417
|
-
timestamp: Date.now(),
|
|
2625
|
+
const message = payload.message.trim();
|
|
2626
|
+
if (!message) return;
|
|
2627
|
+
this.sfuClient.sendChatMessage({
|
|
2628
|
+
message,
|
|
2418
2629
|
reply_to: payload.reply_to ?? null,
|
|
2419
2630
|
target: payload.target ?? null
|
|
2420
|
-
};
|
|
2421
|
-
|
|
2422
|
-
|
|
2631
|
+
});
|
|
2632
|
+
}
|
|
2633
|
+
sendReaction(reaction) {
|
|
2634
|
+
if (!this.sfuClient) {
|
|
2635
|
+
console.warn("SFU Client not connected");
|
|
2636
|
+
return;
|
|
2637
|
+
}
|
|
2638
|
+
this.sfuClient.sendReaction(reaction);
|
|
2423
2639
|
}
|
|
2424
2640
|
// CLEANUP
|
|
2425
2641
|
cleanupRemoteParticipant(participantId) {
|
|
@@ -2507,6 +2723,7 @@ var MeetingProvider = ({
|
|
|
2507
2723
|
const trackStateListeners = (0, import_react2.useRef)(/* @__PURE__ */ new Set());
|
|
2508
2724
|
const recordingStartedListeners = (0, import_react2.useRef)(/* @__PURE__ */ new Set());
|
|
2509
2725
|
const recordingStoppedListeners = (0, import_react2.useRef)(/* @__PURE__ */ new Set());
|
|
2726
|
+
const reactionListeners = (0, import_react2.useRef)(/* @__PURE__ */ new Set());
|
|
2510
2727
|
const activeSpeakerListeners = (0, import_react2.useRef)(
|
|
2511
2728
|
/* @__PURE__ */ new Set()
|
|
2512
2729
|
);
|
|
@@ -2536,6 +2753,9 @@ var MeetingProvider = ({
|
|
|
2536
2753
|
},
|
|
2537
2754
|
onRecordingStopped: (recording) => {
|
|
2538
2755
|
recordingStoppedListeners.current.forEach((fn) => fn(recording));
|
|
2756
|
+
},
|
|
2757
|
+
onReaction: (reaction) => {
|
|
2758
|
+
reactionListeners.current.forEach((fn) => fn(reaction));
|
|
2539
2759
|
}
|
|
2540
2760
|
}
|
|
2541
2761
|
);
|
|
@@ -2582,6 +2802,7 @@ var MeetingProvider = ({
|
|
|
2582
2802
|
startScreenShare: sdk.startScreenShare.bind(sdk),
|
|
2583
2803
|
stopScreenShare: sdk.stopScreenShare.bind(sdk),
|
|
2584
2804
|
sendMessage: sdk.sendChatMessage.bind(sdk),
|
|
2805
|
+
sendReaction: sdk.sendReaction.bind(sdk),
|
|
2585
2806
|
room: sdk.getMeeting(),
|
|
2586
2807
|
localParticipant,
|
|
2587
2808
|
participants,
|
|
@@ -2638,6 +2859,10 @@ var MeetingProvider = ({
|
|
|
2638
2859
|
recordingStoppedListeners.current.add(cb);
|
|
2639
2860
|
return () => recordingStoppedListeners.current.delete(cb);
|
|
2640
2861
|
},
|
|
2862
|
+
onReaction: (cb) => {
|
|
2863
|
+
reactionListeners.current.add(cb);
|
|
2864
|
+
return () => reactionListeners.current.delete(cb);
|
|
2865
|
+
},
|
|
2641
2866
|
onActiveSpeakersChanged: (cb) => {
|
|
2642
2867
|
activeSpeakerListeners.current.add(cb);
|
|
2643
2868
|
return () => {
|
|
@@ -2734,6 +2959,10 @@ var useMeeting = (handlers) => {
|
|
|
2734
2959
|
if (!handlers?.onRecordingStopped) return;
|
|
2735
2960
|
return ctx.onRecordingStopped(handlers.onRecordingStopped);
|
|
2736
2961
|
}, [handlers?.onRecordingStopped]);
|
|
2962
|
+
(0, import_react4.useEffect)(() => {
|
|
2963
|
+
if (!handlers?.onReaction) return;
|
|
2964
|
+
return ctx.onReaction(handlers.onReaction);
|
|
2965
|
+
}, [handlers?.onReaction]);
|
|
2737
2966
|
const { sdk: _, ...publicApi } = ctx;
|
|
2738
2967
|
return publicApi;
|
|
2739
2968
|
};
|