@defcomm/meetingsdk 0.6.8 → 0.7.1

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 CHANGED
@@ -421,10 +421,26 @@ Toggle the local camera:
421
421
  ```tsx
422
422
  const { toggleCam } = useMeeting();
423
423
 
424
- <button onClick={toggleCam}>Toggle camera</button>;
425
- ```
426
-
427
- The local participant state exposes `media.micEnabled` and `media.camEnabled`, so the button can reflect the current state.
424
+ <button
425
+ onClick={() =>
426
+ void toggleCam().catch((error) => {
427
+ console.error("Unable to toggle camera", error);
428
+ })
429
+ }
430
+ >
431
+ Toggle camera
432
+ </button>;
433
+ ```
434
+
435
+ Camera-off is a privacy action: the SDK detaches and stops the active camera
436
+ `MediaStreamTrack`, releasing the browser's camera capture. It does not merely
437
+ set `track.enabled = false`. Turning the camera back on explicitly requests a
438
+ new camera track and may trigger the browser's permission prompt if access was
439
+ revoked. Joining with `videoMuted: true` does not request camera access at all.
440
+
441
+ The local participant state exposes `media.micEnabled` and `media.camEnabled`,
442
+ so the button can reflect the current state. `toggleCam()` returns a Promise;
443
+ handle errors if camera permission is denied or the device is unavailable.
428
444
 
429
445
  ---
430
446
 
@@ -811,7 +827,7 @@ export function Meeting() {
811
827
  <div>
812
828
  <button onClick={() => void join()}>Join</button>
813
829
  <button onClick={() => toggleMic()}>Mic</button>
814
- <button onClick={() => toggleCam()}>Camera</button>
830
+ <button onClick={() => void toggleCam()}>Camera</button>
815
831
  <button onClick={() => void startScreenShare()}>
816
832
  Share screen
817
833
  </button>
package/dist/index.d.mts CHANGED
@@ -112,7 +112,7 @@ type Participant = {
112
112
  type ParticipantMedia = {
113
113
  stream?: MediaStream | null;
114
114
  screenStream?: MediaStream | null;
115
- cameraTrack?: MediaStreamTrack;
115
+ cameraTrack?: MediaStreamTrack | null;
116
116
  screenTrack?: MediaStreamTrack;
117
117
  audioTrack?: MediaStreamTrack;
118
118
  micEnabled: boolean;
@@ -315,6 +315,9 @@ declare class VideoSDKCore {
315
315
  private screenStream;
316
316
  private isScreenSharing;
317
317
  private participantName;
318
+ private cameraDeviceId?;
319
+ private cameraEnabled;
320
+ private cameraToggleInProgress;
318
321
  readonly state: MeetingState;
319
322
  private intentionalDisconnect;
320
323
  private remoteStreams;
@@ -325,6 +328,13 @@ declare class VideoSDKCore {
325
328
  private emitError;
326
329
  constructor(options: VideoSDKCoreOptions, events?: Events, apiBase?: string, wsBase?: string);
327
330
  initLocal(video: HTMLVideoElement, name: string): Promise<void>;
331
+ private hasLiveCameraTrack;
332
+ private getLiveCameraTrack;
333
+ /**
334
+ * Stop every locally captured camera track and remove it from the stream.
335
+ * Track.enabled=false only emits black frames; stop() releases camera capture.
336
+ */
337
+ private stopCameraCapture;
328
338
  private updateLocalMedia;
329
339
  createRoom(input: {
330
340
  name: string;
@@ -339,6 +349,13 @@ declare class VideoSDKCore {
339
349
  getMeetingSummary(roomCode: string, sessionId: string): Promise<{
340
350
  summary: MeetingSummary | null;
341
351
  }>;
352
+ private acquireOptionalLocalMedia;
353
+ private acquireCameraTrack;
354
+ /**
355
+ * Wakes the active-speaker Web Audio pipeline. Call this from a user gesture
356
+ * whenever possible (Join, first click inside the meeting, etc.).
357
+ */
358
+ resumeActiveSpeaker(): Promise<boolean>;
342
359
  joinMeeting(config: Omit<MeetingConfig, "participantId">): Promise<void>;
343
360
  private connect;
344
361
  private createSFUClient;
@@ -361,7 +378,7 @@ declare class VideoSDKCore {
361
378
  selectCamera(deviceId: string): Promise<MediaStreamTrack>;
362
379
  selectMicrophone(deviceId: string): Promise<MediaStreamTrack>;
363
380
  toggleMic(): void;
364
- toggleCam(): void;
381
+ toggleCam(): Promise<void>;
365
382
  startScreenShare(): Promise<MediaStream | null>;
366
383
  stopScreenShare(): Promise<void>;
367
384
  startRecording(): Promise<void>;
@@ -426,7 +443,8 @@ type MeetingContextValue = {
426
443
  summary: MeetingSummary | null;
427
444
  }>;
428
445
  toggleMic: () => void;
429
- toggleCam: () => void;
446
+ toggleCam: () => Promise<void>;
447
+ resumeActiveSpeaker: () => Promise<boolean>;
430
448
  startScreenShare: () => Promise<MediaStream | null>;
431
449
  stopScreenShare: () => void;
432
450
  sendMessage: (input: ChatInput) => void;
@@ -523,7 +541,8 @@ declare const useMeeting: (handlers?: {
523
541
  summary: MeetingSummary | null;
524
542
  }>;
525
543
  toggleMic: () => void;
526
- toggleCam: () => void;
544
+ toggleCam: () => Promise<void>;
545
+ resumeActiveSpeaker: () => Promise<boolean>;
527
546
  startScreenShare: () => Promise<MediaStream | null>;
528
547
  stopScreenShare: () => void;
529
548
  sendMessage: (input: ChatInput) => void;
@@ -630,6 +649,15 @@ interface ActiveSpeakerDetectorOptions {
630
649
  releaseMs?: number;
631
650
  onActiveSpeakersChanged?: (participantIds: string[]) => void;
632
651
  }
652
+ /**
653
+ * Detects currently speaking participants from the actual audio tracks that
654
+ * are being received/published by WebRTC.
655
+ *
656
+ * The AudioContext is explicitly resumable so an application can wake it from
657
+ * a real user gesture (for example, the Join button). This matters in browsers
658
+ * that create Web Audio contexts in the "suspended" state until the page has
659
+ * received user interaction.
660
+ */
633
661
  declare class ActiveSpeakerDetector {
634
662
  private audioContext;
635
663
  private speakers;
@@ -642,7 +670,12 @@ declare class ActiveSpeakerDetector {
642
670
  private lastEmitted;
643
671
  constructor(options?: ActiveSpeakerDetectorOptions);
644
672
  private ensureAudioContext;
645
- resume(): Promise<void>;
673
+ /**
674
+ * Create/wake the Web Audio context. Call this from a user gesture when
675
+ * possible. Returns true when the context is running after the call.
676
+ */
677
+ resume(): Promise<boolean>;
678
+ getAudioContextState(): AudioContextState | "unavailable";
646
679
  addTrack(participantId: string, track: MediaStreamTrack): void;
647
680
  removeParticipant(participantId: string): void;
648
681
  removeTrack(track: MediaStreamTrack): void;
@@ -650,6 +683,7 @@ declare class ActiveSpeakerDetector {
650
683
  start(): void;
651
684
  stop(): void;
652
685
  private sample;
686
+ private getActiveSpeakers;
653
687
  private getActiveSpeakerIds;
654
688
  private emitIfChanged;
655
689
  destroy(): Promise<void>;
package/dist/index.d.ts CHANGED
@@ -112,7 +112,7 @@ type Participant = {
112
112
  type ParticipantMedia = {
113
113
  stream?: MediaStream | null;
114
114
  screenStream?: MediaStream | null;
115
- cameraTrack?: MediaStreamTrack;
115
+ cameraTrack?: MediaStreamTrack | null;
116
116
  screenTrack?: MediaStreamTrack;
117
117
  audioTrack?: MediaStreamTrack;
118
118
  micEnabled: boolean;
@@ -315,6 +315,9 @@ declare class VideoSDKCore {
315
315
  private screenStream;
316
316
  private isScreenSharing;
317
317
  private participantName;
318
+ private cameraDeviceId?;
319
+ private cameraEnabled;
320
+ private cameraToggleInProgress;
318
321
  readonly state: MeetingState;
319
322
  private intentionalDisconnect;
320
323
  private remoteStreams;
@@ -325,6 +328,13 @@ declare class VideoSDKCore {
325
328
  private emitError;
326
329
  constructor(options: VideoSDKCoreOptions, events?: Events, apiBase?: string, wsBase?: string);
327
330
  initLocal(video: HTMLVideoElement, name: string): Promise<void>;
331
+ private hasLiveCameraTrack;
332
+ private getLiveCameraTrack;
333
+ /**
334
+ * Stop every locally captured camera track and remove it from the stream.
335
+ * Track.enabled=false only emits black frames; stop() releases camera capture.
336
+ */
337
+ private stopCameraCapture;
328
338
  private updateLocalMedia;
329
339
  createRoom(input: {
330
340
  name: string;
@@ -339,6 +349,13 @@ declare class VideoSDKCore {
339
349
  getMeetingSummary(roomCode: string, sessionId: string): Promise<{
340
350
  summary: MeetingSummary | null;
341
351
  }>;
352
+ private acquireOptionalLocalMedia;
353
+ private acquireCameraTrack;
354
+ /**
355
+ * Wakes the active-speaker Web Audio pipeline. Call this from a user gesture
356
+ * whenever possible (Join, first click inside the meeting, etc.).
357
+ */
358
+ resumeActiveSpeaker(): Promise<boolean>;
342
359
  joinMeeting(config: Omit<MeetingConfig, "participantId">): Promise<void>;
343
360
  private connect;
344
361
  private createSFUClient;
@@ -361,7 +378,7 @@ declare class VideoSDKCore {
361
378
  selectCamera(deviceId: string): Promise<MediaStreamTrack>;
362
379
  selectMicrophone(deviceId: string): Promise<MediaStreamTrack>;
363
380
  toggleMic(): void;
364
- toggleCam(): void;
381
+ toggleCam(): Promise<void>;
365
382
  startScreenShare(): Promise<MediaStream | null>;
366
383
  stopScreenShare(): Promise<void>;
367
384
  startRecording(): Promise<void>;
@@ -426,7 +443,8 @@ type MeetingContextValue = {
426
443
  summary: MeetingSummary | null;
427
444
  }>;
428
445
  toggleMic: () => void;
429
- toggleCam: () => void;
446
+ toggleCam: () => Promise<void>;
447
+ resumeActiveSpeaker: () => Promise<boolean>;
430
448
  startScreenShare: () => Promise<MediaStream | null>;
431
449
  stopScreenShare: () => void;
432
450
  sendMessage: (input: ChatInput) => void;
@@ -523,7 +541,8 @@ declare const useMeeting: (handlers?: {
523
541
  summary: MeetingSummary | null;
524
542
  }>;
525
543
  toggleMic: () => void;
526
- toggleCam: () => void;
544
+ toggleCam: () => Promise<void>;
545
+ resumeActiveSpeaker: () => Promise<boolean>;
527
546
  startScreenShare: () => Promise<MediaStream | null>;
528
547
  stopScreenShare: () => void;
529
548
  sendMessage: (input: ChatInput) => void;
@@ -630,6 +649,15 @@ interface ActiveSpeakerDetectorOptions {
630
649
  releaseMs?: number;
631
650
  onActiveSpeakersChanged?: (participantIds: string[]) => void;
632
651
  }
652
+ /**
653
+ * Detects currently speaking participants from the actual audio tracks that
654
+ * are being received/published by WebRTC.
655
+ *
656
+ * The AudioContext is explicitly resumable so an application can wake it from
657
+ * a real user gesture (for example, the Join button). This matters in browsers
658
+ * that create Web Audio contexts in the "suspended" state until the page has
659
+ * received user interaction.
660
+ */
633
661
  declare class ActiveSpeakerDetector {
634
662
  private audioContext;
635
663
  private speakers;
@@ -642,7 +670,12 @@ declare class ActiveSpeakerDetector {
642
670
  private lastEmitted;
643
671
  constructor(options?: ActiveSpeakerDetectorOptions);
644
672
  private ensureAudioContext;
645
- resume(): Promise<void>;
673
+ /**
674
+ * Create/wake the Web Audio context. Call this from a user gesture when
675
+ * possible. Returns true when the context is running after the call.
676
+ */
677
+ resume(): Promise<boolean>;
678
+ getAudioContextState(): AudioContextState | "unavailable";
646
679
  addTrack(participantId: string, track: MediaStreamTrack): void;
647
680
  removeParticipant(participantId: string): void;
648
681
  removeTrack(track: MediaStreamTrack): void;
@@ -650,6 +683,7 @@ declare class ActiveSpeakerDetector {
650
683
  start(): void;
651
684
  stop(): void;
652
685
  private sample;
686
+ private getActiveSpeakers;
653
687
  private getActiveSpeakerIds;
654
688
  private emitIfChanged;
655
689
  destroy(): Promise<void>;