@defcomm/meetingsdk 0.2.4 → 0.2.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/dist/index.d.mts +4 -16
- package/dist/index.d.ts +4 -16
- package/dist/index.js +181 -247
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +181 -247
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -349,9 +349,6 @@ var SFUClient = class {
|
|
|
349
349
|
this.localStream = null;
|
|
350
350
|
this.screenStream = null;
|
|
351
351
|
this.videoSender = null;
|
|
352
|
-
this.audioMuted = false;
|
|
353
|
-
this.videoMuted = false;
|
|
354
|
-
this.activeRecording = null;
|
|
355
352
|
this.audioSender = null;
|
|
356
353
|
this.screenSender = null;
|
|
357
354
|
this.audioTransceiver = null;
|
|
@@ -372,7 +369,7 @@ var SFUClient = class {
|
|
|
372
369
|
this.joiningWithResume = false;
|
|
373
370
|
this.reconnectTimer = null;
|
|
374
371
|
this.reconnectAttempt = 0;
|
|
375
|
-
this.maxReconnectAttempts =
|
|
372
|
+
this.maxReconnectAttempts = 8;
|
|
376
373
|
this.reconnectBaseMs = 750;
|
|
377
374
|
this.joinWaiter = null;
|
|
378
375
|
this.transportRecoveryInProgress = false;
|
|
@@ -395,8 +392,7 @@ var SFUClient = class {
|
|
|
395
392
|
this.trackToSource = /* @__PURE__ */ new Map();
|
|
396
393
|
this.localTrackIds = /* @__PURE__ */ new Map();
|
|
397
394
|
this.subscriberStatsTimer = null;
|
|
398
|
-
this.
|
|
399
|
-
this.roomSyncInFlight = false;
|
|
395
|
+
this.lastRecordingId = null;
|
|
400
396
|
this.heartbeatTimer = null;
|
|
401
397
|
this.apiBase = options.apiBase || "https://api.example.com/api";
|
|
402
398
|
this.wsBase = options.wsBase || "wss://api.example.com/ws";
|
|
@@ -409,6 +405,8 @@ var SFUClient = class {
|
|
|
409
405
|
});
|
|
410
406
|
this.onParticipantPresence = options.onParticipantPresence || (() => {
|
|
411
407
|
});
|
|
408
|
+
this.onParticipantMediaState = options.onParticipantMediaState || (() => {
|
|
409
|
+
});
|
|
412
410
|
this.onTrackPublished = options.onTrackPublished || (() => {
|
|
413
411
|
});
|
|
414
412
|
this.onTrackUnpublished = options.onTrackUnpublished || (() => {
|
|
@@ -435,14 +433,10 @@ var SFUClient = class {
|
|
|
435
433
|
});
|
|
436
434
|
this.onTrackStateChanged = options.onTrackStateChanged || (() => {
|
|
437
435
|
});
|
|
438
|
-
this.onParticipantMediaState = options.onParticipantMediaState || (() => {
|
|
439
|
-
});
|
|
440
436
|
this.onRecordingStarted = options.onRecordingStarted || (() => {
|
|
441
437
|
});
|
|
442
438
|
this.onRecordingStopped = options.onRecordingStopped || (() => {
|
|
443
439
|
});
|
|
444
|
-
this.onRoomState = options.onRoomState || (() => {
|
|
445
|
-
});
|
|
446
440
|
this.onError = options.onError || console.error;
|
|
447
441
|
this.autoSubscribe = options.autoSubscribe !== false;
|
|
448
442
|
}
|
|
@@ -464,29 +458,6 @@ var SFUClient = class {
|
|
|
464
458
|
this.heartbeatTimer = null;
|
|
465
459
|
}
|
|
466
460
|
}
|
|
467
|
-
startRoomStateSync() {
|
|
468
|
-
this.stopRoomStateSync();
|
|
469
|
-
this.roomSyncTimer = setInterval(() => {
|
|
470
|
-
if (this.state !== "connected") return;
|
|
471
|
-
void this.syncRoomState();
|
|
472
|
-
}, 5e3);
|
|
473
|
-
}
|
|
474
|
-
stopRoomStateSync() {
|
|
475
|
-
if (this.roomSyncTimer) {
|
|
476
|
-
clearInterval(this.roomSyncTimer);
|
|
477
|
-
this.roomSyncTimer = null;
|
|
478
|
-
}
|
|
479
|
-
this.roomSyncInFlight = false;
|
|
480
|
-
}
|
|
481
|
-
async syncRoomState() {
|
|
482
|
-
if (this.roomSyncInFlight || !this.isSocketOpen()) return;
|
|
483
|
-
this.roomSyncInFlight = true;
|
|
484
|
-
try {
|
|
485
|
-
this.send({ type: "sync_room_state" });
|
|
486
|
-
} finally {
|
|
487
|
-
this.roomSyncInFlight = false;
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
461
|
createId() {
|
|
491
462
|
return typeof crypto !== "undefined" && crypto.randomUUID ? crypto.randomUUID() : `id_${Math.random().toString(36).slice(2)}_${Date.now()}`;
|
|
492
463
|
}
|
|
@@ -584,13 +555,11 @@ var SFUClient = class {
|
|
|
584
555
|
this.resumeToken = null;
|
|
585
556
|
}
|
|
586
557
|
this.room = nextRoom;
|
|
587
|
-
this.audioMuted = Boolean(options.audioMuted);
|
|
588
|
-
this.videoMuted = Boolean(options.videoMuted);
|
|
589
558
|
this.joinOptions = {
|
|
590
559
|
displayName: options.displayName,
|
|
591
560
|
avatarUrl: options.avatarUrl,
|
|
592
|
-
audioMuted:
|
|
593
|
-
videoMuted:
|
|
561
|
+
audioMuted: options.audioMuted,
|
|
562
|
+
videoMuted: options.videoMuted
|
|
594
563
|
};
|
|
595
564
|
if (options.participantId) this.participantId = options.participantId;
|
|
596
565
|
if (!this.resumeToken) {
|
|
@@ -660,8 +629,8 @@ var SFUClient = class {
|
|
|
660
629
|
resume_token: this.resumeToken,
|
|
661
630
|
display_name: options.displayName,
|
|
662
631
|
avatar_url: options.avatarUrl,
|
|
663
|
-
audio_muted: this.audioMuted,
|
|
664
|
-
video_muted: this.videoMuted
|
|
632
|
+
audio_muted: options.audioMuted ?? this.joinOptions.audioMuted ?? false,
|
|
633
|
+
video_muted: options.videoMuted ?? this.joinOptions.videoMuted ?? false
|
|
665
634
|
};
|
|
666
635
|
if (this.pendingJoinRequestId) {
|
|
667
636
|
this.send({
|
|
@@ -702,20 +671,8 @@ var SFUClient = class {
|
|
|
702
671
|
scheduleReconnect() {
|
|
703
672
|
if (this.reconnectTimer || this.intentionalClose) return;
|
|
704
673
|
if (this.reconnectAttempt >= this.maxReconnectAttempts) {
|
|
705
|
-
const error = new Error("SFU reconnect attempts exhausted");
|
|
706
|
-
console.error("[SFU] Reconnect attempts exhausted; leaving meeting", error);
|
|
707
|
-
this.intentionalClose = true;
|
|
708
|
-
this.stopHeartbeat();
|
|
709
|
-
this.stopRoomStateSync();
|
|
710
|
-
this.cleanupAll();
|
|
711
674
|
this.setState("disconnected");
|
|
712
|
-
this.
|
|
713
|
-
code: "RECONNECT_TIMEOUT",
|
|
714
|
-
message: error.message,
|
|
715
|
-
recoverable: false
|
|
716
|
-
});
|
|
717
|
-
this.onDisconnected();
|
|
718
|
-
this.failJoin(error);
|
|
675
|
+
this.failJoin(new Error("SFU reconnect attempts exhausted"));
|
|
719
676
|
return;
|
|
720
677
|
}
|
|
721
678
|
this.reconnectAttempt += 1;
|
|
@@ -788,8 +745,8 @@ var SFUClient = class {
|
|
|
788
745
|
resume_token: this.resumeToken,
|
|
789
746
|
display_name: this.joinOptions.displayName,
|
|
790
747
|
avatar_url: this.joinOptions.avatarUrl,
|
|
791
|
-
audio_muted: this.audioMuted,
|
|
792
|
-
video_muted: this.videoMuted
|
|
748
|
+
audio_muted: this.joinOptions.audioMuted ?? false,
|
|
749
|
+
video_muted: this.joinOptions.videoMuted ?? false
|
|
793
750
|
}
|
|
794
751
|
});
|
|
795
752
|
}
|
|
@@ -864,8 +821,22 @@ var SFUClient = class {
|
|
|
864
821
|
if (!track?.track_id) break;
|
|
865
822
|
this.rememberTrack(track);
|
|
866
823
|
if (track.participant_id === this.currentParticipantId) {
|
|
867
|
-
if (track.source === "audio")
|
|
868
|
-
|
|
824
|
+
if (track.source === "audio") {
|
|
825
|
+
this.localTrackIds.set("audio", track.track_id);
|
|
826
|
+
const muted = !(this.localStream?.getAudioTracks()[0]?.enabled ?? true);
|
|
827
|
+
this.send({
|
|
828
|
+
type: "track_state",
|
|
829
|
+
payload: { track_id: track.track_id, muted }
|
|
830
|
+
});
|
|
831
|
+
}
|
|
832
|
+
if (track.source === "camera") {
|
|
833
|
+
this.localTrackIds.set("camera", track.track_id);
|
|
834
|
+
const muted = !(this.localStream?.getVideoTracks()[0]?.enabled ?? true);
|
|
835
|
+
this.send({
|
|
836
|
+
type: "track_state",
|
|
837
|
+
payload: { track_id: track.track_id, muted }
|
|
838
|
+
});
|
|
839
|
+
}
|
|
869
840
|
if (track.source === "screen")
|
|
870
841
|
this.localTrackIds.set("screen", track.track_id);
|
|
871
842
|
break;
|
|
@@ -894,27 +865,6 @@ var SFUClient = class {
|
|
|
894
865
|
this.onTrackUnpublished(track);
|
|
895
866
|
break;
|
|
896
867
|
}
|
|
897
|
-
case "participant_media_state": {
|
|
898
|
-
const participantId = payload.participant_id;
|
|
899
|
-
if (!participantId) break;
|
|
900
|
-
const participant = this.participants.get(participantId);
|
|
901
|
-
if (participant) {
|
|
902
|
-
participant.audio_muted = Boolean(payload.audio_muted);
|
|
903
|
-
participant.video_muted = Boolean(payload.video_muted);
|
|
904
|
-
this.participants.set(participantId, participant);
|
|
905
|
-
}
|
|
906
|
-
for (const track of this.trackMetadata.values()) {
|
|
907
|
-
if (track.participant_id !== participantId) continue;
|
|
908
|
-
if (track.source === "audio") track.muted = Boolean(payload.audio_muted);
|
|
909
|
-
if (track.source === "camera") track.muted = Boolean(payload.video_muted);
|
|
910
|
-
}
|
|
911
|
-
this.onParticipantMediaState(
|
|
912
|
-
participantId,
|
|
913
|
-
Boolean(payload.audio_muted),
|
|
914
|
-
Boolean(payload.video_muted)
|
|
915
|
-
);
|
|
916
|
-
break;
|
|
917
|
-
}
|
|
918
868
|
case "track_state_changed": {
|
|
919
869
|
const trackId = payload.track_id || payload.track?.track_id;
|
|
920
870
|
if (!trackId) break;
|
|
@@ -936,20 +886,16 @@ var SFUClient = class {
|
|
|
936
886
|
case "subscription_updated": {
|
|
937
887
|
break;
|
|
938
888
|
}
|
|
939
|
-
case "room_state": {
|
|
940
|
-
await this.applyRoomState(payload);
|
|
941
|
-
break;
|
|
942
|
-
}
|
|
943
889
|
case "recording_started": {
|
|
944
|
-
this.
|
|
890
|
+
this.lastRecordingId = payload.recording_id || this.lastRecordingId;
|
|
891
|
+
this.onRecordingStarted({
|
|
945
892
|
recording_id: payload.recording_id,
|
|
946
893
|
started_at: payload.started_at
|
|
947
|
-
};
|
|
948
|
-
this.onRecordingStarted(this.activeRecording);
|
|
894
|
+
});
|
|
949
895
|
break;
|
|
950
896
|
}
|
|
951
897
|
case "recording_stopped": {
|
|
952
|
-
this.
|
|
898
|
+
this.lastRecordingId = null;
|
|
953
899
|
this.onRecordingStopped({
|
|
954
900
|
recording_id: payload.recording_id,
|
|
955
901
|
stopped_at: payload.stopped_at
|
|
@@ -985,6 +931,29 @@ var SFUClient = class {
|
|
|
985
931
|
this.onScreenShareStopped(participantId, trackId);
|
|
986
932
|
break;
|
|
987
933
|
}
|
|
934
|
+
case "room_state": {
|
|
935
|
+
await this.reconcileRoomState(payload);
|
|
936
|
+
break;
|
|
937
|
+
}
|
|
938
|
+
case "participant_media_state": {
|
|
939
|
+
const participantId = payload.participant_id;
|
|
940
|
+
if (participantId) {
|
|
941
|
+
const current = this.participants.get(participantId);
|
|
942
|
+
if (current) {
|
|
943
|
+
this.participants.set(participantId, {
|
|
944
|
+
...current,
|
|
945
|
+
audio_muted: Boolean(payload.audio_muted),
|
|
946
|
+
video_muted: Boolean(payload.video_muted)
|
|
947
|
+
});
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
this.onParticipantMediaState?.(
|
|
951
|
+
participantId,
|
|
952
|
+
Boolean(payload.audio_muted),
|
|
953
|
+
Boolean(payload.video_muted)
|
|
954
|
+
);
|
|
955
|
+
break;
|
|
956
|
+
}
|
|
988
957
|
case "error": {
|
|
989
958
|
const message2 = payload.message || "SFU signaling error";
|
|
990
959
|
if (this.state === "reconnecting" && message2.includes("participant session is stale")) {
|
|
@@ -1007,66 +976,89 @@ var SFUClient = class {
|
|
|
1007
976
|
console.debug("[SFU] Ignoring unknown server message", message);
|
|
1008
977
|
}
|
|
1009
978
|
}
|
|
1010
|
-
async
|
|
1011
|
-
const
|
|
1012
|
-
for (const participant of payload
|
|
1013
|
-
if (participant?.participant_id)
|
|
979
|
+
async reconcileRoomState(payload) {
|
|
980
|
+
const nextParticipants = /* @__PURE__ */ new Map();
|
|
981
|
+
for (const participant of payload.participants || []) {
|
|
982
|
+
if (participant?.participant_id) {
|
|
983
|
+
nextParticipants.set(participant.participant_id, participant);
|
|
984
|
+
}
|
|
1014
985
|
}
|
|
1015
|
-
for (const
|
|
1016
|
-
if (
|
|
1017
|
-
this.participants.delete(
|
|
1018
|
-
this.
|
|
1019
|
-
this.onParticipantLeft(id);
|
|
986
|
+
for (const participantId of this.participants.keys()) {
|
|
987
|
+
if (participantId !== this.currentParticipantId && !nextParticipants.has(participantId)) {
|
|
988
|
+
this.participants.delete(participantId);
|
|
989
|
+
this.onParticipantLeft(participantId);
|
|
1020
990
|
}
|
|
1021
991
|
}
|
|
1022
|
-
for (const
|
|
1023
|
-
if (
|
|
1024
|
-
const previous = this.participants.get(
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
}
|
|
1031
|
-
if (
|
|
1032
|
-
|
|
992
|
+
for (const participant of nextParticipants.values()) {
|
|
993
|
+
if (participant.participant_id === this.currentParticipantId) continue;
|
|
994
|
+
const previous = this.participants.get(participant.participant_id);
|
|
995
|
+
const wasScreenSharing = Boolean(previous?.screen_sharing);
|
|
996
|
+
const isScreenSharing = Boolean(participant.screen_sharing);
|
|
997
|
+
this.participants.set(participant.participant_id, participant);
|
|
998
|
+
if (!previous) {
|
|
999
|
+
this.onParticipantJoined(participant);
|
|
1000
|
+
}
|
|
1001
|
+
if (participant.presence) {
|
|
1002
|
+
this.onParticipantPresence(
|
|
1003
|
+
participant.participant_id,
|
|
1004
|
+
String(participant.presence).toLowerCase()
|
|
1005
|
+
);
|
|
1006
|
+
}
|
|
1007
|
+
this.onParticipantMediaState(
|
|
1008
|
+
participant.participant_id,
|
|
1009
|
+
Boolean(participant.audio_muted),
|
|
1010
|
+
Boolean(participant.video_muted)
|
|
1011
|
+
);
|
|
1012
|
+
if (!wasScreenSharing && isScreenSharing) {
|
|
1013
|
+
this.onScreenShareStarted(participant.participant_id, void 0);
|
|
1014
|
+
} else if (wasScreenSharing && !isScreenSharing) {
|
|
1015
|
+
this.onScreenShareStopped(
|
|
1016
|
+
participant.participant_id,
|
|
1017
|
+
participant.screen_track_id || void 0
|
|
1018
|
+
);
|
|
1019
|
+
}
|
|
1033
1020
|
}
|
|
1034
1021
|
const nextTracks = /* @__PURE__ */ new Map();
|
|
1035
|
-
for (const track of payload
|
|
1036
|
-
if (
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
this.
|
|
1044
|
-
this.trackToParticipant.delete(
|
|
1045
|
-
this.trackToSource.delete(
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
recording_id: payload.recording.recording_id,
|
|
1051
|
-
started_at: payload.recording.started_at
|
|
1052
|
-
};
|
|
1053
|
-
if (!this.activeRecording || this.activeRecording.recording_id !== current.recording_id) {
|
|
1054
|
-
this.activeRecording = current;
|
|
1055
|
-
this.onRecordingStarted(current);
|
|
1022
|
+
for (const track of payload.tracks || []) {
|
|
1023
|
+
if (track?.track_id) {
|
|
1024
|
+
nextTracks.set(track.track_id, track);
|
|
1025
|
+
this.rememberTrack(track);
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
for (const [trackId, oldTrack] of [...this.trackMetadata.entries()]) {
|
|
1029
|
+
if (!nextTracks.has(trackId)) {
|
|
1030
|
+
this.trackMetadata.delete(trackId);
|
|
1031
|
+
this.trackToParticipant.delete(trackId);
|
|
1032
|
+
this.trackToSource.delete(trackId);
|
|
1033
|
+
this.subscribedTracks.delete(trackId);
|
|
1034
|
+
if (oldTrack.participant_id !== this.currentParticipantId) {
|
|
1035
|
+
this.onTrackUnpublished(oldTrack);
|
|
1036
|
+
}
|
|
1056
1037
|
}
|
|
1057
|
-
} else if (this.activeRecording) {
|
|
1058
|
-
const previous = this.activeRecording;
|
|
1059
|
-
this.activeRecording = null;
|
|
1060
|
-
this.onRecordingStopped({
|
|
1061
|
-
recording_id: previous.recording_id,
|
|
1062
|
-
stopped_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
1063
|
-
});
|
|
1064
1038
|
}
|
|
1065
1039
|
if (this.autoSubscribe) {
|
|
1066
|
-
const missing = [...nextTracks.values()].filter(
|
|
1040
|
+
const missing = [...nextTracks.values()].filter(
|
|
1041
|
+
(track) => track.participant_id !== this.currentParticipantId && !this.subscribedTracks.has(track.track_id)
|
|
1042
|
+
).map((track) => track.track_id);
|
|
1067
1043
|
if (missing.length) await this.subscribeMultiple(missing);
|
|
1068
1044
|
}
|
|
1069
|
-
|
|
1045
|
+
const nextRecordingId = payload.recording?.recording_id || null;
|
|
1046
|
+
if (payload.recording) {
|
|
1047
|
+
if (this.lastRecordingId !== nextRecordingId) {
|
|
1048
|
+
this.lastRecordingId = nextRecordingId;
|
|
1049
|
+
this.onRecordingStarted({
|
|
1050
|
+
recording_id: payload.recording.recording_id,
|
|
1051
|
+
started_at: payload.recording.started_at
|
|
1052
|
+
});
|
|
1053
|
+
}
|
|
1054
|
+
} else if (this.lastRecordingId) {
|
|
1055
|
+
const recordingId = this.lastRecordingId;
|
|
1056
|
+
this.lastRecordingId = null;
|
|
1057
|
+
this.onRecordingStopped({
|
|
1058
|
+
recording_id: recordingId,
|
|
1059
|
+
stopped_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
1060
|
+
});
|
|
1061
|
+
}
|
|
1070
1062
|
}
|
|
1071
1063
|
rememberTrack(track) {
|
|
1072
1064
|
this.trackMetadata.set(track.track_id, track);
|
|
@@ -1097,23 +1089,8 @@ var SFUClient = class {
|
|
|
1097
1089
|
for (const track of payload.tracks || []) {
|
|
1098
1090
|
if (track?.track_id) this.rememberTrack(track);
|
|
1099
1091
|
}
|
|
1100
|
-
if (payload.recording) {
|
|
1101
|
-
this.activeRecording = {
|
|
1102
|
-
recording_id: payload.recording.recording_id,
|
|
1103
|
-
started_at: payload.recording.started_at
|
|
1104
|
-
};
|
|
1105
|
-
this.onRecordingStarted(this.activeRecording);
|
|
1106
|
-
} else if (this.activeRecording) {
|
|
1107
|
-
const previous = this.activeRecording;
|
|
1108
|
-
this.activeRecording = null;
|
|
1109
|
-
this.onRecordingStopped({
|
|
1110
|
-
recording_id: previous.recording_id,
|
|
1111
|
-
stopped_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
1112
|
-
});
|
|
1113
|
-
}
|
|
1114
1092
|
await this.initializePeerConnections();
|
|
1115
1093
|
this.setState("connected");
|
|
1116
|
-
this.startRoomStateSync();
|
|
1117
1094
|
this.onConnected(payload, resumed);
|
|
1118
1095
|
for (const participant of this.participants.values()) {
|
|
1119
1096
|
if (participant.participant_id !== this.currentParticipantId) {
|
|
@@ -1569,31 +1546,25 @@ var SFUClient = class {
|
|
|
1569
1546
|
this.localStream?.getAudioTracks().forEach((track) => {
|
|
1570
1547
|
track.enabled = !muted;
|
|
1571
1548
|
});
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
}
|
|
1580
|
-
});
|
|
1581
|
-
}
|
|
1549
|
+
this.send({
|
|
1550
|
+
type: "set_media_state",
|
|
1551
|
+
payload: {
|
|
1552
|
+
audio_muted: muted,
|
|
1553
|
+
video_muted: !(this.localStream?.getVideoTracks()[0]?.enabled ?? true)
|
|
1554
|
+
}
|
|
1555
|
+
});
|
|
1582
1556
|
}
|
|
1583
1557
|
muteVideo(muted) {
|
|
1584
1558
|
this.localStream?.getVideoTracks().forEach((track) => {
|
|
1585
1559
|
track.enabled = !muted;
|
|
1586
1560
|
});
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
}
|
|
1595
|
-
});
|
|
1596
|
-
}
|
|
1561
|
+
this.send({
|
|
1562
|
+
type: "set_media_state",
|
|
1563
|
+
payload: {
|
|
1564
|
+
audio_muted: !(this.localStream?.getAudioTracks()[0]?.enabled ?? true),
|
|
1565
|
+
video_muted: muted
|
|
1566
|
+
}
|
|
1567
|
+
});
|
|
1597
1568
|
}
|
|
1598
1569
|
async startRecording() {
|
|
1599
1570
|
if (!this.send({ type: "start_recording" })) {
|
|
@@ -1668,7 +1639,6 @@ var SFUClient = class {
|
|
|
1668
1639
|
}
|
|
1669
1640
|
async leave() {
|
|
1670
1641
|
this.stopHeartbeat();
|
|
1671
|
-
this.stopRoomStateSync();
|
|
1672
1642
|
this.intentionalClose = true;
|
|
1673
1643
|
this.setState("leaving");
|
|
1674
1644
|
if (this.reconnectTimer) {
|
|
@@ -2036,13 +2006,9 @@ var VideoSDKCore = class {
|
|
|
2036
2006
|
);
|
|
2037
2007
|
return;
|
|
2038
2008
|
}
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
throw new Error(
|
|
2043
|
-
`SFU client already exists in state "${state}". Disconnect explicitly before creating another connection.`
|
|
2044
|
-
);
|
|
2045
|
-
}
|
|
2009
|
+
throw new Error(
|
|
2010
|
+
`SFU client already exists in state "${state}". Disconnect explicitly before creating another connection.`
|
|
2011
|
+
);
|
|
2046
2012
|
}
|
|
2047
2013
|
const client = new SFUClient({
|
|
2048
2014
|
apiBase: this.apiBase,
|
|
@@ -2057,50 +2023,12 @@ var VideoSDKCore = class {
|
|
|
2057
2023
|
console.log(`[SFU] ${resumed ? "Resumed" : "Joined"} room`, payload);
|
|
2058
2024
|
this.state.updateLocalParticipant({
|
|
2059
2025
|
id: this.myId,
|
|
2060
|
-
name: this.participantName
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
for (const participant of roomState?.participants || []) {
|
|
2065
|
-
const pid = participant?.participant_id;
|
|
2066
|
-
if (!pid || pid === this.myId) continue;
|
|
2067
|
-
const current = this.state.getParticipant(pid);
|
|
2068
|
-
if (!current) continue;
|
|
2069
|
-
this.state.updateParticipantMedia(pid, {
|
|
2070
|
-
stream: current.media?.stream ?? null,
|
|
2071
|
-
micEnabled: !Boolean(participant.audio_muted),
|
|
2072
|
-
camEnabled: !Boolean(participant.video_muted),
|
|
2073
|
-
isScreenSharing: Boolean(participant.screen_sharing)
|
|
2074
|
-
});
|
|
2075
|
-
}
|
|
2076
|
-
const presenters = /* @__PURE__ */ new Set();
|
|
2077
|
-
for (const participant of roomState?.participants || []) {
|
|
2078
|
-
const pid = participant?.participant_id;
|
|
2079
|
-
if (!pid || pid === this.myId) continue;
|
|
2080
|
-
const current = this.state.getParticipant(pid);
|
|
2081
|
-
if (!current) continue;
|
|
2082
|
-
if (participant.screen_sharing) {
|
|
2083
|
-
presenters.add(pid);
|
|
2084
|
-
this.state.updateParticipantMedia(pid, {
|
|
2085
|
-
isScreenSharing: true,
|
|
2086
|
-
screenStream: current.media?.screenStream ?? null
|
|
2087
|
-
});
|
|
2088
|
-
} else if (current.media?.isScreenSharing) {
|
|
2089
|
-
const screen = this.remoteScreenStreams.get(pid);
|
|
2090
|
-
screen?.getTracks().forEach((track) => track.stop());
|
|
2091
|
-
this.remoteScreenStreams.delete(pid);
|
|
2092
|
-
this.state.updateParticipantMedia(pid, {
|
|
2093
|
-
isScreenSharing: false,
|
|
2094
|
-
screenStream: null,
|
|
2095
|
-
screenTrack: void 0
|
|
2096
|
-
});
|
|
2026
|
+
name: this.participantName,
|
|
2027
|
+
media: {
|
|
2028
|
+
micEnabled: this.localStream?.getAudioTracks()[0]?.enabled ?? true,
|
|
2029
|
+
camEnabled: this.localStream?.getVideoTracks()[0]?.enabled ?? true
|
|
2097
2030
|
}
|
|
2098
|
-
}
|
|
2099
|
-
const presenter = [...presenters][0] ?? null;
|
|
2100
|
-
if (this.state.presenterId !== presenter) {
|
|
2101
|
-
this.state.setPresenterId(presenter);
|
|
2102
|
-
}
|
|
2103
|
-
this.events.onRoomUpdate?.(roomState);
|
|
2031
|
+
});
|
|
2104
2032
|
},
|
|
2105
2033
|
onDisconnected: () => {
|
|
2106
2034
|
console.log("[SFU] Signaling WebSocket disconnected; reconnecting");
|
|
@@ -2168,22 +2096,44 @@ var VideoSDKCore = class {
|
|
|
2168
2096
|
return;
|
|
2169
2097
|
}
|
|
2170
2098
|
const pname = participant.user_metadata?.name || participant.display_name || "Participant";
|
|
2171
|
-
|
|
2099
|
+
const participantMedia = participant.media || {};
|
|
2100
|
+
const participantState = {
|
|
2172
2101
|
id: pid,
|
|
2173
2102
|
name: pname,
|
|
2174
|
-
connectionState: "connected",
|
|
2103
|
+
connectionState: participant.presence === "reconnecting" ? "reconnecting" : "connected",
|
|
2175
2104
|
media: {
|
|
2176
2105
|
micEnabled: !Boolean(participant.audio_muted),
|
|
2177
2106
|
camEnabled: !Boolean(participant.video_muted),
|
|
2178
|
-
isScreenSharing:
|
|
2107
|
+
isScreenSharing: Boolean(participant.screen_sharing),
|
|
2108
|
+
screenStream: participantMedia.screenStream ?? null,
|
|
2179
2109
|
stream: null
|
|
2180
2110
|
}
|
|
2181
|
-
}
|
|
2111
|
+
};
|
|
2112
|
+
if (!this.state.addParticipant(participantState)) {
|
|
2113
|
+
this.state.updateParticipantMedia(pid, participantState.media);
|
|
2114
|
+
}
|
|
2182
2115
|
this.events.onUserJoined?.({
|
|
2183
2116
|
id: pid,
|
|
2184
2117
|
name: pname
|
|
2185
2118
|
});
|
|
2186
2119
|
},
|
|
2120
|
+
onParticipantMediaState: (participantId, audioMuted, videoMuted) => {
|
|
2121
|
+
if (participantId === this.myId) {
|
|
2122
|
+
this.state.updateLocalParticipant({
|
|
2123
|
+
media: {
|
|
2124
|
+
micEnabled: !audioMuted,
|
|
2125
|
+
camEnabled: !videoMuted
|
|
2126
|
+
}
|
|
2127
|
+
});
|
|
2128
|
+
return;
|
|
2129
|
+
}
|
|
2130
|
+
this.state.updateParticipantMedia(participantId, {
|
|
2131
|
+
micEnabled: !audioMuted,
|
|
2132
|
+
camEnabled: !videoMuted
|
|
2133
|
+
});
|
|
2134
|
+
this.events.onMuteStateChanged?.(participantId, "audio", audioMuted);
|
|
2135
|
+
this.events.onMuteStateChanged?.(participantId, "video", videoMuted);
|
|
2136
|
+
},
|
|
2187
2137
|
onParticipantPresence: (participantId, presence) => {
|
|
2188
2138
|
if (participantId === this.myId) {
|
|
2189
2139
|
return;
|
|
@@ -2247,18 +2197,6 @@ var VideoSDKCore = class {
|
|
|
2247
2197
|
camEnabled: track.kind === "video" ? false : current.media?.camEnabled ?? true
|
|
2248
2198
|
});
|
|
2249
2199
|
},
|
|
2250
|
-
onParticipantMediaState: (participantId, audioMuted, videoMuted) => {
|
|
2251
|
-
if (participantId === this.myId) return;
|
|
2252
|
-
const current = this.state.getParticipant(participantId);
|
|
2253
|
-
if (!current) return;
|
|
2254
|
-
this.state.updateParticipantMedia(participantId, {
|
|
2255
|
-
stream: current.media?.stream ?? null,
|
|
2256
|
-
micEnabled: !audioMuted,
|
|
2257
|
-
camEnabled: !videoMuted
|
|
2258
|
-
});
|
|
2259
|
-
this.events.onMuteStateChanged?.(participantId, "audio", audioMuted);
|
|
2260
|
-
this.events.onMuteStateChanged?.(participantId, "video", videoMuted);
|
|
2261
|
-
},
|
|
2262
2200
|
onTrackStateChanged: (track) => {
|
|
2263
2201
|
const pid = track.participant_id;
|
|
2264
2202
|
if (!pid || pid === this.myId) {
|
|
@@ -2360,8 +2298,8 @@ var VideoSDKCore = class {
|
|
|
2360
2298
|
await client.getToken(roomId, {
|
|
2361
2299
|
displayName: name,
|
|
2362
2300
|
participantId: this.myId,
|
|
2363
|
-
audioMuted: this.
|
|
2364
|
-
videoMuted: this.
|
|
2301
|
+
audioMuted: !this.localStream?.getAudioTracks()[0]?.enabled,
|
|
2302
|
+
videoMuted: !this.localStream?.getVideoTracks()[0]?.enabled
|
|
2365
2303
|
});
|
|
2366
2304
|
}
|
|
2367
2305
|
// SFU STATE
|
|
@@ -2525,6 +2463,7 @@ var VideoSDKCore = class {
|
|
|
2525
2463
|
screenTrack: this.screenStream.getVideoTracks()[0]
|
|
2526
2464
|
}
|
|
2527
2465
|
});
|
|
2466
|
+
this.state.setPresenterId(this.myId);
|
|
2528
2467
|
return this.screenStream;
|
|
2529
2468
|
} catch (err) {
|
|
2530
2469
|
this.emitError(
|
|
@@ -2546,6 +2485,9 @@ var VideoSDKCore = class {
|
|
|
2546
2485
|
this.screenStream.getTracks().forEach((track) => track.stop());
|
|
2547
2486
|
this.screenStream = null;
|
|
2548
2487
|
this.isScreenSharing = false;
|
|
2488
|
+
if (this.state.presenterId === this.myId) {
|
|
2489
|
+
this.state.setPresenterId(null);
|
|
2490
|
+
}
|
|
2549
2491
|
this.state.updateLocalParticipant({
|
|
2550
2492
|
media: {
|
|
2551
2493
|
isScreenSharing: false,
|
|
@@ -2675,7 +2617,6 @@ var MeetingProvider = ({
|
|
|
2675
2617
|
/* @__PURE__ */ new Set()
|
|
2676
2618
|
);
|
|
2677
2619
|
const meetingLeftListeners = useRef(/* @__PURE__ */ new Set());
|
|
2678
|
-
const roomUpdateListeners = useRef(/* @__PURE__ */ new Set());
|
|
2679
2620
|
const trackStateListeners = useRef(/* @__PURE__ */ new Set());
|
|
2680
2621
|
const recordingStartedListeners = useRef(/* @__PURE__ */ new Set());
|
|
2681
2622
|
const recordingStoppedListeners = useRef(/* @__PURE__ */ new Set());
|
|
@@ -2700,9 +2641,6 @@ var MeetingProvider = ({
|
|
|
2700
2641
|
onMeetingLeft: () => {
|
|
2701
2642
|
meetingLeftListeners.current.forEach((fn) => fn());
|
|
2702
2643
|
},
|
|
2703
|
-
onRoomUpdate: (data) => {
|
|
2704
|
-
roomUpdateListeners.current.forEach((fn) => fn(data));
|
|
2705
|
-
},
|
|
2706
2644
|
onTrackStateChanged: (track) => {
|
|
2707
2645
|
trackStateListeners.current.forEach((fn) => fn(track));
|
|
2708
2646
|
},
|
|
@@ -2801,10 +2739,6 @@ var MeetingProvider = ({
|
|
|
2801
2739
|
meetingLeftListeners.current.delete(cb);
|
|
2802
2740
|
};
|
|
2803
2741
|
},
|
|
2804
|
-
onRoomUpdate: (cb) => {
|
|
2805
|
-
roomUpdateListeners.current.add(cb);
|
|
2806
|
-
return () => roomUpdateListeners.current.delete(cb);
|
|
2807
|
-
},
|
|
2808
2742
|
onTrackStateChanged: (cb) => {
|
|
2809
2743
|
trackStateListeners.current.add(cb);
|
|
2810
2744
|
return () => trackStateListeners.current.delete(cb);
|