@defcomm/meetingsdk 0.6.0 → 0.6.2
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/README.md +742 -899
- package/dist/index.d.mts +26 -35
- package/dist/index.d.ts +26 -35
- package/dist/index.js +169 -119
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +169 -118
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -24,7 +24,6 @@ __export(index_exports, {
|
|
|
24
24
|
MeetingProvider: () => MeetingProvider,
|
|
25
25
|
MeetingState: () => MeetingState,
|
|
26
26
|
VideoSDKCore: () => VideoSDKCore,
|
|
27
|
-
useLiveTranscript: () => useLiveTranscript,
|
|
28
27
|
useLocalParticipant: () => useLocalParticipant,
|
|
29
28
|
useMeeting: () => useMeeting,
|
|
30
29
|
useMeetingContext: () => useMeetingContext,
|
|
@@ -229,7 +228,6 @@ var MeetingState = class {
|
|
|
229
228
|
this.presenterId = null;
|
|
230
229
|
this.activeSpeakerIds = /* @__PURE__ */ new Set();
|
|
231
230
|
this.recording = null;
|
|
232
|
-
this.liveTranscripts = [];
|
|
233
231
|
this.networkQuality = null;
|
|
234
232
|
this.listeners = /* @__PURE__ */ new Map();
|
|
235
233
|
}
|
|
@@ -268,17 +266,6 @@ var MeetingState = class {
|
|
|
268
266
|
this.recording = null;
|
|
269
267
|
this.notify("recording");
|
|
270
268
|
}
|
|
271
|
-
addLiveTranscript(transcript) {
|
|
272
|
-
this.liveTranscripts = [...this.liveTranscripts.slice(-499), transcript];
|
|
273
|
-
this.notify("transcript");
|
|
274
|
-
}
|
|
275
|
-
getLiveTranscripts() {
|
|
276
|
-
return this.liveTranscripts;
|
|
277
|
-
}
|
|
278
|
-
clearLiveTranscripts() {
|
|
279
|
-
this.liveTranscripts = [];
|
|
280
|
-
this.notify("transcript");
|
|
281
|
-
}
|
|
282
269
|
setNetworkQuality(quality) {
|
|
283
270
|
this.networkQuality = quality;
|
|
284
271
|
this.notify("networkQuality");
|
|
@@ -403,13 +390,11 @@ var MeetingState = class {
|
|
|
403
390
|
this.chatMessages.clear();
|
|
404
391
|
this.presenterId = null;
|
|
405
392
|
this.activeSpeakerIds = /* @__PURE__ */ new Set();
|
|
406
|
-
this.liveTranscripts = [];
|
|
407
393
|
this.networkQuality = null;
|
|
408
394
|
this.notify("participants");
|
|
409
395
|
this.notify("chat");
|
|
410
396
|
this.notify("presenter");
|
|
411
397
|
this.notify("activeSpeakers");
|
|
412
|
-
this.notify("transcript");
|
|
413
398
|
this.notify("networkQuality");
|
|
414
399
|
}
|
|
415
400
|
};
|
|
@@ -472,7 +457,6 @@ var SFUClient = class {
|
|
|
472
457
|
this.trackToSource = /* @__PURE__ */ new Map();
|
|
473
458
|
this.localTrackIds = /* @__PURE__ */ new Map();
|
|
474
459
|
this.subscriberStatsTimer = null;
|
|
475
|
-
this.liveTranscriptionSeen = false;
|
|
476
460
|
this.networkProfile = null;
|
|
477
461
|
this.heartbeatTimer = null;
|
|
478
462
|
this.apiBase = options.apiBase || "https://api.example.com/api";
|
|
@@ -530,8 +514,6 @@ var SFUClient = class {
|
|
|
530
514
|
});
|
|
531
515
|
this.onRoomUpdate = options.onRoomUpdate || (() => {
|
|
532
516
|
});
|
|
533
|
-
this.onLiveTranscript = options.onLiveTranscript || (() => {
|
|
534
|
-
});
|
|
535
517
|
this.onNetworkQuality = options.onNetworkQuality || (() => {
|
|
536
518
|
});
|
|
537
519
|
this.onParticipantMediaState = options.onParticipantMediaState || (() => {
|
|
@@ -1128,24 +1110,6 @@ var SFUClient = class {
|
|
|
1128
1110
|
if (reaction?.id && reaction?.emoji) this.onReaction(reaction);
|
|
1129
1111
|
break;
|
|
1130
1112
|
}
|
|
1131
|
-
case "live_transcript": {
|
|
1132
|
-
const transcript = {
|
|
1133
|
-
transcript_id: String(payload.transcript_id),
|
|
1134
|
-
participant_id: String(payload.participant_id),
|
|
1135
|
-
speaker_name: payload.speaker_name ?? null,
|
|
1136
|
-
sequence: Number(payload.sequence ?? 0),
|
|
1137
|
-
text: String(payload.text ?? ""),
|
|
1138
|
-
offset_ms: payload.offset_ms == null ? null : Number(payload.offset_ms),
|
|
1139
|
-
start_ms: payload.start_ms == null ? null : Number(payload.start_ms),
|
|
1140
|
-
end_ms: payload.end_ms == null ? null : Number(payload.end_ms),
|
|
1141
|
-
timestamp: String(payload.timestamp ?? (/* @__PURE__ */ new Date()).toISOString())
|
|
1142
|
-
};
|
|
1143
|
-
if (transcript.text.trim()) {
|
|
1144
|
-
this.liveTranscriptionSeen = true;
|
|
1145
|
-
this.onLiveTranscript(transcript);
|
|
1146
|
-
}
|
|
1147
|
-
break;
|
|
1148
|
-
}
|
|
1149
1113
|
case "network_quality": {
|
|
1150
1114
|
const raw = payload.quality || payload;
|
|
1151
1115
|
const quality = {
|
|
@@ -1603,6 +1567,78 @@ var SFUClient = class {
|
|
|
1603
1567
|
this.subscriptionRunning = false;
|
|
1604
1568
|
}
|
|
1605
1569
|
}
|
|
1570
|
+
/**
|
|
1571
|
+
* Enumerate media inputs and outputs exposed by the browser/OS.
|
|
1572
|
+
* Labels may be empty until the user has granted media permission.
|
|
1573
|
+
*/
|
|
1574
|
+
async getMediaDevices() {
|
|
1575
|
+
if (!navigator.mediaDevices?.enumerateDevices) {
|
|
1576
|
+
throw new Error("Media device enumeration is not supported on this device");
|
|
1577
|
+
}
|
|
1578
|
+
return navigator.mediaDevices.enumerateDevices();
|
|
1579
|
+
}
|
|
1580
|
+
/**
|
|
1581
|
+
* Replace the published camera without leaving the meeting.
|
|
1582
|
+
* The browser/OS must expose the target as a videoinput device.
|
|
1583
|
+
*/
|
|
1584
|
+
async selectCamera(deviceId) {
|
|
1585
|
+
if (!deviceId) throw new Error("Camera deviceId is required");
|
|
1586
|
+
if (!navigator.mediaDevices?.getUserMedia) {
|
|
1587
|
+
throw new Error("Camera access is not supported on this device");
|
|
1588
|
+
}
|
|
1589
|
+
const stream = await navigator.mediaDevices.getUserMedia({
|
|
1590
|
+
video: { deviceId: { exact: deviceId } },
|
|
1591
|
+
audio: false
|
|
1592
|
+
});
|
|
1593
|
+
const nextTrack = stream.getVideoTracks()[0];
|
|
1594
|
+
if (!nextTrack) {
|
|
1595
|
+
stream.getTracks().forEach((track) => track.stop());
|
|
1596
|
+
throw new Error("Selected camera returned no video track");
|
|
1597
|
+
}
|
|
1598
|
+
const currentTrack = this.localStream?.getVideoTracks()[0] ?? null;
|
|
1599
|
+
nextTrack.enabled = currentTrack?.enabled ?? true;
|
|
1600
|
+
if (!this.localStream) this.localStream = new MediaStream();
|
|
1601
|
+
if (currentTrack) this.localStream.removeTrack(currentTrack);
|
|
1602
|
+
this.localStream.addTrack(nextTrack);
|
|
1603
|
+
if (this.videoSender) {
|
|
1604
|
+
await this.videoSender.replaceTrack(nextTrack);
|
|
1605
|
+
}
|
|
1606
|
+
currentTrack?.stop();
|
|
1607
|
+
return nextTrack;
|
|
1608
|
+
}
|
|
1609
|
+
/**
|
|
1610
|
+
* Replace the published microphone without leaving the meeting.
|
|
1611
|
+
*/
|
|
1612
|
+
async selectMicrophone(deviceId) {
|
|
1613
|
+
if (!deviceId) throw new Error("Microphone deviceId is required");
|
|
1614
|
+
if (!navigator.mediaDevices?.getUserMedia) {
|
|
1615
|
+
throw new Error("Microphone access is not supported on this device");
|
|
1616
|
+
}
|
|
1617
|
+
const stream = await navigator.mediaDevices.getUserMedia({
|
|
1618
|
+
video: false,
|
|
1619
|
+
audio: {
|
|
1620
|
+
deviceId: { exact: deviceId },
|
|
1621
|
+
echoCancellation: true,
|
|
1622
|
+
noiseSuppression: true,
|
|
1623
|
+
autoGainControl: true
|
|
1624
|
+
}
|
|
1625
|
+
});
|
|
1626
|
+
const nextTrack = stream.getAudioTracks()[0];
|
|
1627
|
+
if (!nextTrack) {
|
|
1628
|
+
stream.getTracks().forEach((track) => track.stop());
|
|
1629
|
+
throw new Error("Selected microphone returned no audio track");
|
|
1630
|
+
}
|
|
1631
|
+
const currentTrack = this.localStream?.getAudioTracks()[0] ?? null;
|
|
1632
|
+
nextTrack.enabled = currentTrack?.enabled ?? true;
|
|
1633
|
+
if (!this.localStream) this.localStream = new MediaStream();
|
|
1634
|
+
if (currentTrack) this.localStream.removeTrack(currentTrack);
|
|
1635
|
+
this.localStream.addTrack(nextTrack);
|
|
1636
|
+
if (this.audioSender) {
|
|
1637
|
+
await this.audioSender.replaceTrack(nextTrack);
|
|
1638
|
+
}
|
|
1639
|
+
currentTrack?.stop();
|
|
1640
|
+
return nextTrack;
|
|
1641
|
+
}
|
|
1606
1642
|
async publish({ audio = true, video = true } = {}) {
|
|
1607
1643
|
if (!this.publisher)
|
|
1608
1644
|
throw new Error("Publisher PeerConnection is not initialized");
|
|
@@ -1824,27 +1860,6 @@ var SFUClient = class {
|
|
|
1824
1860
|
}
|
|
1825
1861
|
});
|
|
1826
1862
|
}
|
|
1827
|
-
/**
|
|
1828
|
-
* Transcription is server-authoritative. The SFU reads the already-published
|
|
1829
|
-
* microphone RTP stream, sends audio to the configured transcription service,
|
|
1830
|
-
* persists final segments, and broadcasts LiveTranscript events.
|
|
1831
|
-
*
|
|
1832
|
-
* These methods remain as compatibility shims for applications that used the
|
|
1833
|
-
* previous browser MediaRecorder-based API. They intentionally do not capture
|
|
1834
|
-
* or upload microphone audio from the browser.
|
|
1835
|
-
*/
|
|
1836
|
-
async startLiveTranscription() {
|
|
1837
|
-
if (!this.room) {
|
|
1838
|
-
throw new Error("Cannot start live transcription without a room");
|
|
1839
|
-
}
|
|
1840
|
-
console.info("[Transcript] server-authoritative live transcription is managed by the SFU");
|
|
1841
|
-
}
|
|
1842
|
-
stopLiveTranscription() {
|
|
1843
|
-
console.info("[Transcript] server-authoritative live transcription remains managed by the SFU");
|
|
1844
|
-
}
|
|
1845
|
-
isLiveTranscriptionActive() {
|
|
1846
|
-
return this.liveTranscriptionSeen;
|
|
1847
|
-
}
|
|
1848
1863
|
async getTranscript(roomCode, sessionId) {
|
|
1849
1864
|
if (!this.authToken) throw new Error("Authentication token is required");
|
|
1850
1865
|
const query = sessionId ? `?session_id=${encodeURIComponent(sessionId)}` : "";
|
|
@@ -2041,7 +2056,6 @@ var SFUClient = class {
|
|
|
2041
2056
|
}
|
|
2042
2057
|
}
|
|
2043
2058
|
async leave() {
|
|
2044
|
-
this.stopLiveTranscription();
|
|
2045
2059
|
this.stopHeartbeat();
|
|
2046
2060
|
this.intentionalClose = true;
|
|
2047
2061
|
this.setState("leaving");
|
|
@@ -2331,7 +2345,14 @@ var VideoSDKCore = class {
|
|
|
2331
2345
|
}
|
|
2332
2346
|
// JOIN
|
|
2333
2347
|
async joinMeeting(config) {
|
|
2334
|
-
const {
|
|
2348
|
+
const {
|
|
2349
|
+
roomId,
|
|
2350
|
+
name,
|
|
2351
|
+
audioMuted = false,
|
|
2352
|
+
videoMuted = false,
|
|
2353
|
+
cameraDeviceId,
|
|
2354
|
+
microphoneDeviceId
|
|
2355
|
+
} = config;
|
|
2335
2356
|
if (!roomId || !name) {
|
|
2336
2357
|
throw new Error("roomId and name are required to join meeting");
|
|
2337
2358
|
}
|
|
@@ -2366,8 +2387,13 @@ var VideoSDKCore = class {
|
|
|
2366
2387
|
this.room.name = name;
|
|
2367
2388
|
if (!this.localStream) {
|
|
2368
2389
|
this.localStream = await navigator.mediaDevices.getUserMedia({
|
|
2369
|
-
video: true,
|
|
2370
|
-
audio:
|
|
2390
|
+
video: cameraDeviceId ? { deviceId: { exact: cameraDeviceId } } : true,
|
|
2391
|
+
audio: microphoneDeviceId ? {
|
|
2392
|
+
deviceId: { exact: microphoneDeviceId },
|
|
2393
|
+
echoCancellation: true,
|
|
2394
|
+
noiseSuppression: true,
|
|
2395
|
+
autoGainControl: true
|
|
2396
|
+
} : true
|
|
2371
2397
|
});
|
|
2372
2398
|
const localAudioTrack = this.localStream.getAudioTracks()[0];
|
|
2373
2399
|
if (localAudioTrack) {
|
|
@@ -2456,10 +2482,6 @@ var VideoSDKCore = class {
|
|
|
2456
2482
|
console.warn(`[SFU] Reconnecting, attempt ${attempt}`);
|
|
2457
2483
|
},
|
|
2458
2484
|
// ADMISSION CONTROL
|
|
2459
|
-
onLiveTranscript: (transcript) => {
|
|
2460
|
-
this.state.addLiveTranscript(transcript);
|
|
2461
|
-
this.events.onLiveTranscript?.(transcript);
|
|
2462
|
-
},
|
|
2463
2485
|
onNetworkQuality: (quality) => {
|
|
2464
2486
|
this.state.setNetworkQuality(quality);
|
|
2465
2487
|
this.events.onNetworkQuality?.(quality);
|
|
@@ -2615,10 +2637,12 @@ var VideoSDKCore = class {
|
|
|
2615
2637
|
stream: null
|
|
2616
2638
|
}
|
|
2617
2639
|
});
|
|
2618
|
-
this.
|
|
2640
|
+
const joinedParticipant = this.state.getParticipant(pid) ?? {
|
|
2619
2641
|
id: pid,
|
|
2620
2642
|
name: pname
|
|
2621
|
-
}
|
|
2643
|
+
};
|
|
2644
|
+
this.events.onUserJoined?.(joinedParticipant);
|
|
2645
|
+
this.events.onParticipantJoined?.(joinedParticipant);
|
|
2622
2646
|
},
|
|
2623
2647
|
onParticipantPresence: (participantId, presence) => {
|
|
2624
2648
|
if (participantId === this.myId) {
|
|
@@ -2647,9 +2671,11 @@ var VideoSDKCore = class {
|
|
|
2647
2671
|
return;
|
|
2648
2672
|
}
|
|
2649
2673
|
console.log("[SFU] Participant permanently left", pid);
|
|
2674
|
+
const leavingParticipant = this.state.getParticipant(pid) ?? { id: pid };
|
|
2650
2675
|
this.cleanupRemoteParticipant(pid);
|
|
2651
2676
|
this.state.removeParticipant(pid);
|
|
2652
2677
|
this.events.onUserLeft?.(pid);
|
|
2678
|
+
this.events.onParticipantLeft?.(leavingParticipant);
|
|
2653
2679
|
},
|
|
2654
2680
|
// TRACKS
|
|
2655
2681
|
onParticipantMediaState: (participantId, audioMuted, videoMuted) => {
|
|
@@ -2959,6 +2985,39 @@ var VideoSDKCore = class {
|
|
|
2959
2985
|
return this.sfuClient?.removeModerator(roomCode, userId);
|
|
2960
2986
|
}
|
|
2961
2987
|
// MEDIA CONTROL
|
|
2988
|
+
async getMediaDevices() {
|
|
2989
|
+
if (!this.sfuClient) {
|
|
2990
|
+
throw new Error("SFU client is not initialized");
|
|
2991
|
+
}
|
|
2992
|
+
return this.sfuClient.getMediaDevices();
|
|
2993
|
+
}
|
|
2994
|
+
async selectCamera(deviceId) {
|
|
2995
|
+
if (!this.sfuClient) {
|
|
2996
|
+
throw new Error("SFU client is not initialized");
|
|
2997
|
+
}
|
|
2998
|
+
const track = await this.sfuClient.selectCamera(deviceId);
|
|
2999
|
+
if (this.localStream) {
|
|
3000
|
+
this.state.localStream = this.localStream;
|
|
3001
|
+
this.updateLocalMedia();
|
|
3002
|
+
}
|
|
3003
|
+
return track;
|
|
3004
|
+
}
|
|
3005
|
+
async selectMicrophone(deviceId) {
|
|
3006
|
+
if (!this.sfuClient) {
|
|
3007
|
+
throw new Error("SFU client is not initialized");
|
|
3008
|
+
}
|
|
3009
|
+
const track = await this.sfuClient.selectMicrophone(deviceId);
|
|
3010
|
+
if (this.localStream) {
|
|
3011
|
+
const mic = this.localStream.getAudioTracks()[0];
|
|
3012
|
+
if (mic) {
|
|
3013
|
+
this.activeSpeakerDetector.removeParticipant(this.myId);
|
|
3014
|
+
this.activeSpeakerDetector.addTrack(this.myId, mic);
|
|
3015
|
+
}
|
|
3016
|
+
this.state.localStream = this.localStream;
|
|
3017
|
+
this.updateLocalMedia();
|
|
3018
|
+
}
|
|
3019
|
+
return track;
|
|
3020
|
+
}
|
|
2962
3021
|
toggleMic() {
|
|
2963
3022
|
const mediaState = this.state.localParticipant?.media;
|
|
2964
3023
|
if (!mediaState || !this.localStream) {
|
|
@@ -3108,22 +3167,6 @@ var VideoSDKCore = class {
|
|
|
3108
3167
|
}
|
|
3109
3168
|
}
|
|
3110
3169
|
}
|
|
3111
|
-
async startLiveTranscription() {
|
|
3112
|
-
if (!this.sfuClient) {
|
|
3113
|
-
throw new Error("SFU client is not connected");
|
|
3114
|
-
}
|
|
3115
|
-
const audioTrack = this.localStream?.getAudioTracks()[0];
|
|
3116
|
-
if (!audioTrack || audioTrack.readyState !== "live") {
|
|
3117
|
-
throw new Error("Microphone audio track is not available");
|
|
3118
|
-
}
|
|
3119
|
-
await this.sfuClient.startLiveTranscription();
|
|
3120
|
-
}
|
|
3121
|
-
stopLiveTranscription() {
|
|
3122
|
-
this.sfuClient?.stopLiveTranscription();
|
|
3123
|
-
}
|
|
3124
|
-
isLiveTranscriptionActive() {
|
|
3125
|
-
return this.sfuClient?.isLiveTranscriptionActive() ?? false;
|
|
3126
|
-
}
|
|
3127
3170
|
getNetworkQuality() {
|
|
3128
3171
|
return this.state.networkQuality;
|
|
3129
3172
|
}
|
|
@@ -3175,7 +3218,6 @@ var VideoSDKCore = class {
|
|
|
3175
3218
|
this.room.id = null;
|
|
3176
3219
|
this.room.name = null;
|
|
3177
3220
|
this.state.localParticipant = null;
|
|
3178
|
-
this.state.clearLiveTranscripts();
|
|
3179
3221
|
this.state.setNetworkQuality(null);
|
|
3180
3222
|
this.state.notify("localParticipant");
|
|
3181
3223
|
this.state.resetRemoteState();
|
|
@@ -3230,15 +3272,21 @@ var MeetingProvider = ({
|
|
|
3230
3272
|
const activeSpeakerListeners = (0, import_react2.useRef)(
|
|
3231
3273
|
/* @__PURE__ */ new Set()
|
|
3232
3274
|
);
|
|
3233
|
-
const liveTranscriptListeners = (0, import_react2.useRef)(
|
|
3234
|
-
/* @__PURE__ */ new Set()
|
|
3235
|
-
);
|
|
3236
3275
|
const networkQualityListeners = (0, import_react2.useRef)(
|
|
3237
3276
|
/* @__PURE__ */ new Set()
|
|
3238
3277
|
);
|
|
3239
3278
|
const connectionStateListeners = (0, import_react2.useRef)(
|
|
3240
3279
|
/* @__PURE__ */ new Set()
|
|
3241
3280
|
);
|
|
3281
|
+
const participantJoinedListeners = (0, import_react2.useRef)(
|
|
3282
|
+
/* @__PURE__ */ new Set()
|
|
3283
|
+
);
|
|
3284
|
+
const participantLeftListeners = (0, import_react2.useRef)(
|
|
3285
|
+
/* @__PURE__ */ new Set()
|
|
3286
|
+
);
|
|
3287
|
+
const chatMessageListeners = (0, import_react2.useRef)(
|
|
3288
|
+
/* @__PURE__ */ new Set()
|
|
3289
|
+
);
|
|
3242
3290
|
if (!sdkRef.current) {
|
|
3243
3291
|
sdkRef.current = new VideoSDKCore(
|
|
3244
3292
|
{
|
|
@@ -3299,6 +3347,7 @@ var MeetingProvider = ({
|
|
|
3299
3347
|
data: msg
|
|
3300
3348
|
};
|
|
3301
3349
|
pubSubListeners.current.get("SECURE_CHAT")?.forEach((fn) => fn(pubSubMessage));
|
|
3350
|
+
chatMessageListeners.current.forEach((fn) => fn(msg));
|
|
3302
3351
|
},
|
|
3303
3352
|
onReaction: (reaction) => {
|
|
3304
3353
|
reactionListeners.current.forEach((fn) => fn(reaction));
|
|
@@ -3319,9 +3368,6 @@ var MeetingProvider = ({
|
|
|
3319
3368
|
);
|
|
3320
3369
|
pubSubListeners.current.get("REACTION")?.forEach((fn) => fn(message));
|
|
3321
3370
|
},
|
|
3322
|
-
onLiveTranscript: (transcript) => {
|
|
3323
|
-
liveTranscriptListeners.current.forEach((fn) => fn(transcript));
|
|
3324
|
-
},
|
|
3325
3371
|
onNetworkQuality: (quality) => {
|
|
3326
3372
|
networkQualityListeners.current.forEach((fn) => fn(quality));
|
|
3327
3373
|
},
|
|
@@ -3329,6 +3375,12 @@ var MeetingProvider = ({
|
|
|
3329
3375
|
connectionStateListeners.current.forEach(
|
|
3330
3376
|
(fn) => fn(state)
|
|
3331
3377
|
);
|
|
3378
|
+
},
|
|
3379
|
+
onParticipantJoined: (participant) => {
|
|
3380
|
+
participantJoinedListeners.current.forEach((fn) => fn(participant));
|
|
3381
|
+
},
|
|
3382
|
+
onParticipantLeft: (participant) => {
|
|
3383
|
+
participantLeftListeners.current.forEach((fn) => fn(participant));
|
|
3332
3384
|
}
|
|
3333
3385
|
}
|
|
3334
3386
|
);
|
|
@@ -3360,11 +3412,6 @@ var MeetingProvider = ({
|
|
|
3360
3412
|
"chat",
|
|
3361
3413
|
(s) => s.getChatMessages()
|
|
3362
3414
|
);
|
|
3363
|
-
const liveTranscripts = useMeetingStore(
|
|
3364
|
-
sdk.state,
|
|
3365
|
-
"transcript",
|
|
3366
|
-
(s) => s.getLiveTranscripts()
|
|
3367
|
-
);
|
|
3368
3415
|
const networkQuality = useMeetingStore(
|
|
3369
3416
|
sdk.state,
|
|
3370
3417
|
"networkQuality",
|
|
@@ -3382,6 +3429,9 @@ var MeetingProvider = ({
|
|
|
3382
3429
|
createRoom: sdk.createRoom.bind(sdk),
|
|
3383
3430
|
getRoom: sdk.getRoom.bind(sdk),
|
|
3384
3431
|
deleteRoom: sdk.deleteRoom.bind(sdk),
|
|
3432
|
+
getMediaDevices: sdk.getMediaDevices.bind(sdk),
|
|
3433
|
+
selectCamera: sdk.selectCamera.bind(sdk),
|
|
3434
|
+
selectMicrophone: sdk.selectMicrophone.bind(sdk),
|
|
3385
3435
|
getTranscript: sdk.getTranscript.bind(sdk),
|
|
3386
3436
|
getMeetingSummary: sdk.getMeetingSummary.bind(sdk),
|
|
3387
3437
|
toggleMic: sdk.toggleMic.bind(sdk),
|
|
@@ -3396,11 +3446,7 @@ var MeetingProvider = ({
|
|
|
3396
3446
|
messages,
|
|
3397
3447
|
presenterId,
|
|
3398
3448
|
activeSpeakerIds,
|
|
3399
|
-
liveTranscripts,
|
|
3400
3449
|
networkQuality,
|
|
3401
|
-
startLiveTranscription: sdk.startLiveTranscription.bind(sdk),
|
|
3402
|
-
stopLiveTranscription: sdk.stopLiveTranscription.bind(sdk),
|
|
3403
|
-
isLiveTranscriptionActive: sdk.isLiveTranscriptionActive.bind(sdk),
|
|
3404
3450
|
recording,
|
|
3405
3451
|
usePubSub: (topic) => {
|
|
3406
3452
|
if (topic === "SECURE_CHAT") {
|
|
@@ -3519,10 +3565,6 @@ var MeetingProvider = ({
|
|
|
3519
3565
|
reactionListeners.current.add(cb);
|
|
3520
3566
|
return () => reactionListeners.current.delete(cb);
|
|
3521
3567
|
},
|
|
3522
|
-
onLiveTranscript: (cb) => {
|
|
3523
|
-
liveTranscriptListeners.current.add(cb);
|
|
3524
|
-
return () => liveTranscriptListeners.current.delete(cb);
|
|
3525
|
-
},
|
|
3526
3568
|
onNetworkQuality: (cb) => {
|
|
3527
3569
|
networkQualityListeners.current.add(cb);
|
|
3528
3570
|
return () => networkQualityListeners.current.delete(cb);
|
|
@@ -3538,6 +3580,18 @@ var MeetingProvider = ({
|
|
|
3538
3580
|
return () => {
|
|
3539
3581
|
activeSpeakerListeners.current.delete(cb);
|
|
3540
3582
|
};
|
|
3583
|
+
},
|
|
3584
|
+
onParticipantJoined: (cb) => {
|
|
3585
|
+
participantJoinedListeners.current.add(cb);
|
|
3586
|
+
return () => participantJoinedListeners.current.delete(cb);
|
|
3587
|
+
},
|
|
3588
|
+
onChatMessage: (cb) => {
|
|
3589
|
+
chatMessageListeners.current.add(cb);
|
|
3590
|
+
return () => chatMessageListeners.current.delete(cb);
|
|
3591
|
+
},
|
|
3592
|
+
onParticipantLeft: (cb) => {
|
|
3593
|
+
participantLeftListeners.current.add(cb);
|
|
3594
|
+
return () => participantLeftListeners.current.delete(cb);
|
|
3541
3595
|
}
|
|
3542
3596
|
};
|
|
3543
3597
|
}, [
|
|
@@ -3549,7 +3603,6 @@ var MeetingProvider = ({
|
|
|
3549
3603
|
presenterId,
|
|
3550
3604
|
recording,
|
|
3551
3605
|
activeSpeakerIds,
|
|
3552
|
-
liveTranscripts,
|
|
3553
3606
|
networkQuality,
|
|
3554
3607
|
reactionPubSubMessages
|
|
3555
3608
|
]);
|
|
@@ -3659,14 +3712,22 @@ var useMeeting = (handlers) => {
|
|
|
3659
3712
|
if (!handlers?.onConnectionStateChanged) return;
|
|
3660
3713
|
return ctx.onConnectionStateChanged(handlers.onConnectionStateChanged);
|
|
3661
3714
|
}, [handlers?.onConnectionStateChanged]);
|
|
3662
|
-
(0, import_react4.useEffect)(() => {
|
|
3663
|
-
if (!handlers?.onLiveTranscript) return;
|
|
3664
|
-
return ctx.onLiveTranscript(handlers.onLiveTranscript);
|
|
3665
|
-
}, [handlers?.onLiveTranscript]);
|
|
3666
3715
|
(0, import_react4.useEffect)(() => {
|
|
3667
3716
|
if (!handlers?.onNetworkQuality) return;
|
|
3668
3717
|
return ctx.onNetworkQuality(handlers.onNetworkQuality);
|
|
3669
3718
|
}, [handlers?.onNetworkQuality]);
|
|
3719
|
+
(0, import_react4.useEffect)(() => {
|
|
3720
|
+
if (!handlers?.onParticipantJoined) return;
|
|
3721
|
+
return ctx.onParticipantJoined(handlers.onParticipantJoined);
|
|
3722
|
+
}, [handlers?.onParticipantJoined]);
|
|
3723
|
+
(0, import_react4.useEffect)(() => {
|
|
3724
|
+
if (!handlers?.onParticipantLeft) return;
|
|
3725
|
+
return ctx.onParticipantLeft(handlers.onParticipantLeft);
|
|
3726
|
+
}, [handlers?.onParticipantLeft]);
|
|
3727
|
+
(0, import_react4.useEffect)(() => {
|
|
3728
|
+
if (!handlers?.onChatMessage) return;
|
|
3729
|
+
return ctx.onChatMessage(handlers.onChatMessage);
|
|
3730
|
+
}, [handlers?.onChatMessage]);
|
|
3670
3731
|
(0, import_react4.useEffect)(() => {
|
|
3671
3732
|
if (!handlers?.onReaction) return;
|
|
3672
3733
|
return ctx.onReaction(handlers.onReaction);
|
|
@@ -3804,16 +3865,6 @@ function useMeetingPreview(roomId, participantId) {
|
|
|
3804
3865
|
};
|
|
3805
3866
|
}
|
|
3806
3867
|
|
|
3807
|
-
// src/react/useLiveTranscript.ts
|
|
3808
|
-
var useLiveTranscript = () => {
|
|
3809
|
-
const { sdk } = useMeetingContext();
|
|
3810
|
-
return useMeetingStore(
|
|
3811
|
-
sdk.state,
|
|
3812
|
-
"transcript",
|
|
3813
|
-
(state) => state.getLiveTranscripts()
|
|
3814
|
-
);
|
|
3815
|
-
};
|
|
3816
|
-
|
|
3817
3868
|
// src/react/useNetworkQuality.ts
|
|
3818
3869
|
var useNetworkQuality = () => {
|
|
3819
3870
|
const { sdk } = useMeetingContext();
|
|
@@ -3843,7 +3894,6 @@ function usePubSub(topic, options) {
|
|
|
3843
3894
|
MeetingProvider,
|
|
3844
3895
|
MeetingState,
|
|
3845
3896
|
VideoSDKCore,
|
|
3846
|
-
useLiveTranscript,
|
|
3847
3897
|
useLocalParticipant,
|
|
3848
3898
|
useMeeting,
|
|
3849
3899
|
useMeetingContext,
|