@whereby.com/media 9.6.0 → 9.7.0

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.cjs CHANGED
@@ -2498,18 +2498,19 @@ function getMediaConstraints({ disableAEC, disableAGC, hd, lax, lowDataMode, pre
2498
2498
  return constraints;
2499
2499
  }
2500
2500
  function getConstraints({ devices, videoId, audioId, options, type = "ideal" }) {
2501
- const audioDevices = devices.filter((d) => d.kind === "audioinput");
2502
- const videoDevices = devices.filter((d) => d.kind === "videoinput");
2503
- const useDefaultAudio = !audioId || !audioDevices.some((d) => d.deviceId === audioId);
2504
- const useDefaultVideo = !videoId || !videoDevices.some((d) => d.deviceId === videoId);
2501
+ const strict = !!devices;
2502
+ const audioDevices = devices === null || devices === void 0 ? void 0 : devices.filter((d) => d.kind === "audioinput");
2503
+ const videoDevices = devices === null || devices === void 0 ? void 0 : devices.filter((d) => d.kind === "videoinput");
2504
+ const useDefaultAudio = !audioId || (strict && !(audioDevices === null || audioDevices === void 0 ? void 0 : audioDevices.some((d) => d.deviceId === audioId)));
2505
+ const useDefaultVideo = !videoId || (strict && !(videoDevices === null || videoDevices === void 0 ? void 0 : videoDevices.some((d) => d.deviceId === videoId)));
2505
2506
  const constraints = getMediaConstraints(Object.assign({ preferredDeviceIds: {
2506
2507
  audioId: useDefaultAudio ? null : { [type]: audioId },
2507
2508
  videoId: useDefaultVideo ? null : { [type]: videoId },
2508
2509
  } }, options));
2509
- if (audioId === false || !audioDevices.length) {
2510
+ if (audioId === false || (strict && !(audioDevices === null || audioDevices === void 0 ? void 0 : audioDevices.length))) {
2510
2511
  delete constraints.audio;
2511
2512
  }
2512
- if (videoId === false || !videoDevices.length) {
2513
+ if (videoId === false || (strict && !(videoDevices === null || videoDevices === void 0 ? void 0 : videoDevices.length))) {
2513
2514
  delete constraints.video;
2514
2515
  }
2515
2516
  return constraints;
@@ -4486,6 +4487,13 @@ class VegaRtcManager {
4486
4487
  });
4487
4488
  this._networkIsDetectedUpBySignal = false;
4488
4489
  this._cpuOveruseDetected = false;
4490
+ this._sfuZombie = {
4491
+ offlineDetectedAt: null,
4492
+ onBrowserOffline: () => this._sfuZombieOnOffline(),
4493
+ };
4494
+ if (typeof window !== "undefined") {
4495
+ window.addEventListener("offline", this._sfuZombie.onBrowserOffline);
4496
+ }
4489
4497
  this.analytics = {
4490
4498
  vegaRequestTimeout: 0,
4491
4499
  vegaUnknownResponse: 0,
@@ -4509,6 +4517,9 @@ class VegaRtcManager {
4509
4517
  numIceConnected: 0,
4510
4518
  numIceDisconnected: 0,
4511
4519
  numIceFailed: 0,
4520
+ sfuMsFromOfflineToClose: 0,
4521
+ sfuOfflineWhileConnectedCount: 0,
4522
+ sfuOfflineToCloseCount: 0,
4512
4523
  };
4513
4524
  }
4514
4525
  _updateAndScheduleMediaServersRefresh({ iceServers, turnServers, sfuServer, mediaserverConfigTtlSeconds, }) {
@@ -4563,6 +4574,32 @@ class VegaRtcManager {
4563
4574
  (_a = this._vegaConnectionManager) === null || _a === void 0 ? void 0 : _a.networkIsPossiblyDown();
4564
4575
  }
4565
4576
  }
4577
+ _sfuZombieOnOffline() {
4578
+ var _a, _b, _c, _d;
4579
+ if (!this._isConnectingOrConnected || this._sfuZombie.offlineDetectedAt !== null) {
4580
+ return;
4581
+ }
4582
+ this._sfuZombie.offlineDetectedAt = Date.now();
4583
+ this.analytics.sfuOfflineWhileConnectedCount++;
4584
+ rtcStats.sendEvent("SfuOfflineWhileConnected", {
4585
+ sfuWsReadyState: (_b = (_a = this._vegaConnection) === null || _a === void 0 ? void 0 : _a.socket) === null || _b === void 0 ? void 0 : _b.readyState,
4586
+ sendTransportState: (_c = this._sendTransport) === null || _c === void 0 ? void 0 : _c.connectionState,
4587
+ recvTransportState: (_d = this._receiveTransport) === null || _d === void 0 ? void 0 : _d.connectionState,
4588
+ });
4589
+ }
4590
+ _sfuZombieReset() {
4591
+ this._sfuZombie.offlineDetectedAt = null;
4592
+ }
4593
+ _sfuZombieOnClose() {
4594
+ let msFromOfflineToClose;
4595
+ if (this._reconnect && this._sfuZombie.offlineDetectedAt !== null) {
4596
+ msFromOfflineToClose = Date.now() - this._sfuZombie.offlineDetectedAt;
4597
+ this.analytics.sfuMsFromOfflineToClose += msFromOfflineToClose;
4598
+ this.analytics.sfuOfflineToCloseCount++;
4599
+ }
4600
+ this._sfuZombieReset();
4601
+ return msFromOfflineToClose;
4602
+ }
4566
4603
  setupSocketListeners() {
4567
4604
  this._socketListenerDeregisterFunctions.push(() => this._clearMediaServersRefresh(), this._serverSocket.on(PROTOCOL_RESPONSES.MEDIASERVER_CONFIG, (data) => {
4568
4605
  if (data.error) {
@@ -4659,7 +4696,8 @@ class VegaRtcManager {
4659
4696
  }
4660
4697
  this._qualityMonitor.close();
4661
4698
  this._emitToPWA(rtcManagerEvents.SFU_CONNECTION_CLOSED);
4662
- rtcStats.sendEvent("SfuConnectionClosed", {});
4699
+ const msFromOfflineToClose = this._sfuZombieOnClose();
4700
+ rtcStats.sendEvent("SfuConnectionClosed", { msFromOfflineToClose });
4663
4701
  }
4664
4702
  _join() {
4665
4703
  return __awaiter(this, void 0, void 0, function* () {
@@ -5639,6 +5677,10 @@ class VegaRtcManager {
5639
5677
  clearTimeout(this._reconnectTimeOut);
5640
5678
  this._reconnectTimeOut = null;
5641
5679
  }
5680
+ this._sfuZombieReset();
5681
+ if (typeof window !== "undefined") {
5682
+ window.removeEventListener("offline", this._sfuZombie.onBrowserOffline);
5683
+ }
5642
5684
  this._socketListenerDeregisterFunctions.forEach((func) => {
5643
5685
  func();
5644
5686
  });
@@ -7291,6 +7333,106 @@ function replaceTracksInStream(stream, newStream, only) {
7291
7333
  replacedTracks.forEach((track) => stream.removeTrack(track));
7292
7334
  return replacedTracks;
7293
7335
  }
7336
+ function createGetUserMediaAttempts() {
7337
+ const attempts = [];
7338
+ const attempt = (c) => __awaiter(this, void 0, void 0, function* () {
7339
+ var _a, _b;
7340
+ try {
7341
+ const s = yield getUserMedia(c);
7342
+ attempts.push({ constraints: c, outcome: { ok: true } });
7343
+ return s;
7344
+ }
7345
+ catch (e) {
7346
+ attempts.push({
7347
+ constraints: c,
7348
+ outcome: Object.assign({ ok: false, errorName: (_a = e === null || e === void 0 ? void 0 : e.name) !== null && _a !== void 0 ? _a : "UnknownError", errorMessage: (_b = e === null || e === void 0 ? void 0 : e.message) !== null && _b !== void 0 ? _b : String(e) }, ((e === null || e === void 0 ? void 0 : e.constraint) && { constraint: e.constraint })),
7349
+ });
7350
+ throw e;
7351
+ }
7352
+ });
7353
+ const attachAttempts = (err) => {
7354
+ if (err)
7355
+ err.attempts = attempts;
7356
+ return err;
7357
+ };
7358
+ return { attempts, attempt, attachAttempts };
7359
+ }
7360
+ function getInitialStream(constraintOpt) {
7361
+ return __awaiter(this, void 0, void 0, function* () {
7362
+ const { attempts, attempt, attachAttempts } = createGetUserMediaAttempts();
7363
+ let error;
7364
+ let stream;
7365
+ const opts = Object.assign(Object.assign({}, constraintOpt), { type: "exact" });
7366
+ try {
7367
+ stream = yield attempt(getConstraints(opts));
7368
+ return {
7369
+ stream,
7370
+ attempts,
7371
+ };
7372
+ }
7373
+ catch (e) {
7374
+ logger.error(e);
7375
+ error = e;
7376
+ }
7377
+ const acquireOneKind = (targetConstraint) => __awaiter(this, void 0, void 0, function* () {
7378
+ const retryOpts = Object.assign(Object.assign({}, opts), { options: Object.assign({}, opts.options) });
7379
+ let stream;
7380
+ let lastError = error;
7381
+ const ignoredConstraint = targetConstraint === "videoId" ? "audioId" : "videoId";
7382
+ if (retryOpts[ignoredConstraint] !== false) {
7383
+ retryOpts[ignoredConstraint] = false;
7384
+ try {
7385
+ stream = yield attempt(getConstraints(retryOpts));
7386
+ return stream;
7387
+ }
7388
+ catch (e) {
7389
+ logger.error(e);
7390
+ lastError = e;
7391
+ }
7392
+ }
7393
+ if ((lastError === null || lastError === void 0 ? void 0 : lastError.name) === "NotAllowedError") {
7394
+ return;
7395
+ }
7396
+ if (retryOpts[targetConstraint]) {
7397
+ retryOpts[targetConstraint] = null;
7398
+ try {
7399
+ stream = yield attempt(getConstraints(retryOpts));
7400
+ return stream;
7401
+ }
7402
+ catch (e) {
7403
+ logger.error(e);
7404
+ }
7405
+ }
7406
+ try {
7407
+ retryOpts.options.lax = true;
7408
+ stream = yield attempt(getConstraints(retryOpts));
7409
+ return stream;
7410
+ }
7411
+ catch (e) {
7412
+ logger.error(e);
7413
+ }
7414
+ });
7415
+ if (opts.videoId !== false) {
7416
+ stream = yield acquireOneKind("videoId");
7417
+ }
7418
+ if (opts.audioId !== false) {
7419
+ if (!stream) {
7420
+ stream = yield acquireOneKind("audioId");
7421
+ }
7422
+ else {
7423
+ const audioOnlyStream = yield acquireOneKind("audioId");
7424
+ if (audioOnlyStream) {
7425
+ const audioTrack = audioOnlyStream.getAudioTracks()[0];
7426
+ stream.addTrack(audioTrack);
7427
+ }
7428
+ }
7429
+ }
7430
+ if (!stream) {
7431
+ throw attachAttempts(error !== null && error !== void 0 ? error : new Error("Unknown error"));
7432
+ }
7433
+ return { error, stream, attempts };
7434
+ });
7435
+ }
7294
7436
  function getStream(constraintOpt_1) {
7295
7437
  return __awaiter(this, arguments, void 0, function* (constraintOpt, { replaceStream, fallback = true } = {}) {
7296
7438
  var _a;
@@ -7298,25 +7440,10 @@ function getStream(constraintOpt_1) {
7298
7440
  let newConstraints;
7299
7441
  let retryConstraintOpt;
7300
7442
  let stream = null;
7301
- const attempts = [];
7443
+ const { attempts, attempt, attachAttempts } = createGetUserMediaAttempts();
7302
7444
  const only = (constraintOpt.audioId === false && "video") || (constraintOpt.videoId === false && "audio");
7303
7445
  const stopTracks = isMobile || only !== "video";
7304
7446
  const constraints = getConstraints(constraintOpt);
7305
- const attempt = (c) => __awaiter(this, void 0, void 0, function* () {
7306
- var _a, _b;
7307
- try {
7308
- const s = yield getUserMedia(c);
7309
- attempts.push({ constraints: c, outcome: { ok: true } });
7310
- return s;
7311
- }
7312
- catch (e) {
7313
- attempts.push({
7314
- constraints: c,
7315
- outcome: Object.assign({ ok: false, errorName: (_a = e === null || e === void 0 ? void 0 : e.name) !== null && _a !== void 0 ? _a : "UnknownError", errorMessage: (_b = e === null || e === void 0 ? void 0 : e.message) !== null && _b !== void 0 ? _b : String(e) }, ((e === null || e === void 0 ? void 0 : e.constraint) && { constraint: e.constraint })),
7316
- });
7317
- throw e;
7318
- }
7319
- });
7320
7447
  const addDetails = (err, orgErr) => {
7321
7448
  if (err) {
7322
7449
  err.details = Object.assign({ constraints, constraint: err.constraint || (orgErr === null || orgErr === void 0 ? void 0 : orgErr.constraint), newConstraints,
@@ -7328,11 +7455,6 @@ function getStream(constraintOpt_1) {
7328
7455
  return new Error("Unknown error");
7329
7456
  }
7330
7457
  };
7331
- const attachAttempts = (err) => {
7332
- if (err)
7333
- err.attempts = attempts;
7334
- return err;
7335
- };
7336
7458
  const getSingleStream = (e) => __awaiter(this, void 0, void 0, function* () {
7337
7459
  if (constraints.audio && constraints.video) {
7338
7460
  try {
@@ -7606,6 +7728,7 @@ exports.getConstraints = getConstraints;
7606
7728
  exports.getCurrentPeerConnections = getCurrentPeerConnections;
7607
7729
  exports.getDeviceData = getDeviceData;
7608
7730
  exports.getDisplayMedia = getDisplayMedia;
7731
+ exports.getInitialStream = getInitialStream;
7609
7732
  exports.getIssuesAndMetrics = getIssuesAndMetrics;
7610
7733
  exports.getMediaConstraints = getMediaConstraints;
7611
7734
  exports.getMediaSettings = getMediaSettings;
package/dist/index.d.cts CHANGED
@@ -449,6 +449,9 @@ type VegaAnalytics = {
449
449
  numIceConnected: number;
450
450
  numIceDisconnected: number;
451
451
  numIceFailed: number;
452
+ sfuMsFromOfflineToClose: number;
453
+ sfuOfflineWhileConnectedCount: number;
454
+ sfuOfflineToCloseCount: number;
452
455
  };
453
456
 
454
457
  type VegaAnalyticMetric = keyof VegaAnalytics;
@@ -600,8 +603,13 @@ type GetMediaConstraintsOptions = {
600
603
  simulcast: boolean;
601
604
  widescreen: boolean;
602
605
  };
606
+ type GetInitialStreamOptions = {
607
+ videoId: false | string | null;
608
+ audioId: false | string | null;
609
+ options: Omit<GetMediaConstraintsOptions, "preferredDeviceIds">;
610
+ };
603
611
  type GetConstraintsOptions = {
604
- devices: MediaDeviceInfo[];
612
+ devices?: MediaDeviceInfo[];
605
613
  audioId?: boolean | string | null;
606
614
  videoId?: boolean | string | null;
607
615
  type?: "ideal" | "exact";
@@ -1384,6 +1392,7 @@ declare function getDeviceData({ audioTrack, videoTrack, devices, stoppedVideoTr
1384
1392
  }): GetDeviceDataResult;
1385
1393
  declare function stopStreamTracks(stream: MediaStream, only?: "audio" | "video" | false): void;
1386
1394
  declare function replaceTracksInStream(stream: MediaStream, newStream: MediaStream, only: "audio" | "video" | false): MediaStreamTrack[];
1395
+ declare function getInitialStream(constraintOpt: GetInitialStreamOptions): Promise<GetStreamResult>;
1387
1396
  declare function getStream(constraintOpt: GetConstraintsOptions, { replaceStream, fallback }?: GetStreamOptions): Promise<GetStreamResult>;
1388
1397
  declare function hasGetDisplayMedia(): boolean;
1389
1398
  declare function getDisplayMedia(constraints?: DisplayMediaStreamOptions, contentHint?: string): Promise<MediaStream>;
@@ -2025,12 +2034,19 @@ declare class VegaRtcManager implements RtcManager {
2025
2034
  _vegaConnectionManager?: ReturnType<typeof createVegaConnectionManager>;
2026
2035
  _networkIsDetectedUpBySignal: boolean;
2027
2036
  _cpuOveruseDetected: boolean;
2037
+ _sfuZombie: {
2038
+ offlineDetectedAt: number | null;
2039
+ onBrowserOffline: any;
2040
+ };
2028
2041
  analytics: VegaAnalytics;
2029
2042
  constructor({ selfId, room, emitter, serverSocket, webrtcProvider, features, eventClaim }: VegaRtcManagerOptions);
2030
2043
  _updateAndScheduleMediaServersRefresh({ iceServers, turnServers, sfuServer, mediaserverConfigTtlSeconds, }: SignalMediaServerConfig): void;
2031
2044
  _clearMediaServersRefresh(): void;
2032
2045
  _onNetworkIsDetectedUpBySignal(): void;
2033
2046
  _onNetworkIsDetectedPossiblyDownBySignal(): void;
2047
+ _sfuZombieOnOffline(): void;
2048
+ _sfuZombieReset(): void;
2049
+ _sfuZombieOnClose(): number | undefined;
2034
2050
  setupSocketListeners(): void;
2035
2051
  _emitScreenshareStarted(): void;
2036
2052
  _connect(): void;
@@ -2143,5 +2159,5 @@ declare class VegaRtcManager implements RtcManager {
2143
2159
  hasClient(clientId: string): boolean;
2144
2160
  }
2145
2161
 
2146
- export { ADDITIONAL_SCREEN_SHARE_SETTINGS, AUDIO_SETTINGS, BandwidthTester, CAMERA_STREAM_ID, EVENTS, FILE_SHARE_ERROR_CODES, KNOCK_MESSAGES, KalmanFilter, Logger, MEDIA_JITTER_BUFFER_TARGET, NoDevicesError, P2pRtcManager, PROTOCOL_ERRORS, PROTOCOL_EVENTS, PROTOCOL_REQUESTS, PROTOCOL_RESPONSES, RELAY_MESSAGES, ReconnectManager, RtcEventNames, RtcManagerDispatcher, SCREEN_SHARE_SETTINGS, SCREEN_SHARE_SIMULCAST_SETTINGS, STREAM_TYPES, ServerSocket, Session, SfuV2Parser, TYPES, VIDEO_SETTINGS_HD, VIDEO_SETTINGS_SD, VIDEO_SETTINGS_VP9, VIDEO_SETTINGS_VP9_LOW_BANDWIDTH, VegaConnection, VegaMediaQualityMonitor, VegaRtcManager, addAbsCaptureTimeExtMap, addExtMap, assert, buildDeviceList, calculateStd, captureAudioSsrcMetrics, captureCandidatePairInfoMetrics, captureCommonSsrcMetrics, captureSsrcInfo, captureVideoSsrcMetrics, cleanSdp, compareLocalDevices, createACFCalculator, createMicAnalyser, createWorker, deprioritizeH264, detectMicrophoneNotWorking, enumerate, external_stun_servers, filterMidExtension, filterMsidSemantic, fromLocation, generateByteString, getConstraints, getCurrentPeerConnections, getDeviceData, getDisplayMedia, getIssuesAndMetrics, getMediaConstraints, getMediaSettings, getMediasoupDeviceAsync, getNumFailedStatsReports, getNumFailedTrackSsrcLookups, getNumMissingTrackSsrcLookups, getPeerConnectionIndex, getStats, getStream, getUpdatedDevices, getUpdatedStats, getUserMedia, hasGetDisplayMedia, ipRegex, isFileShareError, isMobile, issueDetectorOrMetricEnabled, maybeTurnOnly, modifyMediaCapabilities, removePeerConnection, replaceTracksInStream, _default as rtcManagerEvents, rtcStats, setClientProvider, setCodecPreferenceSDP, setPeerConnectionsForTests, setVideoBandwidthUsingSetParameters, sortCodecs, standardDeviation, startPerformanceMonitor, stopStreamTracks, subscribeIssues, subscribeStats, trackAnnotations, turnServerOverride, updateRenderedDimensions, variance };
2147
- export type { AddCameraStreamOptions, AddSpotlightRequest, AudioEnableRequest, AudioEnableRequestedEvent, AudioEnabledEvent, BreakoutConfig, BreakoutGroupJoinedEvent, BreakoutSessionUpdateRequest, BreakoutSessionUpdatedEvent, BuildDeviceListOptions, CannotJoinUnclaimedRoomError, ChatFileShare, ChatMessage, ChatMessageError, ChatMessageRemoved, ChatMessageRequest, ClearableTimeout, ClientKickedEvent, ClientLeftEvent, ClientMetadataPayload, ClientMetadataReceivedEvent, ClientRole, ClientUnableToJoinEvent, CloudRecordingStartedEvent, Codec, ConnectionStatus, Credentials, FileShareErrorCode, FileUploadUrl, ForbiddenError, ForbiddenErrorNames, GetConstraintsOptions, GetDeviceDataResult, GetMediaConstraintsOptions, GetStreamOptions, GetStreamResult, GetUpdatedDevicesResult, GetUserMediaAttempt, GetUserMediaAttemptOutcome, HostPresenceControlsError, IdentifyDeviceRequest, InternalServerError, InvalidAssistantKeyError, IssuesAndMetricsByView, JoinRoomRequest, KnockAcceptedEvent, KnockOnHoldEvent, KnockRejectedEvent, KnockResponse, KnockResponseSender, KnockRoomRequest, KnockerLeftEvent, LiveCaptionEvent, LiveCaptionsStartedEvent, LiveCaptionsStoppedEvent, LiveTranscriptionStartedEvent, LiveTranscriptionStoppedEvent, MaxViewerLimitReachedError, MediaPrefs, Metric, NewClientEvent, OrganizationAssistantNotEnabledError, OrganizationAssistantNotFoundError, OrganizationPlanExhaustedError, RemoveScreenshareStreamOptions, RemoveSpotlightRequest, RoleName, RoomConcurrencyControlsError, RoomEmptyError, RoomFullError, RoomJoinPermissionDeniedError, RoomJoinedErrors, RoomJoinedEvent, RoomJoinedSuccess, RoomKnockedEvent, RoomLockedError, RoomLockedEvent, RoomMeetingTimeExhaustedError, RoomMode, RoomSessionEndedEvent, RtcClientConnectionStatusChangedPayload, RtcEventEmitter, RtcEvents, RtcLocalStreamTrackAddedPayload, RtcLocalStreamTrackRemovedPayload, RtcManager, RtcManagerCreatedPayload, RtcManagerOptions, RtcStreamAddedPayload, ScreenshareStartedEvent, ScreenshareStoppedEvent, SendClientMetadataRequest, SignalClient, SignalEvents, SignalIceCandidateMessage, SignalIceEndOfCandidatesMessage, SignalIceServer, SignalKnocker, SignalMediaServerConfig, SignalRTCSessionDescription, SignalReadyToReceiveOfferMessage, SignalRequests, SignalRoom, SignalSDPMessage, SignalSFUServer, SignalTurnServer, SocketConf, SocketManager, Spotlight, SpotlightAddedEvent, SpotlightRemovedEvent, StatsMonitorOptions, StatsMonitorState, StatsSubscription, TurnTransportProtocol, UniqueRoleAlreadyInRoomError, UpdatedDeviceInfo, UpdatedDevicesInfo, VegaConnectionOptions, VegaRtcManagerOptions, VideoEnableRequest, VideoEnableRequestedEvent, VideoEnabledEvent, WebRTCProvider };
2162
+ export { ADDITIONAL_SCREEN_SHARE_SETTINGS, AUDIO_SETTINGS, BandwidthTester, CAMERA_STREAM_ID, EVENTS, FILE_SHARE_ERROR_CODES, KNOCK_MESSAGES, KalmanFilter, Logger, MEDIA_JITTER_BUFFER_TARGET, NoDevicesError, P2pRtcManager, PROTOCOL_ERRORS, PROTOCOL_EVENTS, PROTOCOL_REQUESTS, PROTOCOL_RESPONSES, RELAY_MESSAGES, ReconnectManager, RtcEventNames, RtcManagerDispatcher, SCREEN_SHARE_SETTINGS, SCREEN_SHARE_SIMULCAST_SETTINGS, STREAM_TYPES, ServerSocket, Session, SfuV2Parser, TYPES, VIDEO_SETTINGS_HD, VIDEO_SETTINGS_SD, VIDEO_SETTINGS_VP9, VIDEO_SETTINGS_VP9_LOW_BANDWIDTH, VegaConnection, VegaMediaQualityMonitor, VegaRtcManager, addAbsCaptureTimeExtMap, addExtMap, assert, buildDeviceList, calculateStd, captureAudioSsrcMetrics, captureCandidatePairInfoMetrics, captureCommonSsrcMetrics, captureSsrcInfo, captureVideoSsrcMetrics, cleanSdp, compareLocalDevices, createACFCalculator, createMicAnalyser, createWorker, deprioritizeH264, detectMicrophoneNotWorking, enumerate, external_stun_servers, filterMidExtension, filterMsidSemantic, fromLocation, generateByteString, getConstraints, getCurrentPeerConnections, getDeviceData, getDisplayMedia, getInitialStream, getIssuesAndMetrics, getMediaConstraints, getMediaSettings, getMediasoupDeviceAsync, getNumFailedStatsReports, getNumFailedTrackSsrcLookups, getNumMissingTrackSsrcLookups, getPeerConnectionIndex, getStats, getStream, getUpdatedDevices, getUpdatedStats, getUserMedia, hasGetDisplayMedia, ipRegex, isFileShareError, isMobile, issueDetectorOrMetricEnabled, maybeTurnOnly, modifyMediaCapabilities, removePeerConnection, replaceTracksInStream, _default as rtcManagerEvents, rtcStats, setClientProvider, setCodecPreferenceSDP, setPeerConnectionsForTests, setVideoBandwidthUsingSetParameters, sortCodecs, standardDeviation, startPerformanceMonitor, stopStreamTracks, subscribeIssues, subscribeStats, trackAnnotations, turnServerOverride, updateRenderedDimensions, variance };
2163
+ export type { AddCameraStreamOptions, AddSpotlightRequest, AudioEnableRequest, AudioEnableRequestedEvent, AudioEnabledEvent, BreakoutConfig, BreakoutGroupJoinedEvent, BreakoutSessionUpdateRequest, BreakoutSessionUpdatedEvent, BuildDeviceListOptions, CannotJoinUnclaimedRoomError, ChatFileShare, ChatMessage, ChatMessageError, ChatMessageRemoved, ChatMessageRequest, ClearableTimeout, ClientKickedEvent, ClientLeftEvent, ClientMetadataPayload, ClientMetadataReceivedEvent, ClientRole, ClientUnableToJoinEvent, CloudRecordingStartedEvent, Codec, ConnectionStatus, Credentials, FileShareErrorCode, FileUploadUrl, ForbiddenError, ForbiddenErrorNames, GetConstraintsOptions, GetDeviceDataResult, GetInitialStreamOptions, GetMediaConstraintsOptions, GetStreamOptions, GetStreamResult, GetUpdatedDevicesResult, GetUserMediaAttempt, GetUserMediaAttemptOutcome, HostPresenceControlsError, IdentifyDeviceRequest, InternalServerError, InvalidAssistantKeyError, IssuesAndMetricsByView, JoinRoomRequest, KnockAcceptedEvent, KnockOnHoldEvent, KnockRejectedEvent, KnockResponse, KnockResponseSender, KnockRoomRequest, KnockerLeftEvent, LiveCaptionEvent, LiveCaptionsStartedEvent, LiveCaptionsStoppedEvent, LiveTranscriptionStartedEvent, LiveTranscriptionStoppedEvent, MaxViewerLimitReachedError, MediaPrefs, Metric, NewClientEvent, OrganizationAssistantNotEnabledError, OrganizationAssistantNotFoundError, OrganizationPlanExhaustedError, RemoveScreenshareStreamOptions, RemoveSpotlightRequest, RoleName, RoomConcurrencyControlsError, RoomEmptyError, RoomFullError, RoomJoinPermissionDeniedError, RoomJoinedErrors, RoomJoinedEvent, RoomJoinedSuccess, RoomKnockedEvent, RoomLockedError, RoomLockedEvent, RoomMeetingTimeExhaustedError, RoomMode, RoomSessionEndedEvent, RtcClientConnectionStatusChangedPayload, RtcEventEmitter, RtcEvents, RtcLocalStreamTrackAddedPayload, RtcLocalStreamTrackRemovedPayload, RtcManager, RtcManagerCreatedPayload, RtcManagerOptions, RtcStreamAddedPayload, ScreenshareStartedEvent, ScreenshareStoppedEvent, SendClientMetadataRequest, SignalClient, SignalEvents, SignalIceCandidateMessage, SignalIceEndOfCandidatesMessage, SignalIceServer, SignalKnocker, SignalMediaServerConfig, SignalRTCSessionDescription, SignalReadyToReceiveOfferMessage, SignalRequests, SignalRoom, SignalSDPMessage, SignalSFUServer, SignalTurnServer, SocketConf, SocketManager, Spotlight, SpotlightAddedEvent, SpotlightRemovedEvent, StatsMonitorOptions, StatsMonitorState, StatsSubscription, TurnTransportProtocol, UniqueRoleAlreadyInRoomError, UpdatedDeviceInfo, UpdatedDevicesInfo, VegaConnectionOptions, VegaRtcManagerOptions, VideoEnableRequest, VideoEnableRequestedEvent, VideoEnabledEvent, WebRTCProvider };
package/dist/index.d.mts CHANGED
@@ -449,6 +449,9 @@ type VegaAnalytics = {
449
449
  numIceConnected: number;
450
450
  numIceDisconnected: number;
451
451
  numIceFailed: number;
452
+ sfuMsFromOfflineToClose: number;
453
+ sfuOfflineWhileConnectedCount: number;
454
+ sfuOfflineToCloseCount: number;
452
455
  };
453
456
 
454
457
  type VegaAnalyticMetric = keyof VegaAnalytics;
@@ -600,8 +603,13 @@ type GetMediaConstraintsOptions = {
600
603
  simulcast: boolean;
601
604
  widescreen: boolean;
602
605
  };
606
+ type GetInitialStreamOptions = {
607
+ videoId: false | string | null;
608
+ audioId: false | string | null;
609
+ options: Omit<GetMediaConstraintsOptions, "preferredDeviceIds">;
610
+ };
603
611
  type GetConstraintsOptions = {
604
- devices: MediaDeviceInfo[];
612
+ devices?: MediaDeviceInfo[];
605
613
  audioId?: boolean | string | null;
606
614
  videoId?: boolean | string | null;
607
615
  type?: "ideal" | "exact";
@@ -1384,6 +1392,7 @@ declare function getDeviceData({ audioTrack, videoTrack, devices, stoppedVideoTr
1384
1392
  }): GetDeviceDataResult;
1385
1393
  declare function stopStreamTracks(stream: MediaStream, only?: "audio" | "video" | false): void;
1386
1394
  declare function replaceTracksInStream(stream: MediaStream, newStream: MediaStream, only: "audio" | "video" | false): MediaStreamTrack[];
1395
+ declare function getInitialStream(constraintOpt: GetInitialStreamOptions): Promise<GetStreamResult>;
1387
1396
  declare function getStream(constraintOpt: GetConstraintsOptions, { replaceStream, fallback }?: GetStreamOptions): Promise<GetStreamResult>;
1388
1397
  declare function hasGetDisplayMedia(): boolean;
1389
1398
  declare function getDisplayMedia(constraints?: DisplayMediaStreamOptions, contentHint?: string): Promise<MediaStream>;
@@ -2025,12 +2034,19 @@ declare class VegaRtcManager implements RtcManager {
2025
2034
  _vegaConnectionManager?: ReturnType<typeof createVegaConnectionManager>;
2026
2035
  _networkIsDetectedUpBySignal: boolean;
2027
2036
  _cpuOveruseDetected: boolean;
2037
+ _sfuZombie: {
2038
+ offlineDetectedAt: number | null;
2039
+ onBrowserOffline: any;
2040
+ };
2028
2041
  analytics: VegaAnalytics;
2029
2042
  constructor({ selfId, room, emitter, serverSocket, webrtcProvider, features, eventClaim }: VegaRtcManagerOptions);
2030
2043
  _updateAndScheduleMediaServersRefresh({ iceServers, turnServers, sfuServer, mediaserverConfigTtlSeconds, }: SignalMediaServerConfig): void;
2031
2044
  _clearMediaServersRefresh(): void;
2032
2045
  _onNetworkIsDetectedUpBySignal(): void;
2033
2046
  _onNetworkIsDetectedPossiblyDownBySignal(): void;
2047
+ _sfuZombieOnOffline(): void;
2048
+ _sfuZombieReset(): void;
2049
+ _sfuZombieOnClose(): number | undefined;
2034
2050
  setupSocketListeners(): void;
2035
2051
  _emitScreenshareStarted(): void;
2036
2052
  _connect(): void;
@@ -2143,5 +2159,5 @@ declare class VegaRtcManager implements RtcManager {
2143
2159
  hasClient(clientId: string): boolean;
2144
2160
  }
2145
2161
 
2146
- export { ADDITIONAL_SCREEN_SHARE_SETTINGS, AUDIO_SETTINGS, BandwidthTester, CAMERA_STREAM_ID, EVENTS, FILE_SHARE_ERROR_CODES, KNOCK_MESSAGES, KalmanFilter, Logger, MEDIA_JITTER_BUFFER_TARGET, NoDevicesError, P2pRtcManager, PROTOCOL_ERRORS, PROTOCOL_EVENTS, PROTOCOL_REQUESTS, PROTOCOL_RESPONSES, RELAY_MESSAGES, ReconnectManager, RtcEventNames, RtcManagerDispatcher, SCREEN_SHARE_SETTINGS, SCREEN_SHARE_SIMULCAST_SETTINGS, STREAM_TYPES, ServerSocket, Session, SfuV2Parser, TYPES, VIDEO_SETTINGS_HD, VIDEO_SETTINGS_SD, VIDEO_SETTINGS_VP9, VIDEO_SETTINGS_VP9_LOW_BANDWIDTH, VegaConnection, VegaMediaQualityMonitor, VegaRtcManager, addAbsCaptureTimeExtMap, addExtMap, assert, buildDeviceList, calculateStd, captureAudioSsrcMetrics, captureCandidatePairInfoMetrics, captureCommonSsrcMetrics, captureSsrcInfo, captureVideoSsrcMetrics, cleanSdp, compareLocalDevices, createACFCalculator, createMicAnalyser, createWorker, deprioritizeH264, detectMicrophoneNotWorking, enumerate, external_stun_servers, filterMidExtension, filterMsidSemantic, fromLocation, generateByteString, getConstraints, getCurrentPeerConnections, getDeviceData, getDisplayMedia, getIssuesAndMetrics, getMediaConstraints, getMediaSettings, getMediasoupDeviceAsync, getNumFailedStatsReports, getNumFailedTrackSsrcLookups, getNumMissingTrackSsrcLookups, getPeerConnectionIndex, getStats, getStream, getUpdatedDevices, getUpdatedStats, getUserMedia, hasGetDisplayMedia, ipRegex, isFileShareError, isMobile, issueDetectorOrMetricEnabled, maybeTurnOnly, modifyMediaCapabilities, removePeerConnection, replaceTracksInStream, _default as rtcManagerEvents, rtcStats, setClientProvider, setCodecPreferenceSDP, setPeerConnectionsForTests, setVideoBandwidthUsingSetParameters, sortCodecs, standardDeviation, startPerformanceMonitor, stopStreamTracks, subscribeIssues, subscribeStats, trackAnnotations, turnServerOverride, updateRenderedDimensions, variance };
2147
- export type { AddCameraStreamOptions, AddSpotlightRequest, AudioEnableRequest, AudioEnableRequestedEvent, AudioEnabledEvent, BreakoutConfig, BreakoutGroupJoinedEvent, BreakoutSessionUpdateRequest, BreakoutSessionUpdatedEvent, BuildDeviceListOptions, CannotJoinUnclaimedRoomError, ChatFileShare, ChatMessage, ChatMessageError, ChatMessageRemoved, ChatMessageRequest, ClearableTimeout, ClientKickedEvent, ClientLeftEvent, ClientMetadataPayload, ClientMetadataReceivedEvent, ClientRole, ClientUnableToJoinEvent, CloudRecordingStartedEvent, Codec, ConnectionStatus, Credentials, FileShareErrorCode, FileUploadUrl, ForbiddenError, ForbiddenErrorNames, GetConstraintsOptions, GetDeviceDataResult, GetMediaConstraintsOptions, GetStreamOptions, GetStreamResult, GetUpdatedDevicesResult, GetUserMediaAttempt, GetUserMediaAttemptOutcome, HostPresenceControlsError, IdentifyDeviceRequest, InternalServerError, InvalidAssistantKeyError, IssuesAndMetricsByView, JoinRoomRequest, KnockAcceptedEvent, KnockOnHoldEvent, KnockRejectedEvent, KnockResponse, KnockResponseSender, KnockRoomRequest, KnockerLeftEvent, LiveCaptionEvent, LiveCaptionsStartedEvent, LiveCaptionsStoppedEvent, LiveTranscriptionStartedEvent, LiveTranscriptionStoppedEvent, MaxViewerLimitReachedError, MediaPrefs, Metric, NewClientEvent, OrganizationAssistantNotEnabledError, OrganizationAssistantNotFoundError, OrganizationPlanExhaustedError, RemoveScreenshareStreamOptions, RemoveSpotlightRequest, RoleName, RoomConcurrencyControlsError, RoomEmptyError, RoomFullError, RoomJoinPermissionDeniedError, RoomJoinedErrors, RoomJoinedEvent, RoomJoinedSuccess, RoomKnockedEvent, RoomLockedError, RoomLockedEvent, RoomMeetingTimeExhaustedError, RoomMode, RoomSessionEndedEvent, RtcClientConnectionStatusChangedPayload, RtcEventEmitter, RtcEvents, RtcLocalStreamTrackAddedPayload, RtcLocalStreamTrackRemovedPayload, RtcManager, RtcManagerCreatedPayload, RtcManagerOptions, RtcStreamAddedPayload, ScreenshareStartedEvent, ScreenshareStoppedEvent, SendClientMetadataRequest, SignalClient, SignalEvents, SignalIceCandidateMessage, SignalIceEndOfCandidatesMessage, SignalIceServer, SignalKnocker, SignalMediaServerConfig, SignalRTCSessionDescription, SignalReadyToReceiveOfferMessage, SignalRequests, SignalRoom, SignalSDPMessage, SignalSFUServer, SignalTurnServer, SocketConf, SocketManager, Spotlight, SpotlightAddedEvent, SpotlightRemovedEvent, StatsMonitorOptions, StatsMonitorState, StatsSubscription, TurnTransportProtocol, UniqueRoleAlreadyInRoomError, UpdatedDeviceInfo, UpdatedDevicesInfo, VegaConnectionOptions, VegaRtcManagerOptions, VideoEnableRequest, VideoEnableRequestedEvent, VideoEnabledEvent, WebRTCProvider };
2162
+ export { ADDITIONAL_SCREEN_SHARE_SETTINGS, AUDIO_SETTINGS, BandwidthTester, CAMERA_STREAM_ID, EVENTS, FILE_SHARE_ERROR_CODES, KNOCK_MESSAGES, KalmanFilter, Logger, MEDIA_JITTER_BUFFER_TARGET, NoDevicesError, P2pRtcManager, PROTOCOL_ERRORS, PROTOCOL_EVENTS, PROTOCOL_REQUESTS, PROTOCOL_RESPONSES, RELAY_MESSAGES, ReconnectManager, RtcEventNames, RtcManagerDispatcher, SCREEN_SHARE_SETTINGS, SCREEN_SHARE_SIMULCAST_SETTINGS, STREAM_TYPES, ServerSocket, Session, SfuV2Parser, TYPES, VIDEO_SETTINGS_HD, VIDEO_SETTINGS_SD, VIDEO_SETTINGS_VP9, VIDEO_SETTINGS_VP9_LOW_BANDWIDTH, VegaConnection, VegaMediaQualityMonitor, VegaRtcManager, addAbsCaptureTimeExtMap, addExtMap, assert, buildDeviceList, calculateStd, captureAudioSsrcMetrics, captureCandidatePairInfoMetrics, captureCommonSsrcMetrics, captureSsrcInfo, captureVideoSsrcMetrics, cleanSdp, compareLocalDevices, createACFCalculator, createMicAnalyser, createWorker, deprioritizeH264, detectMicrophoneNotWorking, enumerate, external_stun_servers, filterMidExtension, filterMsidSemantic, fromLocation, generateByteString, getConstraints, getCurrentPeerConnections, getDeviceData, getDisplayMedia, getInitialStream, getIssuesAndMetrics, getMediaConstraints, getMediaSettings, getMediasoupDeviceAsync, getNumFailedStatsReports, getNumFailedTrackSsrcLookups, getNumMissingTrackSsrcLookups, getPeerConnectionIndex, getStats, getStream, getUpdatedDevices, getUpdatedStats, getUserMedia, hasGetDisplayMedia, ipRegex, isFileShareError, isMobile, issueDetectorOrMetricEnabled, maybeTurnOnly, modifyMediaCapabilities, removePeerConnection, replaceTracksInStream, _default as rtcManagerEvents, rtcStats, setClientProvider, setCodecPreferenceSDP, setPeerConnectionsForTests, setVideoBandwidthUsingSetParameters, sortCodecs, standardDeviation, startPerformanceMonitor, stopStreamTracks, subscribeIssues, subscribeStats, trackAnnotations, turnServerOverride, updateRenderedDimensions, variance };
2163
+ export type { AddCameraStreamOptions, AddSpotlightRequest, AudioEnableRequest, AudioEnableRequestedEvent, AudioEnabledEvent, BreakoutConfig, BreakoutGroupJoinedEvent, BreakoutSessionUpdateRequest, BreakoutSessionUpdatedEvent, BuildDeviceListOptions, CannotJoinUnclaimedRoomError, ChatFileShare, ChatMessage, ChatMessageError, ChatMessageRemoved, ChatMessageRequest, ClearableTimeout, ClientKickedEvent, ClientLeftEvent, ClientMetadataPayload, ClientMetadataReceivedEvent, ClientRole, ClientUnableToJoinEvent, CloudRecordingStartedEvent, Codec, ConnectionStatus, Credentials, FileShareErrorCode, FileUploadUrl, ForbiddenError, ForbiddenErrorNames, GetConstraintsOptions, GetDeviceDataResult, GetInitialStreamOptions, GetMediaConstraintsOptions, GetStreamOptions, GetStreamResult, GetUpdatedDevicesResult, GetUserMediaAttempt, GetUserMediaAttemptOutcome, HostPresenceControlsError, IdentifyDeviceRequest, InternalServerError, InvalidAssistantKeyError, IssuesAndMetricsByView, JoinRoomRequest, KnockAcceptedEvent, KnockOnHoldEvent, KnockRejectedEvent, KnockResponse, KnockResponseSender, KnockRoomRequest, KnockerLeftEvent, LiveCaptionEvent, LiveCaptionsStartedEvent, LiveCaptionsStoppedEvent, LiveTranscriptionStartedEvent, LiveTranscriptionStoppedEvent, MaxViewerLimitReachedError, MediaPrefs, Metric, NewClientEvent, OrganizationAssistantNotEnabledError, OrganizationAssistantNotFoundError, OrganizationPlanExhaustedError, RemoveScreenshareStreamOptions, RemoveSpotlightRequest, RoleName, RoomConcurrencyControlsError, RoomEmptyError, RoomFullError, RoomJoinPermissionDeniedError, RoomJoinedErrors, RoomJoinedEvent, RoomJoinedSuccess, RoomKnockedEvent, RoomLockedError, RoomLockedEvent, RoomMeetingTimeExhaustedError, RoomMode, RoomSessionEndedEvent, RtcClientConnectionStatusChangedPayload, RtcEventEmitter, RtcEvents, RtcLocalStreamTrackAddedPayload, RtcLocalStreamTrackRemovedPayload, RtcManager, RtcManagerCreatedPayload, RtcManagerOptions, RtcStreamAddedPayload, ScreenshareStartedEvent, ScreenshareStoppedEvent, SendClientMetadataRequest, SignalClient, SignalEvents, SignalIceCandidateMessage, SignalIceEndOfCandidatesMessage, SignalIceServer, SignalKnocker, SignalMediaServerConfig, SignalRTCSessionDescription, SignalReadyToReceiveOfferMessage, SignalRequests, SignalRoom, SignalSDPMessage, SignalSFUServer, SignalTurnServer, SocketConf, SocketManager, Spotlight, SpotlightAddedEvent, SpotlightRemovedEvent, StatsMonitorOptions, StatsMonitorState, StatsSubscription, TurnTransportProtocol, UniqueRoleAlreadyInRoomError, UpdatedDeviceInfo, UpdatedDevicesInfo, VegaConnectionOptions, VegaRtcManagerOptions, VideoEnableRequest, VideoEnableRequestedEvent, VideoEnabledEvent, WebRTCProvider };
package/dist/index.d.ts CHANGED
@@ -449,6 +449,9 @@ type VegaAnalytics = {
449
449
  numIceConnected: number;
450
450
  numIceDisconnected: number;
451
451
  numIceFailed: number;
452
+ sfuMsFromOfflineToClose: number;
453
+ sfuOfflineWhileConnectedCount: number;
454
+ sfuOfflineToCloseCount: number;
452
455
  };
453
456
 
454
457
  type VegaAnalyticMetric = keyof VegaAnalytics;
@@ -600,8 +603,13 @@ type GetMediaConstraintsOptions = {
600
603
  simulcast: boolean;
601
604
  widescreen: boolean;
602
605
  };
606
+ type GetInitialStreamOptions = {
607
+ videoId: false | string | null;
608
+ audioId: false | string | null;
609
+ options: Omit<GetMediaConstraintsOptions, "preferredDeviceIds">;
610
+ };
603
611
  type GetConstraintsOptions = {
604
- devices: MediaDeviceInfo[];
612
+ devices?: MediaDeviceInfo[];
605
613
  audioId?: boolean | string | null;
606
614
  videoId?: boolean | string | null;
607
615
  type?: "ideal" | "exact";
@@ -1384,6 +1392,7 @@ declare function getDeviceData({ audioTrack, videoTrack, devices, stoppedVideoTr
1384
1392
  }): GetDeviceDataResult;
1385
1393
  declare function stopStreamTracks(stream: MediaStream, only?: "audio" | "video" | false): void;
1386
1394
  declare function replaceTracksInStream(stream: MediaStream, newStream: MediaStream, only: "audio" | "video" | false): MediaStreamTrack[];
1395
+ declare function getInitialStream(constraintOpt: GetInitialStreamOptions): Promise<GetStreamResult>;
1387
1396
  declare function getStream(constraintOpt: GetConstraintsOptions, { replaceStream, fallback }?: GetStreamOptions): Promise<GetStreamResult>;
1388
1397
  declare function hasGetDisplayMedia(): boolean;
1389
1398
  declare function getDisplayMedia(constraints?: DisplayMediaStreamOptions, contentHint?: string): Promise<MediaStream>;
@@ -2025,12 +2034,19 @@ declare class VegaRtcManager implements RtcManager {
2025
2034
  _vegaConnectionManager?: ReturnType<typeof createVegaConnectionManager>;
2026
2035
  _networkIsDetectedUpBySignal: boolean;
2027
2036
  _cpuOveruseDetected: boolean;
2037
+ _sfuZombie: {
2038
+ offlineDetectedAt: number | null;
2039
+ onBrowserOffline: any;
2040
+ };
2028
2041
  analytics: VegaAnalytics;
2029
2042
  constructor({ selfId, room, emitter, serverSocket, webrtcProvider, features, eventClaim }: VegaRtcManagerOptions);
2030
2043
  _updateAndScheduleMediaServersRefresh({ iceServers, turnServers, sfuServer, mediaserverConfigTtlSeconds, }: SignalMediaServerConfig): void;
2031
2044
  _clearMediaServersRefresh(): void;
2032
2045
  _onNetworkIsDetectedUpBySignal(): void;
2033
2046
  _onNetworkIsDetectedPossiblyDownBySignal(): void;
2047
+ _sfuZombieOnOffline(): void;
2048
+ _sfuZombieReset(): void;
2049
+ _sfuZombieOnClose(): number | undefined;
2034
2050
  setupSocketListeners(): void;
2035
2051
  _emitScreenshareStarted(): void;
2036
2052
  _connect(): void;
@@ -2143,5 +2159,5 @@ declare class VegaRtcManager implements RtcManager {
2143
2159
  hasClient(clientId: string): boolean;
2144
2160
  }
2145
2161
 
2146
- export { ADDITIONAL_SCREEN_SHARE_SETTINGS, AUDIO_SETTINGS, BandwidthTester, CAMERA_STREAM_ID, EVENTS, FILE_SHARE_ERROR_CODES, KNOCK_MESSAGES, KalmanFilter, Logger, MEDIA_JITTER_BUFFER_TARGET, NoDevicesError, P2pRtcManager, PROTOCOL_ERRORS, PROTOCOL_EVENTS, PROTOCOL_REQUESTS, PROTOCOL_RESPONSES, RELAY_MESSAGES, ReconnectManager, RtcEventNames, RtcManagerDispatcher, SCREEN_SHARE_SETTINGS, SCREEN_SHARE_SIMULCAST_SETTINGS, STREAM_TYPES, ServerSocket, Session, SfuV2Parser, TYPES, VIDEO_SETTINGS_HD, VIDEO_SETTINGS_SD, VIDEO_SETTINGS_VP9, VIDEO_SETTINGS_VP9_LOW_BANDWIDTH, VegaConnection, VegaMediaQualityMonitor, VegaRtcManager, addAbsCaptureTimeExtMap, addExtMap, assert, buildDeviceList, calculateStd, captureAudioSsrcMetrics, captureCandidatePairInfoMetrics, captureCommonSsrcMetrics, captureSsrcInfo, captureVideoSsrcMetrics, cleanSdp, compareLocalDevices, createACFCalculator, createMicAnalyser, createWorker, deprioritizeH264, detectMicrophoneNotWorking, enumerate, external_stun_servers, filterMidExtension, filterMsidSemantic, fromLocation, generateByteString, getConstraints, getCurrentPeerConnections, getDeviceData, getDisplayMedia, getIssuesAndMetrics, getMediaConstraints, getMediaSettings, getMediasoupDeviceAsync, getNumFailedStatsReports, getNumFailedTrackSsrcLookups, getNumMissingTrackSsrcLookups, getPeerConnectionIndex, getStats, getStream, getUpdatedDevices, getUpdatedStats, getUserMedia, hasGetDisplayMedia, ipRegex, isFileShareError, isMobile, issueDetectorOrMetricEnabled, maybeTurnOnly, modifyMediaCapabilities, removePeerConnection, replaceTracksInStream, _default as rtcManagerEvents, rtcStats, setClientProvider, setCodecPreferenceSDP, setPeerConnectionsForTests, setVideoBandwidthUsingSetParameters, sortCodecs, standardDeviation, startPerformanceMonitor, stopStreamTracks, subscribeIssues, subscribeStats, trackAnnotations, turnServerOverride, updateRenderedDimensions, variance };
2147
- export type { AddCameraStreamOptions, AddSpotlightRequest, AudioEnableRequest, AudioEnableRequestedEvent, AudioEnabledEvent, BreakoutConfig, BreakoutGroupJoinedEvent, BreakoutSessionUpdateRequest, BreakoutSessionUpdatedEvent, BuildDeviceListOptions, CannotJoinUnclaimedRoomError, ChatFileShare, ChatMessage, ChatMessageError, ChatMessageRemoved, ChatMessageRequest, ClearableTimeout, ClientKickedEvent, ClientLeftEvent, ClientMetadataPayload, ClientMetadataReceivedEvent, ClientRole, ClientUnableToJoinEvent, CloudRecordingStartedEvent, Codec, ConnectionStatus, Credentials, FileShareErrorCode, FileUploadUrl, ForbiddenError, ForbiddenErrorNames, GetConstraintsOptions, GetDeviceDataResult, GetMediaConstraintsOptions, GetStreamOptions, GetStreamResult, GetUpdatedDevicesResult, GetUserMediaAttempt, GetUserMediaAttemptOutcome, HostPresenceControlsError, IdentifyDeviceRequest, InternalServerError, InvalidAssistantKeyError, IssuesAndMetricsByView, JoinRoomRequest, KnockAcceptedEvent, KnockOnHoldEvent, KnockRejectedEvent, KnockResponse, KnockResponseSender, KnockRoomRequest, KnockerLeftEvent, LiveCaptionEvent, LiveCaptionsStartedEvent, LiveCaptionsStoppedEvent, LiveTranscriptionStartedEvent, LiveTranscriptionStoppedEvent, MaxViewerLimitReachedError, MediaPrefs, Metric, NewClientEvent, OrganizationAssistantNotEnabledError, OrganizationAssistantNotFoundError, OrganizationPlanExhaustedError, RemoveScreenshareStreamOptions, RemoveSpotlightRequest, RoleName, RoomConcurrencyControlsError, RoomEmptyError, RoomFullError, RoomJoinPermissionDeniedError, RoomJoinedErrors, RoomJoinedEvent, RoomJoinedSuccess, RoomKnockedEvent, RoomLockedError, RoomLockedEvent, RoomMeetingTimeExhaustedError, RoomMode, RoomSessionEndedEvent, RtcClientConnectionStatusChangedPayload, RtcEventEmitter, RtcEvents, RtcLocalStreamTrackAddedPayload, RtcLocalStreamTrackRemovedPayload, RtcManager, RtcManagerCreatedPayload, RtcManagerOptions, RtcStreamAddedPayload, ScreenshareStartedEvent, ScreenshareStoppedEvent, SendClientMetadataRequest, SignalClient, SignalEvents, SignalIceCandidateMessage, SignalIceEndOfCandidatesMessage, SignalIceServer, SignalKnocker, SignalMediaServerConfig, SignalRTCSessionDescription, SignalReadyToReceiveOfferMessage, SignalRequests, SignalRoom, SignalSDPMessage, SignalSFUServer, SignalTurnServer, SocketConf, SocketManager, Spotlight, SpotlightAddedEvent, SpotlightRemovedEvent, StatsMonitorOptions, StatsMonitorState, StatsSubscription, TurnTransportProtocol, UniqueRoleAlreadyInRoomError, UpdatedDeviceInfo, UpdatedDevicesInfo, VegaConnectionOptions, VegaRtcManagerOptions, VideoEnableRequest, VideoEnableRequestedEvent, VideoEnabledEvent, WebRTCProvider };
2162
+ export { ADDITIONAL_SCREEN_SHARE_SETTINGS, AUDIO_SETTINGS, BandwidthTester, CAMERA_STREAM_ID, EVENTS, FILE_SHARE_ERROR_CODES, KNOCK_MESSAGES, KalmanFilter, Logger, MEDIA_JITTER_BUFFER_TARGET, NoDevicesError, P2pRtcManager, PROTOCOL_ERRORS, PROTOCOL_EVENTS, PROTOCOL_REQUESTS, PROTOCOL_RESPONSES, RELAY_MESSAGES, ReconnectManager, RtcEventNames, RtcManagerDispatcher, SCREEN_SHARE_SETTINGS, SCREEN_SHARE_SIMULCAST_SETTINGS, STREAM_TYPES, ServerSocket, Session, SfuV2Parser, TYPES, VIDEO_SETTINGS_HD, VIDEO_SETTINGS_SD, VIDEO_SETTINGS_VP9, VIDEO_SETTINGS_VP9_LOW_BANDWIDTH, VegaConnection, VegaMediaQualityMonitor, VegaRtcManager, addAbsCaptureTimeExtMap, addExtMap, assert, buildDeviceList, calculateStd, captureAudioSsrcMetrics, captureCandidatePairInfoMetrics, captureCommonSsrcMetrics, captureSsrcInfo, captureVideoSsrcMetrics, cleanSdp, compareLocalDevices, createACFCalculator, createMicAnalyser, createWorker, deprioritizeH264, detectMicrophoneNotWorking, enumerate, external_stun_servers, filterMidExtension, filterMsidSemantic, fromLocation, generateByteString, getConstraints, getCurrentPeerConnections, getDeviceData, getDisplayMedia, getInitialStream, getIssuesAndMetrics, getMediaConstraints, getMediaSettings, getMediasoupDeviceAsync, getNumFailedStatsReports, getNumFailedTrackSsrcLookups, getNumMissingTrackSsrcLookups, getPeerConnectionIndex, getStats, getStream, getUpdatedDevices, getUpdatedStats, getUserMedia, hasGetDisplayMedia, ipRegex, isFileShareError, isMobile, issueDetectorOrMetricEnabled, maybeTurnOnly, modifyMediaCapabilities, removePeerConnection, replaceTracksInStream, _default as rtcManagerEvents, rtcStats, setClientProvider, setCodecPreferenceSDP, setPeerConnectionsForTests, setVideoBandwidthUsingSetParameters, sortCodecs, standardDeviation, startPerformanceMonitor, stopStreamTracks, subscribeIssues, subscribeStats, trackAnnotations, turnServerOverride, updateRenderedDimensions, variance };
2163
+ export type { AddCameraStreamOptions, AddSpotlightRequest, AudioEnableRequest, AudioEnableRequestedEvent, AudioEnabledEvent, BreakoutConfig, BreakoutGroupJoinedEvent, BreakoutSessionUpdateRequest, BreakoutSessionUpdatedEvent, BuildDeviceListOptions, CannotJoinUnclaimedRoomError, ChatFileShare, ChatMessage, ChatMessageError, ChatMessageRemoved, ChatMessageRequest, ClearableTimeout, ClientKickedEvent, ClientLeftEvent, ClientMetadataPayload, ClientMetadataReceivedEvent, ClientRole, ClientUnableToJoinEvent, CloudRecordingStartedEvent, Codec, ConnectionStatus, Credentials, FileShareErrorCode, FileUploadUrl, ForbiddenError, ForbiddenErrorNames, GetConstraintsOptions, GetDeviceDataResult, GetInitialStreamOptions, GetMediaConstraintsOptions, GetStreamOptions, GetStreamResult, GetUpdatedDevicesResult, GetUserMediaAttempt, GetUserMediaAttemptOutcome, HostPresenceControlsError, IdentifyDeviceRequest, InternalServerError, InvalidAssistantKeyError, IssuesAndMetricsByView, JoinRoomRequest, KnockAcceptedEvent, KnockOnHoldEvent, KnockRejectedEvent, KnockResponse, KnockResponseSender, KnockRoomRequest, KnockerLeftEvent, LiveCaptionEvent, LiveCaptionsStartedEvent, LiveCaptionsStoppedEvent, LiveTranscriptionStartedEvent, LiveTranscriptionStoppedEvent, MaxViewerLimitReachedError, MediaPrefs, Metric, NewClientEvent, OrganizationAssistantNotEnabledError, OrganizationAssistantNotFoundError, OrganizationPlanExhaustedError, RemoveScreenshareStreamOptions, RemoveSpotlightRequest, RoleName, RoomConcurrencyControlsError, RoomEmptyError, RoomFullError, RoomJoinPermissionDeniedError, RoomJoinedErrors, RoomJoinedEvent, RoomJoinedSuccess, RoomKnockedEvent, RoomLockedError, RoomLockedEvent, RoomMeetingTimeExhaustedError, RoomMode, RoomSessionEndedEvent, RtcClientConnectionStatusChangedPayload, RtcEventEmitter, RtcEvents, RtcLocalStreamTrackAddedPayload, RtcLocalStreamTrackRemovedPayload, RtcManager, RtcManagerCreatedPayload, RtcManagerOptions, RtcStreamAddedPayload, ScreenshareStartedEvent, ScreenshareStoppedEvent, SendClientMetadataRequest, SignalClient, SignalEvents, SignalIceCandidateMessage, SignalIceEndOfCandidatesMessage, SignalIceServer, SignalKnocker, SignalMediaServerConfig, SignalRTCSessionDescription, SignalReadyToReceiveOfferMessage, SignalRequests, SignalRoom, SignalSDPMessage, SignalSFUServer, SignalTurnServer, SocketConf, SocketManager, Spotlight, SpotlightAddedEvent, SpotlightRemovedEvent, StatsMonitorOptions, StatsMonitorState, StatsSubscription, TurnTransportProtocol, UniqueRoleAlreadyInRoomError, UpdatedDeviceInfo, UpdatedDevicesInfo, VegaConnectionOptions, VegaRtcManagerOptions, VideoEnableRequest, VideoEnableRequestedEvent, VideoEnabledEvent, WebRTCProvider };
package/dist/index.mjs CHANGED
@@ -2478,18 +2478,19 @@ function getMediaConstraints({ disableAEC, disableAGC, hd, lax, lowDataMode, pre
2478
2478
  return constraints;
2479
2479
  }
2480
2480
  function getConstraints({ devices, videoId, audioId, options, type = "ideal" }) {
2481
- const audioDevices = devices.filter((d) => d.kind === "audioinput");
2482
- const videoDevices = devices.filter((d) => d.kind === "videoinput");
2483
- const useDefaultAudio = !audioId || !audioDevices.some((d) => d.deviceId === audioId);
2484
- const useDefaultVideo = !videoId || !videoDevices.some((d) => d.deviceId === videoId);
2481
+ const strict = !!devices;
2482
+ const audioDevices = devices === null || devices === void 0 ? void 0 : devices.filter((d) => d.kind === "audioinput");
2483
+ const videoDevices = devices === null || devices === void 0 ? void 0 : devices.filter((d) => d.kind === "videoinput");
2484
+ const useDefaultAudio = !audioId || (strict && !(audioDevices === null || audioDevices === void 0 ? void 0 : audioDevices.some((d) => d.deviceId === audioId)));
2485
+ const useDefaultVideo = !videoId || (strict && !(videoDevices === null || videoDevices === void 0 ? void 0 : videoDevices.some((d) => d.deviceId === videoId)));
2485
2486
  const constraints = getMediaConstraints(Object.assign({ preferredDeviceIds: {
2486
2487
  audioId: useDefaultAudio ? null : { [type]: audioId },
2487
2488
  videoId: useDefaultVideo ? null : { [type]: videoId },
2488
2489
  } }, options));
2489
- if (audioId === false || !audioDevices.length) {
2490
+ if (audioId === false || (strict && !(audioDevices === null || audioDevices === void 0 ? void 0 : audioDevices.length))) {
2490
2491
  delete constraints.audio;
2491
2492
  }
2492
- if (videoId === false || !videoDevices.length) {
2493
+ if (videoId === false || (strict && !(videoDevices === null || videoDevices === void 0 ? void 0 : videoDevices.length))) {
2493
2494
  delete constraints.video;
2494
2495
  }
2495
2496
  return constraints;
@@ -4466,6 +4467,13 @@ class VegaRtcManager {
4466
4467
  });
4467
4468
  this._networkIsDetectedUpBySignal = false;
4468
4469
  this._cpuOveruseDetected = false;
4470
+ this._sfuZombie = {
4471
+ offlineDetectedAt: null,
4472
+ onBrowserOffline: () => this._sfuZombieOnOffline(),
4473
+ };
4474
+ if (typeof window !== "undefined") {
4475
+ window.addEventListener("offline", this._sfuZombie.onBrowserOffline);
4476
+ }
4469
4477
  this.analytics = {
4470
4478
  vegaRequestTimeout: 0,
4471
4479
  vegaUnknownResponse: 0,
@@ -4489,6 +4497,9 @@ class VegaRtcManager {
4489
4497
  numIceConnected: 0,
4490
4498
  numIceDisconnected: 0,
4491
4499
  numIceFailed: 0,
4500
+ sfuMsFromOfflineToClose: 0,
4501
+ sfuOfflineWhileConnectedCount: 0,
4502
+ sfuOfflineToCloseCount: 0,
4492
4503
  };
4493
4504
  }
4494
4505
  _updateAndScheduleMediaServersRefresh({ iceServers, turnServers, sfuServer, mediaserverConfigTtlSeconds, }) {
@@ -4543,6 +4554,32 @@ class VegaRtcManager {
4543
4554
  (_a = this._vegaConnectionManager) === null || _a === void 0 ? void 0 : _a.networkIsPossiblyDown();
4544
4555
  }
4545
4556
  }
4557
+ _sfuZombieOnOffline() {
4558
+ var _a, _b, _c, _d;
4559
+ if (!this._isConnectingOrConnected || this._sfuZombie.offlineDetectedAt !== null) {
4560
+ return;
4561
+ }
4562
+ this._sfuZombie.offlineDetectedAt = Date.now();
4563
+ this.analytics.sfuOfflineWhileConnectedCount++;
4564
+ rtcStats.sendEvent("SfuOfflineWhileConnected", {
4565
+ sfuWsReadyState: (_b = (_a = this._vegaConnection) === null || _a === void 0 ? void 0 : _a.socket) === null || _b === void 0 ? void 0 : _b.readyState,
4566
+ sendTransportState: (_c = this._sendTransport) === null || _c === void 0 ? void 0 : _c.connectionState,
4567
+ recvTransportState: (_d = this._receiveTransport) === null || _d === void 0 ? void 0 : _d.connectionState,
4568
+ });
4569
+ }
4570
+ _sfuZombieReset() {
4571
+ this._sfuZombie.offlineDetectedAt = null;
4572
+ }
4573
+ _sfuZombieOnClose() {
4574
+ let msFromOfflineToClose;
4575
+ if (this._reconnect && this._sfuZombie.offlineDetectedAt !== null) {
4576
+ msFromOfflineToClose = Date.now() - this._sfuZombie.offlineDetectedAt;
4577
+ this.analytics.sfuMsFromOfflineToClose += msFromOfflineToClose;
4578
+ this.analytics.sfuOfflineToCloseCount++;
4579
+ }
4580
+ this._sfuZombieReset();
4581
+ return msFromOfflineToClose;
4582
+ }
4546
4583
  setupSocketListeners() {
4547
4584
  this._socketListenerDeregisterFunctions.push(() => this._clearMediaServersRefresh(), this._serverSocket.on(PROTOCOL_RESPONSES.MEDIASERVER_CONFIG, (data) => {
4548
4585
  if (data.error) {
@@ -4639,7 +4676,8 @@ class VegaRtcManager {
4639
4676
  }
4640
4677
  this._qualityMonitor.close();
4641
4678
  this._emitToPWA(rtcManagerEvents.SFU_CONNECTION_CLOSED);
4642
- rtcStats.sendEvent("SfuConnectionClosed", {});
4679
+ const msFromOfflineToClose = this._sfuZombieOnClose();
4680
+ rtcStats.sendEvent("SfuConnectionClosed", { msFromOfflineToClose });
4643
4681
  }
4644
4682
  _join() {
4645
4683
  return __awaiter(this, void 0, void 0, function* () {
@@ -5619,6 +5657,10 @@ class VegaRtcManager {
5619
5657
  clearTimeout(this._reconnectTimeOut);
5620
5658
  this._reconnectTimeOut = null;
5621
5659
  }
5660
+ this._sfuZombieReset();
5661
+ if (typeof window !== "undefined") {
5662
+ window.removeEventListener("offline", this._sfuZombie.onBrowserOffline);
5663
+ }
5622
5664
  this._socketListenerDeregisterFunctions.forEach((func) => {
5623
5665
  func();
5624
5666
  });
@@ -7271,6 +7313,106 @@ function replaceTracksInStream(stream, newStream, only) {
7271
7313
  replacedTracks.forEach((track) => stream.removeTrack(track));
7272
7314
  return replacedTracks;
7273
7315
  }
7316
+ function createGetUserMediaAttempts() {
7317
+ const attempts = [];
7318
+ const attempt = (c) => __awaiter(this, void 0, void 0, function* () {
7319
+ var _a, _b;
7320
+ try {
7321
+ const s = yield getUserMedia(c);
7322
+ attempts.push({ constraints: c, outcome: { ok: true } });
7323
+ return s;
7324
+ }
7325
+ catch (e) {
7326
+ attempts.push({
7327
+ constraints: c,
7328
+ outcome: Object.assign({ ok: false, errorName: (_a = e === null || e === void 0 ? void 0 : e.name) !== null && _a !== void 0 ? _a : "UnknownError", errorMessage: (_b = e === null || e === void 0 ? void 0 : e.message) !== null && _b !== void 0 ? _b : String(e) }, ((e === null || e === void 0 ? void 0 : e.constraint) && { constraint: e.constraint })),
7329
+ });
7330
+ throw e;
7331
+ }
7332
+ });
7333
+ const attachAttempts = (err) => {
7334
+ if (err)
7335
+ err.attempts = attempts;
7336
+ return err;
7337
+ };
7338
+ return { attempts, attempt, attachAttempts };
7339
+ }
7340
+ function getInitialStream(constraintOpt) {
7341
+ return __awaiter(this, void 0, void 0, function* () {
7342
+ const { attempts, attempt, attachAttempts } = createGetUserMediaAttempts();
7343
+ let error;
7344
+ let stream;
7345
+ const opts = Object.assign(Object.assign({}, constraintOpt), { type: "exact" });
7346
+ try {
7347
+ stream = yield attempt(getConstraints(opts));
7348
+ return {
7349
+ stream,
7350
+ attempts,
7351
+ };
7352
+ }
7353
+ catch (e) {
7354
+ logger.error(e);
7355
+ error = e;
7356
+ }
7357
+ const acquireOneKind = (targetConstraint) => __awaiter(this, void 0, void 0, function* () {
7358
+ const retryOpts = Object.assign(Object.assign({}, opts), { options: Object.assign({}, opts.options) });
7359
+ let stream;
7360
+ let lastError = error;
7361
+ const ignoredConstraint = targetConstraint === "videoId" ? "audioId" : "videoId";
7362
+ if (retryOpts[ignoredConstraint] !== false) {
7363
+ retryOpts[ignoredConstraint] = false;
7364
+ try {
7365
+ stream = yield attempt(getConstraints(retryOpts));
7366
+ return stream;
7367
+ }
7368
+ catch (e) {
7369
+ logger.error(e);
7370
+ lastError = e;
7371
+ }
7372
+ }
7373
+ if ((lastError === null || lastError === void 0 ? void 0 : lastError.name) === "NotAllowedError") {
7374
+ return;
7375
+ }
7376
+ if (retryOpts[targetConstraint]) {
7377
+ retryOpts[targetConstraint] = null;
7378
+ try {
7379
+ stream = yield attempt(getConstraints(retryOpts));
7380
+ return stream;
7381
+ }
7382
+ catch (e) {
7383
+ logger.error(e);
7384
+ }
7385
+ }
7386
+ try {
7387
+ retryOpts.options.lax = true;
7388
+ stream = yield attempt(getConstraints(retryOpts));
7389
+ return stream;
7390
+ }
7391
+ catch (e) {
7392
+ logger.error(e);
7393
+ }
7394
+ });
7395
+ if (opts.videoId !== false) {
7396
+ stream = yield acquireOneKind("videoId");
7397
+ }
7398
+ if (opts.audioId !== false) {
7399
+ if (!stream) {
7400
+ stream = yield acquireOneKind("audioId");
7401
+ }
7402
+ else {
7403
+ const audioOnlyStream = yield acquireOneKind("audioId");
7404
+ if (audioOnlyStream) {
7405
+ const audioTrack = audioOnlyStream.getAudioTracks()[0];
7406
+ stream.addTrack(audioTrack);
7407
+ }
7408
+ }
7409
+ }
7410
+ if (!stream) {
7411
+ throw attachAttempts(error !== null && error !== void 0 ? error : new Error("Unknown error"));
7412
+ }
7413
+ return { error, stream, attempts };
7414
+ });
7415
+ }
7274
7416
  function getStream(constraintOpt_1) {
7275
7417
  return __awaiter(this, arguments, void 0, function* (constraintOpt, { replaceStream, fallback = true } = {}) {
7276
7418
  var _a;
@@ -7278,25 +7420,10 @@ function getStream(constraintOpt_1) {
7278
7420
  let newConstraints;
7279
7421
  let retryConstraintOpt;
7280
7422
  let stream = null;
7281
- const attempts = [];
7423
+ const { attempts, attempt, attachAttempts } = createGetUserMediaAttempts();
7282
7424
  const only = (constraintOpt.audioId === false && "video") || (constraintOpt.videoId === false && "audio");
7283
7425
  const stopTracks = isMobile || only !== "video";
7284
7426
  const constraints = getConstraints(constraintOpt);
7285
- const attempt = (c) => __awaiter(this, void 0, void 0, function* () {
7286
- var _a, _b;
7287
- try {
7288
- const s = yield getUserMedia(c);
7289
- attempts.push({ constraints: c, outcome: { ok: true } });
7290
- return s;
7291
- }
7292
- catch (e) {
7293
- attempts.push({
7294
- constraints: c,
7295
- outcome: Object.assign({ ok: false, errorName: (_a = e === null || e === void 0 ? void 0 : e.name) !== null && _a !== void 0 ? _a : "UnknownError", errorMessage: (_b = e === null || e === void 0 ? void 0 : e.message) !== null && _b !== void 0 ? _b : String(e) }, ((e === null || e === void 0 ? void 0 : e.constraint) && { constraint: e.constraint })),
7296
- });
7297
- throw e;
7298
- }
7299
- });
7300
7427
  const addDetails = (err, orgErr) => {
7301
7428
  if (err) {
7302
7429
  err.details = Object.assign({ constraints, constraint: err.constraint || (orgErr === null || orgErr === void 0 ? void 0 : orgErr.constraint), newConstraints,
@@ -7308,11 +7435,6 @@ function getStream(constraintOpt_1) {
7308
7435
  return new Error("Unknown error");
7309
7436
  }
7310
7437
  };
7311
- const attachAttempts = (err) => {
7312
- if (err)
7313
- err.attempts = attempts;
7314
- return err;
7315
- };
7316
7438
  const getSingleStream = (e) => __awaiter(this, void 0, void 0, function* () {
7317
7439
  if (constraints.audio && constraints.video) {
7318
7440
  try {
@@ -7522,4 +7644,4 @@ var RtcEventNames;
7522
7644
  RtcEventNames["stream_added"] = "stream_added";
7523
7645
  })(RtcEventNames || (RtcEventNames = {}));
7524
7646
 
7525
- export { ADDITIONAL_SCREEN_SHARE_SETTINGS, AUDIO_SETTINGS, BandwidthTester, CAMERA_STREAM_ID, EVENTS, FILE_SHARE_ERROR_CODES, KNOCK_MESSAGES, KalmanFilter, Logger, MEDIA_JITTER_BUFFER_TARGET, NoDevicesError, P2pRtcManager, PROTOCOL_ERRORS, PROTOCOL_EVENTS, PROTOCOL_REQUESTS, PROTOCOL_RESPONSES, RELAY_MESSAGES, ReconnectManager, RtcEventNames, RtcManagerDispatcher, SCREEN_SHARE_SETTINGS, SCREEN_SHARE_SIMULCAST_SETTINGS, STREAM_TYPES, ServerSocket, Session, SfuV2Parser, TYPES, VIDEO_SETTINGS_HD, VIDEO_SETTINGS_SD, VIDEO_SETTINGS_VP9, VIDEO_SETTINGS_VP9_LOW_BANDWIDTH, VegaConnection, VegaMediaQualityMonitor, VegaRtcManager, addAbsCaptureTimeExtMap, addExtMap, assert, buildDeviceList, calculateStd, captureAudioSsrcMetrics, captureCandidatePairInfoMetrics, captureCommonSsrcMetrics, captureSsrcInfo, captureVideoSsrcMetrics, cleanSdp, compareLocalDevices, createACFCalculator, createMicAnalyser, createWorker, deprioritizeH264, detectMicrophoneNotWorking, enumerate, external_stun_servers, filterMidExtension, filterMsidSemantic, fromLocation, generateByteString, getConstraints, getCurrentPeerConnections, getDeviceData, getDisplayMedia, getIssuesAndMetrics, getMediaConstraints, getMediaSettings, getMediasoupDeviceAsync, getNumFailedStatsReports, getNumFailedTrackSsrcLookups, getNumMissingTrackSsrcLookups, getPeerConnectionIndex, getStats, getStream, getUpdatedDevices, getUpdatedStats, getUserMedia, hasGetDisplayMedia, ipRegex, isFileShareError, isMobile, issueDetectorOrMetricEnabled, maybeTurnOnly, modifyMediaCapabilities, removePeerConnection, replaceTracksInStream, rtcManagerEvents, rtcStats, setClientProvider, setCodecPreferenceSDP, setPeerConnectionsForTests, setVideoBandwidthUsingSetParameters, sortCodecs, standardDeviation, startPerformanceMonitor, stopStreamTracks, subscribeIssues, subscribeStats, trackAnnotations, turnServerOverride, updateRenderedDimensions, variance };
7647
+ export { ADDITIONAL_SCREEN_SHARE_SETTINGS, AUDIO_SETTINGS, BandwidthTester, CAMERA_STREAM_ID, EVENTS, FILE_SHARE_ERROR_CODES, KNOCK_MESSAGES, KalmanFilter, Logger, MEDIA_JITTER_BUFFER_TARGET, NoDevicesError, P2pRtcManager, PROTOCOL_ERRORS, PROTOCOL_EVENTS, PROTOCOL_REQUESTS, PROTOCOL_RESPONSES, RELAY_MESSAGES, ReconnectManager, RtcEventNames, RtcManagerDispatcher, SCREEN_SHARE_SETTINGS, SCREEN_SHARE_SIMULCAST_SETTINGS, STREAM_TYPES, ServerSocket, Session, SfuV2Parser, TYPES, VIDEO_SETTINGS_HD, VIDEO_SETTINGS_SD, VIDEO_SETTINGS_VP9, VIDEO_SETTINGS_VP9_LOW_BANDWIDTH, VegaConnection, VegaMediaQualityMonitor, VegaRtcManager, addAbsCaptureTimeExtMap, addExtMap, assert, buildDeviceList, calculateStd, captureAudioSsrcMetrics, captureCandidatePairInfoMetrics, captureCommonSsrcMetrics, captureSsrcInfo, captureVideoSsrcMetrics, cleanSdp, compareLocalDevices, createACFCalculator, createMicAnalyser, createWorker, deprioritizeH264, detectMicrophoneNotWorking, enumerate, external_stun_servers, filterMidExtension, filterMsidSemantic, fromLocation, generateByteString, getConstraints, getCurrentPeerConnections, getDeviceData, getDisplayMedia, getInitialStream, getIssuesAndMetrics, getMediaConstraints, getMediaSettings, getMediasoupDeviceAsync, getNumFailedStatsReports, getNumFailedTrackSsrcLookups, getNumMissingTrackSsrcLookups, getPeerConnectionIndex, getStats, getStream, getUpdatedDevices, getUpdatedStats, getUserMedia, hasGetDisplayMedia, ipRegex, isFileShareError, isMobile, issueDetectorOrMetricEnabled, maybeTurnOnly, modifyMediaCapabilities, removePeerConnection, replaceTracksInStream, rtcManagerEvents, rtcStats, setClientProvider, setCodecPreferenceSDP, setPeerConnectionsForTests, setVideoBandwidthUsingSetParameters, sortCodecs, standardDeviation, startPerformanceMonitor, stopStreamTracks, subscribeIssues, subscribeStats, trackAnnotations, turnServerOverride, updateRenderedDimensions, variance };
@@ -2478,18 +2478,19 @@ function getMediaConstraints({ disableAEC, disableAGC, hd, lax, lowDataMode, pre
2478
2478
  return constraints;
2479
2479
  }
2480
2480
  function getConstraints({ devices, videoId, audioId, options, type = "ideal" }) {
2481
- const audioDevices = devices.filter((d) => d.kind === "audioinput");
2482
- const videoDevices = devices.filter((d) => d.kind === "videoinput");
2483
- const useDefaultAudio = !audioId || !audioDevices.some((d) => d.deviceId === audioId);
2484
- const useDefaultVideo = !videoId || !videoDevices.some((d) => d.deviceId === videoId);
2481
+ const strict = !!devices;
2482
+ const audioDevices = devices === null || devices === void 0 ? void 0 : devices.filter((d) => d.kind === "audioinput");
2483
+ const videoDevices = devices === null || devices === void 0 ? void 0 : devices.filter((d) => d.kind === "videoinput");
2484
+ const useDefaultAudio = !audioId || (strict && !(audioDevices === null || audioDevices === void 0 ? void 0 : audioDevices.some((d) => d.deviceId === audioId)));
2485
+ const useDefaultVideo = !videoId || (strict && !(videoDevices === null || videoDevices === void 0 ? void 0 : videoDevices.some((d) => d.deviceId === videoId)));
2485
2486
  const constraints = getMediaConstraints(Object.assign({ preferredDeviceIds: {
2486
2487
  audioId: useDefaultAudio ? null : { [type]: audioId },
2487
2488
  videoId: useDefaultVideo ? null : { [type]: videoId },
2488
2489
  } }, options));
2489
- if (audioId === false || !audioDevices.length) {
2490
+ if (audioId === false || (strict && !(audioDevices === null || audioDevices === void 0 ? void 0 : audioDevices.length))) {
2490
2491
  delete constraints.audio;
2491
2492
  }
2492
- if (videoId === false || !videoDevices.length) {
2493
+ if (videoId === false || (strict && !(videoDevices === null || videoDevices === void 0 ? void 0 : videoDevices.length))) {
2493
2494
  delete constraints.video;
2494
2495
  }
2495
2496
  return constraints;
@@ -4466,6 +4467,13 @@ class VegaRtcManager {
4466
4467
  });
4467
4468
  this._networkIsDetectedUpBySignal = false;
4468
4469
  this._cpuOveruseDetected = false;
4470
+ this._sfuZombie = {
4471
+ offlineDetectedAt: null,
4472
+ onBrowserOffline: () => this._sfuZombieOnOffline(),
4473
+ };
4474
+ if (typeof window !== "undefined") {
4475
+ window.addEventListener("offline", this._sfuZombie.onBrowserOffline);
4476
+ }
4469
4477
  this.analytics = {
4470
4478
  vegaRequestTimeout: 0,
4471
4479
  vegaUnknownResponse: 0,
@@ -4489,6 +4497,9 @@ class VegaRtcManager {
4489
4497
  numIceConnected: 0,
4490
4498
  numIceDisconnected: 0,
4491
4499
  numIceFailed: 0,
4500
+ sfuMsFromOfflineToClose: 0,
4501
+ sfuOfflineWhileConnectedCount: 0,
4502
+ sfuOfflineToCloseCount: 0,
4492
4503
  };
4493
4504
  }
4494
4505
  _updateAndScheduleMediaServersRefresh({ iceServers, turnServers, sfuServer, mediaserverConfigTtlSeconds, }) {
@@ -4543,6 +4554,32 @@ class VegaRtcManager {
4543
4554
  (_a = this._vegaConnectionManager) === null || _a === void 0 ? void 0 : _a.networkIsPossiblyDown();
4544
4555
  }
4545
4556
  }
4557
+ _sfuZombieOnOffline() {
4558
+ var _a, _b, _c, _d;
4559
+ if (!this._isConnectingOrConnected || this._sfuZombie.offlineDetectedAt !== null) {
4560
+ return;
4561
+ }
4562
+ this._sfuZombie.offlineDetectedAt = Date.now();
4563
+ this.analytics.sfuOfflineWhileConnectedCount++;
4564
+ rtcStats.sendEvent("SfuOfflineWhileConnected", {
4565
+ sfuWsReadyState: (_b = (_a = this._vegaConnection) === null || _a === void 0 ? void 0 : _a.socket) === null || _b === void 0 ? void 0 : _b.readyState,
4566
+ sendTransportState: (_c = this._sendTransport) === null || _c === void 0 ? void 0 : _c.connectionState,
4567
+ recvTransportState: (_d = this._receiveTransport) === null || _d === void 0 ? void 0 : _d.connectionState,
4568
+ });
4569
+ }
4570
+ _sfuZombieReset() {
4571
+ this._sfuZombie.offlineDetectedAt = null;
4572
+ }
4573
+ _sfuZombieOnClose() {
4574
+ let msFromOfflineToClose;
4575
+ if (this._reconnect && this._sfuZombie.offlineDetectedAt !== null) {
4576
+ msFromOfflineToClose = Date.now() - this._sfuZombie.offlineDetectedAt;
4577
+ this.analytics.sfuMsFromOfflineToClose += msFromOfflineToClose;
4578
+ this.analytics.sfuOfflineToCloseCount++;
4579
+ }
4580
+ this._sfuZombieReset();
4581
+ return msFromOfflineToClose;
4582
+ }
4546
4583
  setupSocketListeners() {
4547
4584
  this._socketListenerDeregisterFunctions.push(() => this._clearMediaServersRefresh(), this._serverSocket.on(PROTOCOL_RESPONSES.MEDIASERVER_CONFIG, (data) => {
4548
4585
  if (data.error) {
@@ -4639,7 +4676,8 @@ class VegaRtcManager {
4639
4676
  }
4640
4677
  this._qualityMonitor.close();
4641
4678
  this._emitToPWA(rtcManagerEvents.SFU_CONNECTION_CLOSED);
4642
- rtcStats.sendEvent("SfuConnectionClosed", {});
4679
+ const msFromOfflineToClose = this._sfuZombieOnClose();
4680
+ rtcStats.sendEvent("SfuConnectionClosed", { msFromOfflineToClose });
4643
4681
  }
4644
4682
  _join() {
4645
4683
  return __awaiter(this, void 0, void 0, function* () {
@@ -5619,6 +5657,10 @@ class VegaRtcManager {
5619
5657
  clearTimeout(this._reconnectTimeOut);
5620
5658
  this._reconnectTimeOut = null;
5621
5659
  }
5660
+ this._sfuZombieReset();
5661
+ if (typeof window !== "undefined") {
5662
+ window.removeEventListener("offline", this._sfuZombie.onBrowserOffline);
5663
+ }
5622
5664
  this._socketListenerDeregisterFunctions.forEach((func) => {
5623
5665
  func();
5624
5666
  });
@@ -7271,6 +7313,106 @@ function replaceTracksInStream(stream, newStream, only) {
7271
7313
  replacedTracks.forEach((track) => stream.removeTrack(track));
7272
7314
  return replacedTracks;
7273
7315
  }
7316
+ function createGetUserMediaAttempts() {
7317
+ const attempts = [];
7318
+ const attempt = (c) => __awaiter(this, void 0, void 0, function* () {
7319
+ var _a, _b;
7320
+ try {
7321
+ const s = yield getUserMedia(c);
7322
+ attempts.push({ constraints: c, outcome: { ok: true } });
7323
+ return s;
7324
+ }
7325
+ catch (e) {
7326
+ attempts.push({
7327
+ constraints: c,
7328
+ outcome: Object.assign({ ok: false, errorName: (_a = e === null || e === void 0 ? void 0 : e.name) !== null && _a !== void 0 ? _a : "UnknownError", errorMessage: (_b = e === null || e === void 0 ? void 0 : e.message) !== null && _b !== void 0 ? _b : String(e) }, ((e === null || e === void 0 ? void 0 : e.constraint) && { constraint: e.constraint })),
7329
+ });
7330
+ throw e;
7331
+ }
7332
+ });
7333
+ const attachAttempts = (err) => {
7334
+ if (err)
7335
+ err.attempts = attempts;
7336
+ return err;
7337
+ };
7338
+ return { attempts, attempt, attachAttempts };
7339
+ }
7340
+ function getInitialStream(constraintOpt) {
7341
+ return __awaiter(this, void 0, void 0, function* () {
7342
+ const { attempts, attempt, attachAttempts } = createGetUserMediaAttempts();
7343
+ let error;
7344
+ let stream;
7345
+ const opts = Object.assign(Object.assign({}, constraintOpt), { type: "exact" });
7346
+ try {
7347
+ stream = yield attempt(getConstraints(opts));
7348
+ return {
7349
+ stream,
7350
+ attempts,
7351
+ };
7352
+ }
7353
+ catch (e) {
7354
+ logger.error(e);
7355
+ error = e;
7356
+ }
7357
+ const acquireOneKind = (targetConstraint) => __awaiter(this, void 0, void 0, function* () {
7358
+ const retryOpts = Object.assign(Object.assign({}, opts), { options: Object.assign({}, opts.options) });
7359
+ let stream;
7360
+ let lastError = error;
7361
+ const ignoredConstraint = targetConstraint === "videoId" ? "audioId" : "videoId";
7362
+ if (retryOpts[ignoredConstraint] !== false) {
7363
+ retryOpts[ignoredConstraint] = false;
7364
+ try {
7365
+ stream = yield attempt(getConstraints(retryOpts));
7366
+ return stream;
7367
+ }
7368
+ catch (e) {
7369
+ logger.error(e);
7370
+ lastError = e;
7371
+ }
7372
+ }
7373
+ if ((lastError === null || lastError === void 0 ? void 0 : lastError.name) === "NotAllowedError") {
7374
+ return;
7375
+ }
7376
+ if (retryOpts[targetConstraint]) {
7377
+ retryOpts[targetConstraint] = null;
7378
+ try {
7379
+ stream = yield attempt(getConstraints(retryOpts));
7380
+ return stream;
7381
+ }
7382
+ catch (e) {
7383
+ logger.error(e);
7384
+ }
7385
+ }
7386
+ try {
7387
+ retryOpts.options.lax = true;
7388
+ stream = yield attempt(getConstraints(retryOpts));
7389
+ return stream;
7390
+ }
7391
+ catch (e) {
7392
+ logger.error(e);
7393
+ }
7394
+ });
7395
+ if (opts.videoId !== false) {
7396
+ stream = yield acquireOneKind("videoId");
7397
+ }
7398
+ if (opts.audioId !== false) {
7399
+ if (!stream) {
7400
+ stream = yield acquireOneKind("audioId");
7401
+ }
7402
+ else {
7403
+ const audioOnlyStream = yield acquireOneKind("audioId");
7404
+ if (audioOnlyStream) {
7405
+ const audioTrack = audioOnlyStream.getAudioTracks()[0];
7406
+ stream.addTrack(audioTrack);
7407
+ }
7408
+ }
7409
+ }
7410
+ if (!stream) {
7411
+ throw attachAttempts(error !== null && error !== void 0 ? error : new Error("Unknown error"));
7412
+ }
7413
+ return { error, stream, attempts };
7414
+ });
7415
+ }
7274
7416
  function getStream(constraintOpt_1) {
7275
7417
  return __awaiter(this, arguments, void 0, function* (constraintOpt, { replaceStream, fallback = true } = {}) {
7276
7418
  var _a;
@@ -7278,25 +7420,10 @@ function getStream(constraintOpt_1) {
7278
7420
  let newConstraints;
7279
7421
  let retryConstraintOpt;
7280
7422
  let stream = null;
7281
- const attempts = [];
7423
+ const { attempts, attempt, attachAttempts } = createGetUserMediaAttempts();
7282
7424
  const only = (constraintOpt.audioId === false && "video") || (constraintOpt.videoId === false && "audio");
7283
7425
  const stopTracks = isMobile || only !== "video";
7284
7426
  const constraints = getConstraints(constraintOpt);
7285
- const attempt = (c) => __awaiter(this, void 0, void 0, function* () {
7286
- var _a, _b;
7287
- try {
7288
- const s = yield getUserMedia(c);
7289
- attempts.push({ constraints: c, outcome: { ok: true } });
7290
- return s;
7291
- }
7292
- catch (e) {
7293
- attempts.push({
7294
- constraints: c,
7295
- outcome: Object.assign({ ok: false, errorName: (_a = e === null || e === void 0 ? void 0 : e.name) !== null && _a !== void 0 ? _a : "UnknownError", errorMessage: (_b = e === null || e === void 0 ? void 0 : e.message) !== null && _b !== void 0 ? _b : String(e) }, ((e === null || e === void 0 ? void 0 : e.constraint) && { constraint: e.constraint })),
7296
- });
7297
- throw e;
7298
- }
7299
- });
7300
7427
  const addDetails = (err, orgErr) => {
7301
7428
  if (err) {
7302
7429
  err.details = Object.assign({ constraints, constraint: err.constraint || (orgErr === null || orgErr === void 0 ? void 0 : orgErr.constraint), newConstraints,
@@ -7308,11 +7435,6 @@ function getStream(constraintOpt_1) {
7308
7435
  return new Error("Unknown error");
7309
7436
  }
7310
7437
  };
7311
- const attachAttempts = (err) => {
7312
- if (err)
7313
- err.attempts = attempts;
7314
- return err;
7315
- };
7316
7438
  const getSingleStream = (e) => __awaiter(this, void 0, void 0, function* () {
7317
7439
  if (constraints.audio && constraints.video) {
7318
7440
  try {
@@ -7522,5 +7644,5 @@ var RtcEventNames;
7522
7644
  RtcEventNames["stream_added"] = "stream_added";
7523
7645
  })(RtcEventNames || (RtcEventNames = {}));
7524
7646
 
7525
- export { ADDITIONAL_SCREEN_SHARE_SETTINGS, AUDIO_SETTINGS, BandwidthTester, CAMERA_STREAM_ID, EVENTS, FILE_SHARE_ERROR_CODES, KNOCK_MESSAGES, KalmanFilter, Logger, MEDIA_JITTER_BUFFER_TARGET, NoDevicesError, P2pRtcManager, PROTOCOL_ERRORS, PROTOCOL_EVENTS, PROTOCOL_REQUESTS, PROTOCOL_RESPONSES, RELAY_MESSAGES, ReconnectManager, RtcEventNames, RtcManagerDispatcher, SCREEN_SHARE_SETTINGS, SCREEN_SHARE_SIMULCAST_SETTINGS, STREAM_TYPES, ServerSocket, Session, SfuV2Parser, TYPES, VIDEO_SETTINGS_HD, VIDEO_SETTINGS_SD, VIDEO_SETTINGS_VP9, VIDEO_SETTINGS_VP9_LOW_BANDWIDTH, VegaConnection, VegaMediaQualityMonitor, VegaRtcManager, addAbsCaptureTimeExtMap, addExtMap, assert, buildDeviceList, calculateStd, captureAudioSsrcMetrics, captureCandidatePairInfoMetrics, captureCommonSsrcMetrics, captureSsrcInfo, captureVideoSsrcMetrics, cleanSdp, compareLocalDevices, createACFCalculator, createMicAnalyser, createWorker, deprioritizeH264, detectMicrophoneNotWorking, enumerate, external_stun_servers, filterMidExtension, filterMsidSemantic, fromLocation, generateByteString, getConstraints, getCurrentPeerConnections, getDeviceData, getDisplayMedia, getIssuesAndMetrics, getMediaConstraints, getMediaSettings, getMediasoupDeviceAsync, getNumFailedStatsReports, getNumFailedTrackSsrcLookups, getNumMissingTrackSsrcLookups, getPeerConnectionIndex, getStats, getStream, getUpdatedDevices, getUpdatedStats, getUserMedia, hasGetDisplayMedia, ipRegex, isFileShareError, isMobile, issueDetectorOrMetricEnabled, maybeTurnOnly, modifyMediaCapabilities, removePeerConnection, replaceTracksInStream, rtcManagerEvents, rtcStats, setClientProvider, setCodecPreferenceSDP, setPeerConnectionsForTests, setVideoBandwidthUsingSetParameters, sortCodecs, standardDeviation, startPerformanceMonitor, stopStreamTracks, subscribeIssues, subscribeStats, trackAnnotations, turnServerOverride, updateRenderedDimensions, variance };
7647
+ export { ADDITIONAL_SCREEN_SHARE_SETTINGS, AUDIO_SETTINGS, BandwidthTester, CAMERA_STREAM_ID, EVENTS, FILE_SHARE_ERROR_CODES, KNOCK_MESSAGES, KalmanFilter, Logger, MEDIA_JITTER_BUFFER_TARGET, NoDevicesError, P2pRtcManager, PROTOCOL_ERRORS, PROTOCOL_EVENTS, PROTOCOL_REQUESTS, PROTOCOL_RESPONSES, RELAY_MESSAGES, ReconnectManager, RtcEventNames, RtcManagerDispatcher, SCREEN_SHARE_SETTINGS, SCREEN_SHARE_SIMULCAST_SETTINGS, STREAM_TYPES, ServerSocket, Session, SfuV2Parser, TYPES, VIDEO_SETTINGS_HD, VIDEO_SETTINGS_SD, VIDEO_SETTINGS_VP9, VIDEO_SETTINGS_VP9_LOW_BANDWIDTH, VegaConnection, VegaMediaQualityMonitor, VegaRtcManager, addAbsCaptureTimeExtMap, addExtMap, assert, buildDeviceList, calculateStd, captureAudioSsrcMetrics, captureCandidatePairInfoMetrics, captureCommonSsrcMetrics, captureSsrcInfo, captureVideoSsrcMetrics, cleanSdp, compareLocalDevices, createACFCalculator, createMicAnalyser, createWorker, deprioritizeH264, detectMicrophoneNotWorking, enumerate, external_stun_servers, filterMidExtension, filterMsidSemantic, fromLocation, generateByteString, getConstraints, getCurrentPeerConnections, getDeviceData, getDisplayMedia, getInitialStream, getIssuesAndMetrics, getMediaConstraints, getMediaSettings, getMediasoupDeviceAsync, getNumFailedStatsReports, getNumFailedTrackSsrcLookups, getNumMissingTrackSsrcLookups, getPeerConnectionIndex, getStats, getStream, getUpdatedDevices, getUpdatedStats, getUserMedia, hasGetDisplayMedia, ipRegex, isFileShareError, isMobile, issueDetectorOrMetricEnabled, maybeTurnOnly, modifyMediaCapabilities, removePeerConnection, replaceTracksInStream, rtcManagerEvents, rtcStats, setClientProvider, setCodecPreferenceSDP, setPeerConnectionsForTests, setVideoBandwidthUsingSetParameters, sortCodecs, standardDeviation, startPerformanceMonitor, stopStreamTracks, subscribeIssues, subscribeStats, trackAnnotations, turnServerOverride, updateRenderedDimensions, variance };
7526
7648
  //# sourceMappingURL=legacy-esm.js.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@whereby.com/media",
3
3
  "description": "Media library for Whereby",
4
- "version": "9.6.0",
4
+ "version": "9.7.0",
5
5
  "license": "MIT",
6
6
  "homepage": "https://github.com/whereby/sdk",
7
7
  "repository": {