@defcomm/meetingsdk 0.2.7 → 0.2.9
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 +23 -5
- package/dist/index.d.ts +23 -5
- package/dist/index.js +84 -39
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +84 -39
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -22,6 +22,7 @@ type Events = {
|
|
|
22
22
|
onUserLeft?: (id: string) => void;
|
|
23
23
|
onMeetingLeft?: () => void;
|
|
24
24
|
onChatMessage?: (msg: ChatMessage) => void;
|
|
25
|
+
onReaction?: (reaction: Reaction) => void;
|
|
25
26
|
onScreenShareStarted?: (peerId: string, stream: MediaStream) => void;
|
|
26
27
|
onScreenShareStopped?: (peerId: string) => void;
|
|
27
28
|
onMuteStateChanged?: (peerId: string, kind: "audio" | "video", muted: boolean) => void;
|
|
@@ -39,6 +40,13 @@ type Events = {
|
|
|
39
40
|
stopped_at: string;
|
|
40
41
|
}) => void;
|
|
41
42
|
};
|
|
43
|
+
type Reaction = {
|
|
44
|
+
id: string;
|
|
45
|
+
participant_id: string;
|
|
46
|
+
sender_name?: string | null;
|
|
47
|
+
emoji: string;
|
|
48
|
+
timestamp: string | number;
|
|
49
|
+
};
|
|
42
50
|
type ChatMessage = {
|
|
43
51
|
id: string;
|
|
44
52
|
text: string;
|
|
@@ -211,7 +219,7 @@ declare class VideoSDKCore {
|
|
|
211
219
|
rejectJoinRequest(requestId: string, reason?: string): Promise<void>;
|
|
212
220
|
toggleMic(): void;
|
|
213
221
|
toggleCam(): void;
|
|
214
|
-
startScreenShare(): Promise<MediaStream>;
|
|
222
|
+
startScreenShare(): Promise<MediaStream | null>;
|
|
215
223
|
stopScreenShare(): void;
|
|
216
224
|
startRecording(): Promise<void>;
|
|
217
225
|
stopRecording(): Promise<void>;
|
|
@@ -219,6 +227,7 @@ declare class VideoSDKCore {
|
|
|
219
227
|
recording: RecordingInfo | null;
|
|
220
228
|
}>;
|
|
221
229
|
sendChatMessage(payload: ChatInput): void;
|
|
230
|
+
sendReaction(reaction: string): void;
|
|
222
231
|
private cleanupRemoteParticipant;
|
|
223
232
|
disconnect(): Promise<void>;
|
|
224
233
|
private performDisconnect;
|
|
@@ -285,6 +294,7 @@ interface SFUClientOptions {
|
|
|
285
294
|
}) => void;
|
|
286
295
|
onError?: (error: any) => void;
|
|
287
296
|
onChatMessage?: (message: any) => void;
|
|
297
|
+
onReaction?: (reaction: any) => void;
|
|
288
298
|
onRoomUpdate?: (data: any) => void;
|
|
289
299
|
onParticipantMediaState?: (participantId: string, audioMuted: boolean, videoMuted: boolean) => void;
|
|
290
300
|
autoSubscribe?: boolean;
|
|
@@ -307,6 +317,7 @@ declare class SFUClient {
|
|
|
307
317
|
private iceServers;
|
|
308
318
|
private requestId;
|
|
309
319
|
private publisherRevision;
|
|
320
|
+
private screenShareGeneration;
|
|
310
321
|
private currentParticipantId;
|
|
311
322
|
private token;
|
|
312
323
|
private room;
|
|
@@ -362,6 +373,7 @@ declare class SFUClient {
|
|
|
362
373
|
private onRecordingStopped;
|
|
363
374
|
private onError;
|
|
364
375
|
private onChatMessage;
|
|
376
|
+
private onReaction;
|
|
365
377
|
private onRoomUpdate;
|
|
366
378
|
private onParticipantMediaState;
|
|
367
379
|
private autoSubscribe;
|
|
@@ -424,7 +436,7 @@ declare class SFUClient {
|
|
|
424
436
|
video?: boolean | undefined;
|
|
425
437
|
}): Promise<MediaStream>;
|
|
426
438
|
private publishExistingTracks;
|
|
427
|
-
shareScreen(): Promise<MediaStream>;
|
|
439
|
+
shareScreen(): Promise<MediaStream | null>;
|
|
428
440
|
stopScreenShare(): Promise<void>;
|
|
429
441
|
muteAudio(muted: boolean): void;
|
|
430
442
|
muteVideo(muted: boolean): void;
|
|
@@ -440,6 +452,7 @@ declare class SFUClient {
|
|
|
440
452
|
rejectJoinRequest(requestId: string, reason?: string): Promise<void>;
|
|
441
453
|
private isSocketOpen;
|
|
442
454
|
private send;
|
|
455
|
+
sendReaction(reaction: string): void;
|
|
443
456
|
private removeRemoteParticipant;
|
|
444
457
|
leave(): Promise<void>;
|
|
445
458
|
private closePeerConnectionsOnly;
|
|
@@ -466,9 +479,10 @@ type MeetingContextValue = {
|
|
|
466
479
|
deleteRoom: (roomCode: string) => Promise<any>;
|
|
467
480
|
toggleMic: () => void;
|
|
468
481
|
toggleCam: () => void;
|
|
469
|
-
startScreenShare: () => Promise<MediaStream>;
|
|
482
|
+
startScreenShare: () => Promise<MediaStream | null>;
|
|
470
483
|
stopScreenShare: () => void;
|
|
471
484
|
sendMessage: (input: ChatInput) => void;
|
|
485
|
+
sendReaction: (emoji: string) => void;
|
|
472
486
|
room: {
|
|
473
487
|
id: string | null;
|
|
474
488
|
name: string | null;
|
|
@@ -491,6 +505,7 @@ type MeetingContextValue = {
|
|
|
491
505
|
onTrackStateChanged: (cb: (track: any) => void) => () => void;
|
|
492
506
|
onRecordingStarted: (cb: (recording: Recording) => void) => () => void;
|
|
493
507
|
onRecordingStopped: (cb: (recording: any) => void) => () => void;
|
|
508
|
+
onReaction: (cb: (reaction: Reaction) => void) => () => void;
|
|
494
509
|
onActiveSpeakersChanged: (cb: (participantIds: string[]) => void) => () => void;
|
|
495
510
|
};
|
|
496
511
|
declare const MeetingProvider: ({ config, children, }: {
|
|
@@ -507,6 +522,7 @@ declare const useMeeting: (handlers?: {
|
|
|
507
522
|
onTrackStateChanged?: (track: any) => void;
|
|
508
523
|
onRecordingStarted?: (recording: any) => void;
|
|
509
524
|
onRecordingStopped?: (recording: any) => void;
|
|
525
|
+
onReaction?: (reaction: any) => void;
|
|
510
526
|
onActiveSpeakersChanged?: (participantIds: string[]) => void;
|
|
511
527
|
}) => {
|
|
512
528
|
join: (config?: Omit<MeetingConfig, "participantId">) => Promise<void>;
|
|
@@ -521,9 +537,10 @@ declare const useMeeting: (handlers?: {
|
|
|
521
537
|
deleteRoom: (roomCode: string) => Promise<any>;
|
|
522
538
|
toggleMic: () => void;
|
|
523
539
|
toggleCam: () => void;
|
|
524
|
-
startScreenShare: () => Promise<MediaStream>;
|
|
540
|
+
startScreenShare: () => Promise<MediaStream | null>;
|
|
525
541
|
stopScreenShare: () => void;
|
|
526
542
|
sendMessage: (input: ChatInput) => void;
|
|
543
|
+
sendReaction: (emoji: string) => void;
|
|
527
544
|
room: {
|
|
528
545
|
id: string | null;
|
|
529
546
|
name: string | null;
|
|
@@ -549,6 +566,7 @@ declare const useMeeting: (handlers?: {
|
|
|
549
566
|
onTrackStateChanged: (cb: (track: any) => void) => () => void;
|
|
550
567
|
onRecordingStarted: (cb: (recording: Recording) => void) => () => void;
|
|
551
568
|
onRecordingStopped: (cb: (recording: any) => void) => () => void;
|
|
569
|
+
onReaction: (cb: (reaction: Reaction) => void) => () => void;
|
|
552
570
|
onActiveSpeakersChanged: (cb: (participantIds: string[]) => void) => () => void;
|
|
553
571
|
};
|
|
554
572
|
|
|
@@ -629,4 +647,4 @@ declare class ActiveSpeakerDetector {
|
|
|
629
647
|
destroy(): Promise<void>;
|
|
630
648
|
}
|
|
631
649
|
|
|
632
|
-
export { ActiveSpeakerDetector, type ChatInput, type MeetingConfig, MeetingProvider, MeetingState, type Participant, type ParticipantInfo, type RecordingInfo, SFUClient, type SFUConnectionState, type TrackInfo, VideoSDKCore, useLocalParticipant, useMeeting, useMeetingContext, useMeetingPreview, useParticipants, useRemoteMedia };
|
|
650
|
+
export { ActiveSpeakerDetector, type ChatInput, type MeetingConfig, MeetingProvider, MeetingState, type Participant, type ParticipantInfo, type Reaction, type RecordingInfo, SFUClient, type SFUConnectionState, type TrackInfo, VideoSDKCore, useLocalParticipant, useMeeting, useMeetingContext, useMeetingPreview, useParticipants, useRemoteMedia };
|
package/dist/index.d.ts
CHANGED
|
@@ -22,6 +22,7 @@ type Events = {
|
|
|
22
22
|
onUserLeft?: (id: string) => void;
|
|
23
23
|
onMeetingLeft?: () => void;
|
|
24
24
|
onChatMessage?: (msg: ChatMessage) => void;
|
|
25
|
+
onReaction?: (reaction: Reaction) => void;
|
|
25
26
|
onScreenShareStarted?: (peerId: string, stream: MediaStream) => void;
|
|
26
27
|
onScreenShareStopped?: (peerId: string) => void;
|
|
27
28
|
onMuteStateChanged?: (peerId: string, kind: "audio" | "video", muted: boolean) => void;
|
|
@@ -39,6 +40,13 @@ type Events = {
|
|
|
39
40
|
stopped_at: string;
|
|
40
41
|
}) => void;
|
|
41
42
|
};
|
|
43
|
+
type Reaction = {
|
|
44
|
+
id: string;
|
|
45
|
+
participant_id: string;
|
|
46
|
+
sender_name?: string | null;
|
|
47
|
+
emoji: string;
|
|
48
|
+
timestamp: string | number;
|
|
49
|
+
};
|
|
42
50
|
type ChatMessage = {
|
|
43
51
|
id: string;
|
|
44
52
|
text: string;
|
|
@@ -211,7 +219,7 @@ declare class VideoSDKCore {
|
|
|
211
219
|
rejectJoinRequest(requestId: string, reason?: string): Promise<void>;
|
|
212
220
|
toggleMic(): void;
|
|
213
221
|
toggleCam(): void;
|
|
214
|
-
startScreenShare(): Promise<MediaStream>;
|
|
222
|
+
startScreenShare(): Promise<MediaStream | null>;
|
|
215
223
|
stopScreenShare(): void;
|
|
216
224
|
startRecording(): Promise<void>;
|
|
217
225
|
stopRecording(): Promise<void>;
|
|
@@ -219,6 +227,7 @@ declare class VideoSDKCore {
|
|
|
219
227
|
recording: RecordingInfo | null;
|
|
220
228
|
}>;
|
|
221
229
|
sendChatMessage(payload: ChatInput): void;
|
|
230
|
+
sendReaction(reaction: string): void;
|
|
222
231
|
private cleanupRemoteParticipant;
|
|
223
232
|
disconnect(): Promise<void>;
|
|
224
233
|
private performDisconnect;
|
|
@@ -285,6 +294,7 @@ interface SFUClientOptions {
|
|
|
285
294
|
}) => void;
|
|
286
295
|
onError?: (error: any) => void;
|
|
287
296
|
onChatMessage?: (message: any) => void;
|
|
297
|
+
onReaction?: (reaction: any) => void;
|
|
288
298
|
onRoomUpdate?: (data: any) => void;
|
|
289
299
|
onParticipantMediaState?: (participantId: string, audioMuted: boolean, videoMuted: boolean) => void;
|
|
290
300
|
autoSubscribe?: boolean;
|
|
@@ -307,6 +317,7 @@ declare class SFUClient {
|
|
|
307
317
|
private iceServers;
|
|
308
318
|
private requestId;
|
|
309
319
|
private publisherRevision;
|
|
320
|
+
private screenShareGeneration;
|
|
310
321
|
private currentParticipantId;
|
|
311
322
|
private token;
|
|
312
323
|
private room;
|
|
@@ -362,6 +373,7 @@ declare class SFUClient {
|
|
|
362
373
|
private onRecordingStopped;
|
|
363
374
|
private onError;
|
|
364
375
|
private onChatMessage;
|
|
376
|
+
private onReaction;
|
|
365
377
|
private onRoomUpdate;
|
|
366
378
|
private onParticipantMediaState;
|
|
367
379
|
private autoSubscribe;
|
|
@@ -424,7 +436,7 @@ declare class SFUClient {
|
|
|
424
436
|
video?: boolean | undefined;
|
|
425
437
|
}): Promise<MediaStream>;
|
|
426
438
|
private publishExistingTracks;
|
|
427
|
-
shareScreen(): Promise<MediaStream>;
|
|
439
|
+
shareScreen(): Promise<MediaStream | null>;
|
|
428
440
|
stopScreenShare(): Promise<void>;
|
|
429
441
|
muteAudio(muted: boolean): void;
|
|
430
442
|
muteVideo(muted: boolean): void;
|
|
@@ -440,6 +452,7 @@ declare class SFUClient {
|
|
|
440
452
|
rejectJoinRequest(requestId: string, reason?: string): Promise<void>;
|
|
441
453
|
private isSocketOpen;
|
|
442
454
|
private send;
|
|
455
|
+
sendReaction(reaction: string): void;
|
|
443
456
|
private removeRemoteParticipant;
|
|
444
457
|
leave(): Promise<void>;
|
|
445
458
|
private closePeerConnectionsOnly;
|
|
@@ -466,9 +479,10 @@ type MeetingContextValue = {
|
|
|
466
479
|
deleteRoom: (roomCode: string) => Promise<any>;
|
|
467
480
|
toggleMic: () => void;
|
|
468
481
|
toggleCam: () => void;
|
|
469
|
-
startScreenShare: () => Promise<MediaStream>;
|
|
482
|
+
startScreenShare: () => Promise<MediaStream | null>;
|
|
470
483
|
stopScreenShare: () => void;
|
|
471
484
|
sendMessage: (input: ChatInput) => void;
|
|
485
|
+
sendReaction: (emoji: string) => void;
|
|
472
486
|
room: {
|
|
473
487
|
id: string | null;
|
|
474
488
|
name: string | null;
|
|
@@ -491,6 +505,7 @@ type MeetingContextValue = {
|
|
|
491
505
|
onTrackStateChanged: (cb: (track: any) => void) => () => void;
|
|
492
506
|
onRecordingStarted: (cb: (recording: Recording) => void) => () => void;
|
|
493
507
|
onRecordingStopped: (cb: (recording: any) => void) => () => void;
|
|
508
|
+
onReaction: (cb: (reaction: Reaction) => void) => () => void;
|
|
494
509
|
onActiveSpeakersChanged: (cb: (participantIds: string[]) => void) => () => void;
|
|
495
510
|
};
|
|
496
511
|
declare const MeetingProvider: ({ config, children, }: {
|
|
@@ -507,6 +522,7 @@ declare const useMeeting: (handlers?: {
|
|
|
507
522
|
onTrackStateChanged?: (track: any) => void;
|
|
508
523
|
onRecordingStarted?: (recording: any) => void;
|
|
509
524
|
onRecordingStopped?: (recording: any) => void;
|
|
525
|
+
onReaction?: (reaction: any) => void;
|
|
510
526
|
onActiveSpeakersChanged?: (participantIds: string[]) => void;
|
|
511
527
|
}) => {
|
|
512
528
|
join: (config?: Omit<MeetingConfig, "participantId">) => Promise<void>;
|
|
@@ -521,9 +537,10 @@ declare const useMeeting: (handlers?: {
|
|
|
521
537
|
deleteRoom: (roomCode: string) => Promise<any>;
|
|
522
538
|
toggleMic: () => void;
|
|
523
539
|
toggleCam: () => void;
|
|
524
|
-
startScreenShare: () => Promise<MediaStream>;
|
|
540
|
+
startScreenShare: () => Promise<MediaStream | null>;
|
|
525
541
|
stopScreenShare: () => void;
|
|
526
542
|
sendMessage: (input: ChatInput) => void;
|
|
543
|
+
sendReaction: (emoji: string) => void;
|
|
527
544
|
room: {
|
|
528
545
|
id: string | null;
|
|
529
546
|
name: string | null;
|
|
@@ -549,6 +566,7 @@ declare const useMeeting: (handlers?: {
|
|
|
549
566
|
onTrackStateChanged: (cb: (track: any) => void) => () => void;
|
|
550
567
|
onRecordingStarted: (cb: (recording: Recording) => void) => () => void;
|
|
551
568
|
onRecordingStopped: (cb: (recording: any) => void) => () => void;
|
|
569
|
+
onReaction: (cb: (reaction: Reaction) => void) => () => void;
|
|
552
570
|
onActiveSpeakersChanged: (cb: (participantIds: string[]) => void) => () => void;
|
|
553
571
|
};
|
|
554
572
|
|
|
@@ -629,4 +647,4 @@ declare class ActiveSpeakerDetector {
|
|
|
629
647
|
destroy(): Promise<void>;
|
|
630
648
|
}
|
|
631
649
|
|
|
632
|
-
export { ActiveSpeakerDetector, type ChatInput, type MeetingConfig, MeetingProvider, MeetingState, type Participant, type ParticipantInfo, type RecordingInfo, SFUClient, type SFUConnectionState, type TrackInfo, VideoSDKCore, useLocalParticipant, useMeeting, useMeetingContext, useMeetingPreview, useParticipants, useRemoteMedia };
|
|
650
|
+
export { ActiveSpeakerDetector, type ChatInput, type MeetingConfig, MeetingProvider, MeetingState, type Participant, type ParticipantInfo, type Reaction, type RecordingInfo, SFUClient, type SFUConnectionState, type TrackInfo, VideoSDKCore, useLocalParticipant, useMeeting, useMeetingContext, useMeetingPreview, useParticipants, useRemoteMedia };
|
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;
|
|
@@ -475,6 +476,8 @@ var SFUClient = class {
|
|
|
475
476
|
this.onError = options.onError || console.error;
|
|
476
477
|
this.onChatMessage = options.onChatMessage || (() => {
|
|
477
478
|
});
|
|
479
|
+
this.onReaction = options.onReaction || (() => {
|
|
480
|
+
});
|
|
478
481
|
this.onRoomUpdate = options.onRoomUpdate || (() => {
|
|
479
482
|
});
|
|
480
483
|
this.onParticipantMediaState = options.onParticipantMediaState || (() => {
|
|
@@ -601,8 +604,10 @@ var SFUClient = class {
|
|
|
601
604
|
avatarUrl: options.avatarUrl
|
|
602
605
|
};
|
|
603
606
|
if (options.participantId) this.participantId = options.participantId;
|
|
604
|
-
if (typeof options.audioMuted === "boolean")
|
|
605
|
-
|
|
607
|
+
if (typeof options.audioMuted === "boolean")
|
|
608
|
+
this.desiredAudioMuted = options.audioMuted;
|
|
609
|
+
if (typeof options.videoMuted === "boolean")
|
|
610
|
+
this.desiredVideoMuted = options.videoMuted;
|
|
606
611
|
if (!this.resumeToken) {
|
|
607
612
|
this.resumeToken = this.loadResumeToken(this.room);
|
|
608
613
|
}
|
|
@@ -987,8 +992,15 @@ var SFUClient = class {
|
|
|
987
992
|
if (!pid) continue;
|
|
988
993
|
if (pid !== this.currentParticipantId) {
|
|
989
994
|
this.participants.set(pid, participant);
|
|
990
|
-
this.onParticipantPresence(
|
|
991
|
-
|
|
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
|
+
);
|
|
992
1004
|
}
|
|
993
1005
|
}
|
|
994
1006
|
for (const [pid] of this.participants) {
|
|
@@ -1000,7 +1012,8 @@ var SFUClient = class {
|
|
|
1000
1012
|
}
|
|
1001
1013
|
for (const track of payload.tracks || []) this.rememberTrack(track);
|
|
1002
1014
|
if (Array.isArray(payload.chat_history)) {
|
|
1003
|
-
for (const message2 of payload.chat_history)
|
|
1015
|
+
for (const message2 of payload.chat_history)
|
|
1016
|
+
this.onChatMessage(message2);
|
|
1004
1017
|
}
|
|
1005
1018
|
break;
|
|
1006
1019
|
}
|
|
@@ -1009,6 +1022,11 @@ var SFUClient = class {
|
|
|
1009
1022
|
if (msg?.id) this.onChatMessage(msg);
|
|
1010
1023
|
break;
|
|
1011
1024
|
}
|
|
1025
|
+
case "reaction": {
|
|
1026
|
+
const reaction = payload.reaction || payload;
|
|
1027
|
+
if (reaction?.id && reaction?.emoji) this.onReaction(reaction);
|
|
1028
|
+
break;
|
|
1029
|
+
}
|
|
1012
1030
|
case "error": {
|
|
1013
1031
|
const message2 = payload.message || "SFU signaling error";
|
|
1014
1032
|
if (this.state === "reconnecting" && message2.includes("participant session is stale")) {
|
|
@@ -1033,7 +1051,9 @@ var SFUClient = class {
|
|
|
1033
1051
|
}
|
|
1034
1052
|
onRoomStateReconciled(payload) {
|
|
1035
1053
|
const participants = payload.participants || [];
|
|
1036
|
-
const local = participants.find(
|
|
1054
|
+
const local = participants.find(
|
|
1055
|
+
(p) => p?.participant_id === this.currentParticipantId
|
|
1056
|
+
);
|
|
1037
1057
|
if (local) {
|
|
1038
1058
|
this.desiredAudioMuted = Boolean(local.audio_muted);
|
|
1039
1059
|
this.desiredVideoMuted = Boolean(local.video_muted);
|
|
@@ -1441,15 +1461,20 @@ var SFUClient = class {
|
|
|
1441
1461
|
}
|
|
1442
1462
|
}
|
|
1443
1463
|
async shareScreen() {
|
|
1444
|
-
if (!this.publisher)
|
|
1464
|
+
if (!this.publisher)
|
|
1445
1465
|
throw new Error("Publisher PeerConnection is not initialized");
|
|
1446
|
-
|
|
1447
|
-
if (!this.screenTransceiver || !this.screenSender) {
|
|
1466
|
+
if (!this.screenTransceiver || !this.screenSender)
|
|
1448
1467
|
throw new Error("Screen transceiver is not initialized");
|
|
1468
|
+
const existing = this.screenStream;
|
|
1469
|
+
const existingTrack = this.screenSender.track;
|
|
1470
|
+
if (existing || existingTrack && existingTrack.readyState === "live") {
|
|
1471
|
+
return existing;
|
|
1449
1472
|
}
|
|
1450
|
-
|
|
1451
|
-
|
|
1473
|
+
try {
|
|
1474
|
+
await this.screenSender.replaceTrack(null);
|
|
1475
|
+
} catch {
|
|
1452
1476
|
}
|
|
1477
|
+
this.screenTransceiver.direction = "inactive";
|
|
1453
1478
|
const screenStream = await navigator.mediaDevices.getDisplayMedia({
|
|
1454
1479
|
video: true,
|
|
1455
1480
|
audio: false
|
|
@@ -1459,29 +1484,22 @@ var SFUClient = class {
|
|
|
1459
1484
|
screenStream.getTracks().forEach((track) => track.stop());
|
|
1460
1485
|
throw new Error("Screen share returned no video track");
|
|
1461
1486
|
}
|
|
1487
|
+
const generation = ++this.screenShareGeneration;
|
|
1462
1488
|
this.screenStream = screenStream;
|
|
1463
1489
|
try {
|
|
1464
1490
|
await this.screenSender.replaceTrack(screenTrack);
|
|
1465
1491
|
this.screenTransceiver.direction = "sendonly";
|
|
1492
|
+
this.send({ type: "start_screen_share" });
|
|
1466
1493
|
const offer = await this.publisher.createOffer();
|
|
1467
1494
|
await this.publisher.setLocalDescription(offer);
|
|
1468
1495
|
this.send({
|
|
1469
1496
|
type: "publish_offer",
|
|
1470
|
-
payload: {
|
|
1471
|
-
revision: ++this.publisherRevision,
|
|
1472
|
-
sdp: offer.sdp
|
|
1473
|
-
}
|
|
1497
|
+
payload: { revision: ++this.publisherRevision, sdp: offer.sdp }
|
|
1474
1498
|
});
|
|
1475
|
-
this.send({ type: "start_screen_share" });
|
|
1476
1499
|
screenTrack.onended = () => {
|
|
1500
|
+
if (generation !== this.screenShareGeneration) return;
|
|
1477
1501
|
void this.stopScreenShare();
|
|
1478
1502
|
};
|
|
1479
|
-
console.info("[publisher] Screen track attached", {
|
|
1480
|
-
screenTrackId: screenTrack.id,
|
|
1481
|
-
cameraTrackId: this.videoSender?.track?.id,
|
|
1482
|
-
screenMid: this.screenTransceiver.mid,
|
|
1483
|
-
cameraMid: this.cameraTransceiver?.mid
|
|
1484
|
-
});
|
|
1485
1503
|
return this.screenStream;
|
|
1486
1504
|
} catch (error) {
|
|
1487
1505
|
try {
|
|
@@ -1499,38 +1517,34 @@ var SFUClient = class {
|
|
|
1499
1517
|
}
|
|
1500
1518
|
}
|
|
1501
1519
|
async stopScreenShare() {
|
|
1502
|
-
|
|
1503
|
-
const
|
|
1504
|
-
if (
|
|
1520
|
+
const stream = this.screenStream;
|
|
1521
|
+
const senderTrack = this.screenSender?.track || null;
|
|
1522
|
+
if (!stream && !senderTrack) return;
|
|
1523
|
+
++this.screenShareGeneration;
|
|
1524
|
+
if (senderTrack) senderTrack.onended = null;
|
|
1505
1525
|
try {
|
|
1506
1526
|
await this.screenSender?.replaceTrack(null);
|
|
1507
1527
|
} catch (error) {
|
|
1508
1528
|
this.onError(error);
|
|
1509
1529
|
}
|
|
1510
|
-
if (this.screenTransceiver)
|
|
1511
|
-
this.screenTransceiver.direction = "inactive";
|
|
1512
|
-
}
|
|
1513
|
-
this.send({ type: "stop_screen_share" });
|
|
1530
|
+
if (this.screenTransceiver) this.screenTransceiver.direction = "inactive";
|
|
1514
1531
|
try {
|
|
1515
1532
|
const offer = await this.publisher?.createOffer();
|
|
1516
1533
|
if (offer && this.publisher) {
|
|
1517
1534
|
await this.publisher.setLocalDescription(offer);
|
|
1518
1535
|
this.send({
|
|
1519
1536
|
type: "publish_offer",
|
|
1520
|
-
payload: {
|
|
1521
|
-
revision: ++this.publisherRevision,
|
|
1522
|
-
sdp: offer.sdp
|
|
1523
|
-
}
|
|
1537
|
+
payload: { revision: ++this.publisherRevision, sdp: offer.sdp }
|
|
1524
1538
|
});
|
|
1525
1539
|
}
|
|
1526
1540
|
} catch (error) {
|
|
1527
1541
|
this.onError(error);
|
|
1528
1542
|
}
|
|
1529
|
-
this.
|
|
1543
|
+
this.send({ type: "stop_screen_share" });
|
|
1544
|
+
stream?.getTracks().forEach((track) => track.stop());
|
|
1530
1545
|
this.screenStream = null;
|
|
1531
|
-
if (this.currentParticipantId)
|
|
1546
|
+
if (this.currentParticipantId)
|
|
1532
1547
|
this.onScreenShareStopped(this.currentParticipantId);
|
|
1533
|
-
}
|
|
1534
1548
|
}
|
|
1535
1549
|
muteAudio(muted) {
|
|
1536
1550
|
this.desiredAudioMuted = muted;
|
|
@@ -1633,6 +1647,14 @@ var SFUClient = class {
|
|
|
1633
1647
|
);
|
|
1634
1648
|
return true;
|
|
1635
1649
|
}
|
|
1650
|
+
sendReaction(reaction) {
|
|
1651
|
+
this.send({
|
|
1652
|
+
type: "send_reaction",
|
|
1653
|
+
payload: {
|
|
1654
|
+
reaction
|
|
1655
|
+
}
|
|
1656
|
+
});
|
|
1657
|
+
}
|
|
1636
1658
|
removeRemoteParticipant(participantId) {
|
|
1637
1659
|
const stream = this.remoteStreams.get(participantId);
|
|
1638
1660
|
if (stream) {
|
|
@@ -2051,7 +2073,9 @@ var VideoSDKCore = class {
|
|
|
2051
2073
|
// ADMISSION CONTROL
|
|
2052
2074
|
onRoomUpdate: (payload) => {
|
|
2053
2075
|
const participants = payload?.participants || [];
|
|
2054
|
-
const local = participants.find(
|
|
2076
|
+
const local = participants.find(
|
|
2077
|
+
(p) => p?.participant_id === this.myId
|
|
2078
|
+
);
|
|
2055
2079
|
if (local) {
|
|
2056
2080
|
const media = this.state.localParticipant?.media;
|
|
2057
2081
|
this.state.updateLocalParticipant({
|
|
@@ -2074,7 +2098,8 @@ var VideoSDKCore = class {
|
|
|
2074
2098
|
});
|
|
2075
2099
|
}
|
|
2076
2100
|
if (local.screen_sharing) this.state.setPresenterId(this.myId);
|
|
2077
|
-
else if (this.state.presenterId === this.myId)
|
|
2101
|
+
else if (this.state.presenterId === this.myId)
|
|
2102
|
+
this.state.setPresenterId(null);
|
|
2078
2103
|
}
|
|
2079
2104
|
const presenter = participants.find((p) => p?.screen_sharing);
|
|
2080
2105
|
if (presenter) this.state.setPresenterId(presenter.participant_id);
|
|
@@ -2505,7 +2530,7 @@ var VideoSDKCore = class {
|
|
|
2505
2530
|
media: {
|
|
2506
2531
|
isScreenSharing: true,
|
|
2507
2532
|
screenStream: this.screenStream,
|
|
2508
|
-
screenTrack: this.screenStream
|
|
2533
|
+
screenTrack: this.screenStream?.getVideoTracks()[0]
|
|
2509
2534
|
}
|
|
2510
2535
|
});
|
|
2511
2536
|
return this.screenStream;
|
|
@@ -2570,6 +2595,13 @@ var VideoSDKCore = class {
|
|
|
2570
2595
|
target: payload.target ?? null
|
|
2571
2596
|
});
|
|
2572
2597
|
}
|
|
2598
|
+
sendReaction(reaction) {
|
|
2599
|
+
if (!this.sfuClient) {
|
|
2600
|
+
console.warn("SFU Client not connected");
|
|
2601
|
+
return;
|
|
2602
|
+
}
|
|
2603
|
+
this.sfuClient.sendReaction(reaction);
|
|
2604
|
+
}
|
|
2573
2605
|
// CLEANUP
|
|
2574
2606
|
cleanupRemoteParticipant(participantId) {
|
|
2575
2607
|
this.activeSpeakerDetector.removeParticipant(participantId);
|
|
@@ -2656,6 +2688,7 @@ var MeetingProvider = ({
|
|
|
2656
2688
|
const trackStateListeners = (0, import_react2.useRef)(/* @__PURE__ */ new Set());
|
|
2657
2689
|
const recordingStartedListeners = (0, import_react2.useRef)(/* @__PURE__ */ new Set());
|
|
2658
2690
|
const recordingStoppedListeners = (0, import_react2.useRef)(/* @__PURE__ */ new Set());
|
|
2691
|
+
const reactionListeners = (0, import_react2.useRef)(/* @__PURE__ */ new Set());
|
|
2659
2692
|
const activeSpeakerListeners = (0, import_react2.useRef)(
|
|
2660
2693
|
/* @__PURE__ */ new Set()
|
|
2661
2694
|
);
|
|
@@ -2685,6 +2718,9 @@ var MeetingProvider = ({
|
|
|
2685
2718
|
},
|
|
2686
2719
|
onRecordingStopped: (recording) => {
|
|
2687
2720
|
recordingStoppedListeners.current.forEach((fn) => fn(recording));
|
|
2721
|
+
},
|
|
2722
|
+
onReaction: (reaction) => {
|
|
2723
|
+
reactionListeners.current.forEach((fn) => fn(reaction));
|
|
2688
2724
|
}
|
|
2689
2725
|
}
|
|
2690
2726
|
);
|
|
@@ -2731,6 +2767,7 @@ var MeetingProvider = ({
|
|
|
2731
2767
|
startScreenShare: sdk.startScreenShare.bind(sdk),
|
|
2732
2768
|
stopScreenShare: sdk.stopScreenShare.bind(sdk),
|
|
2733
2769
|
sendMessage: sdk.sendChatMessage.bind(sdk),
|
|
2770
|
+
sendReaction: sdk.sendReaction.bind(sdk),
|
|
2734
2771
|
room: sdk.getMeeting(),
|
|
2735
2772
|
localParticipant,
|
|
2736
2773
|
participants,
|
|
@@ -2787,6 +2824,10 @@ var MeetingProvider = ({
|
|
|
2787
2824
|
recordingStoppedListeners.current.add(cb);
|
|
2788
2825
|
return () => recordingStoppedListeners.current.delete(cb);
|
|
2789
2826
|
},
|
|
2827
|
+
onReaction: (cb) => {
|
|
2828
|
+
reactionListeners.current.add(cb);
|
|
2829
|
+
return () => reactionListeners.current.delete(cb);
|
|
2830
|
+
},
|
|
2790
2831
|
onActiveSpeakersChanged: (cb) => {
|
|
2791
2832
|
activeSpeakerListeners.current.add(cb);
|
|
2792
2833
|
return () => {
|
|
@@ -2883,6 +2924,10 @@ var useMeeting = (handlers) => {
|
|
|
2883
2924
|
if (!handlers?.onRecordingStopped) return;
|
|
2884
2925
|
return ctx.onRecordingStopped(handlers.onRecordingStopped);
|
|
2885
2926
|
}, [handlers?.onRecordingStopped]);
|
|
2927
|
+
(0, import_react4.useEffect)(() => {
|
|
2928
|
+
if (!handlers?.onReaction) return;
|
|
2929
|
+
return ctx.onReaction(handlers.onReaction);
|
|
2930
|
+
}, [handlers?.onReaction]);
|
|
2886
2931
|
const { sdk: _, ...publicApi } = ctx;
|
|
2887
2932
|
return publicApi;
|
|
2888
2933
|
};
|