@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.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 = 6;
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.roomSyncTimer = null;
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: this.audioMuted,
593
- videoMuted: this.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.onError({
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") this.localTrackIds.set("audio", track.track_id);
868
- if (track.source === "camera") this.localTrackIds.set("camera", track.track_id);
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.activeRecording = {
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.activeRecording = null;
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 applyRoomState(payload) {
1011
- const authoritative = /* @__PURE__ */ new Map();
1012
- for (const participant of payload?.participants || []) {
1013
- if (participant?.participant_id) authoritative.set(participant.participant_id, participant);
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 id of [...this.participants.keys()]) {
1016
- if (!authoritative.has(id) && id !== this.currentParticipantId) {
1017
- this.participants.delete(id);
1018
- this.removeRemoteParticipant(id);
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 [id, participant] of authoritative) {
1023
- if (id === this.currentParticipantId) continue;
1024
- const previous = this.participants.get(id);
1025
- this.participants.set(id, {
1026
- ...previous,
1027
- ...participant,
1028
- audio_muted: Boolean(participant.audio_muted),
1029
- video_muted: Boolean(participant.video_muted)
1030
- });
1031
- if (!previous) this.onParticipantJoined(participant);
1032
- if (participant.presence) this.onParticipantPresence(id, String(participant.presence));
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?.tracks || []) {
1036
- if (!track?.track_id) continue;
1037
- nextTracks.set(track.track_id, track);
1038
- this.rememberTrack(track);
1039
- }
1040
- for (const id of [...this.trackMetadata.keys()]) {
1041
- if (!nextTracks.has(id)) {
1042
- this.trackMetadata.delete(id);
1043
- this.subscribedTracks.delete(id);
1044
- this.trackToParticipant.delete(id);
1045
- this.trackToSource.delete(id);
1046
- }
1047
- }
1048
- if (payload?.recording) {
1049
- const current = {
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((t) => t.participant_id !== this.currentParticipantId && !this.subscribedTracks.has(t.track_id)).map((t) => t.track_id);
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
- this.onRoomState(payload);
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
- const trackId = this.localTrackIds.get("audio");
1573
- if (trackId) {
1574
- this.send({
1575
- type: "track_state",
1576
- payload: {
1577
- track_id: trackId,
1578
- muted
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
- const trackId = this.localTrackIds.get("camera");
1588
- if (trackId) {
1589
- this.send({
1590
- type: "track_state",
1591
- payload: {
1592
- track_id: trackId,
1593
- muted
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
- if (state === "disconnected" || state === "idle") {
2040
- this.sfuClient = null;
2041
- } else {
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
- onRoomState: (roomState) => {
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
- this.state.addParticipant({
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: false,
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.state.localParticipant?.media?.micEnabled,
2364
- videoMuted: this.state.localParticipant?.media?.camEnabled
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);