@whereby.com/media 8.0.0 → 8.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -506,8 +506,8 @@ type GetMediaConstraintsOptions = {
506
506
  };
507
507
  type GetConstraintsOptions = {
508
508
  devices: MediaDeviceInfo[];
509
- audioId?: boolean | string;
510
- videoId?: boolean | string;
509
+ audioId?: boolean | string | null;
510
+ videoId?: boolean | string | null;
511
511
  type?: "ideal" | "exact";
512
512
  options: Omit<GetMediaConstraintsOptions, "preferredDeviceIds">;
513
513
  };
@@ -515,6 +515,11 @@ type GetStreamOptions = {
515
515
  replaceStream?: MediaStream;
516
516
  fallback?: boolean;
517
517
  };
518
+ interface BuildDeviceListOptions {
519
+ devices: MediaDeviceInfo[];
520
+ busyDeviceIds: string[];
521
+ kind: MediaDeviceKind;
522
+ }
518
523
  type GetStreamResult = {
519
524
  error?: unknown;
520
525
  replacedTracks?: MediaStreamTrack[];
@@ -1136,7 +1141,7 @@ declare class BandwidthTester extends EventEmitter {
1136
1141
  features?: any;
1137
1142
  });
1138
1143
  start(runTime?: number): void;
1139
- close(): void;
1144
+ close(vegaConnectionClosed?: boolean): void;
1140
1145
  _start(): Promise<void>;
1141
1146
  _createTransport(send: any): Promise<void>;
1142
1147
  _getTestTrack(): any;
@@ -1163,22 +1168,33 @@ declare class NoDevicesError extends Error {
1163
1168
  constructor(...args: any);
1164
1169
  }
1165
1170
  declare function enumerate(): Promise<MediaDeviceInfo[]>;
1166
- declare function buildDeviceList({ busyDeviceIds, devices, kind }: any): any;
1171
+ declare function buildDeviceList({ busyDeviceIds, devices, kind }: BuildDeviceListOptions): {
1172
+ [x: string]: string | boolean;
1173
+ label: string;
1174
+ busy: boolean;
1175
+ }[] | {
1176
+ [x: string]: string;
1177
+ label: string;
1178
+ }[];
1167
1179
  declare function getUserMedia(constraints: any): Promise<MediaStream>;
1168
1180
  declare function getDeviceData({ audioTrack, videoTrack, devices, stoppedVideoTrack, lastAudioId, lastVideoId, }: {
1169
1181
  audioTrack?: MediaStreamTrack | null;
1170
1182
  videoTrack?: MediaStreamTrack | null;
1171
1183
  devices: MediaDeviceInfo[];
1172
- stoppedVideoTrack?: boolean;
1184
+ stoppedVideoTrack?: MediaStreamTrack;
1173
1185
  lastAudioId?: string | undefined;
1174
1186
  lastVideoId?: string | undefined;
1175
1187
  }): GetDeviceDataResult;
1176
1188
  declare function stopStreamTracks(stream: MediaStream, only?: "audio" | "video" | false): void;
1177
1189
  declare function replaceTracksInStream(stream: MediaStream, newStream: MediaStream, only: "audio" | "video" | false): MediaStreamTrack[];
1178
- declare function getStream(constraintOpt: any, { replaceStream, fallback }?: GetStreamOptions): Promise<GetStreamResult>;
1190
+ declare function getStream(constraintOpt: GetConstraintsOptions, { replaceStream, fallback }?: GetStreamOptions): Promise<GetStreamResult>;
1179
1191
  declare function hasGetDisplayMedia(): boolean;
1180
1192
  declare function getDisplayMedia(constraints?: DisplayMediaStreamOptions, contentHint?: string): Promise<MediaStream>;
1181
- declare function compareLocalDevices(before: MediaDeviceInfo[], after: MediaDeviceInfo[]): any;
1193
+ declare function compareLocalDevices(before: MediaDeviceInfo[], after: MediaDeviceInfo[]): Record<MediaDeviceKind, {
1194
+ removed: Record<string, MediaDeviceInfo>;
1195
+ added: Record<string, MediaDeviceInfo>;
1196
+ changed: Record<string, MediaDeviceInfo>;
1197
+ }>;
1182
1198
  declare function getUpdatedDevices({ oldDevices, newDevices, currentAudioId, currentVideoId, currentSpeakerId, }: {
1183
1199
  oldDevices: MediaDeviceInfo[];
1184
1200
  newDevices: MediaDeviceInfo[];
@@ -1188,7 +1204,6 @@ declare function getUpdatedDevices({ oldDevices, newDevices, currentAudioId, cur
1188
1204
  }): GetUpdatedDevicesResult;
1189
1205
 
1190
1206
  interface P2PSessionOptions {
1191
- peerConnectionId: string;
1192
1207
  clientId: string;
1193
1208
  bandwidth: number;
1194
1209
  peerConnectionConfig: RTCConfiguration;
@@ -1196,7 +1211,6 @@ interface P2PSessionOptions {
1196
1211
  incrementAnalyticMetric: P2PIncrementAnalyticMetric;
1197
1212
  }
1198
1213
  declare class Session {
1199
- peerConnectionId: any;
1200
1214
  relayCandidateSeen: boolean;
1201
1215
  serverReflexiveCandidateSeen: boolean;
1202
1216
  publicHostCandidateSeen: boolean;
@@ -1222,7 +1236,7 @@ declare class Session {
1222
1236
  srdComplete: any;
1223
1237
  _incrementAnalyticMetric: P2PIncrementAnalyticMetric;
1224
1238
  pendingReplaceTrackActions: (() => Promise<void>)[];
1225
- constructor({ peerConnectionId, clientId, bandwidth, peerConnectionConfig, deprioritizeH264Encoding, incrementAnalyticMetric, }: P2PSessionOptions);
1239
+ constructor({ clientId, bandwidth, peerConnectionConfig, deprioritizeH264Encoding, incrementAnalyticMetric, }: P2PSessionOptions);
1226
1240
  addStream(stream: MediaStream): void;
1227
1241
  addTrack(track: MediaStreamTrack, stream?: MediaStream): void;
1228
1242
  removeTrack(track: MediaStreamTrack): void;
@@ -1240,7 +1254,6 @@ declare class Session {
1240
1254
  }
1241
1255
 
1242
1256
  interface CreateSessionOptions {
1243
- peerConnectionId: string;
1244
1257
  clientId: string;
1245
1258
  initialBandwidth: number;
1246
1259
  isOfferer: boolean;
@@ -1342,9 +1355,9 @@ declare class P2pRtcManager implements RtcManager {
1342
1355
  _setJitterBufferTarget(pc: RTCPeerConnection): void;
1343
1356
  _emitServerEvent(eventName: string, data?: any): void;
1344
1357
  _emit(eventName: string, data?: any): void;
1345
- _getSession(peerConnectionId: string): Session | null;
1346
- _createSession({ clientId, initialBandwidth, isOfferer, peerConnectionId }: CreateSessionOptions): Session;
1347
- _cleanup(peerConnectionId: string): void;
1358
+ _getSession(clientId: string): Session | null;
1359
+ _createSession({ clientId, initialBandwidth, isOfferer }: CreateSessionOptions): Session;
1360
+ _cleanup(clientId: string): void;
1348
1361
  _forEachPeerConnection(func: any): void;
1349
1362
  _addStreamToPeerConnections(stream: MediaStream): void;
1350
1363
  _addTrackToPeerConnections(track: MediaStreamTrack, stream?: MediaStream): void;
@@ -1361,11 +1374,6 @@ declare class P2pRtcManager implements RtcManager {
1361
1374
  _negotiatePeerConnection({ clientId, session, constraints, isInitialOffer, }: NegotiatePeerConnectionOptions): void;
1362
1375
  _withForcedRenegotiation(session: Session, action: any): void;
1363
1376
  _changeBandwidthForAllClients(isJoining: boolean): number;
1364
- _createP2pSession({ clientId, initialBandwidth, isOfferer, }: {
1365
- clientId: string;
1366
- initialBandwidth: number;
1367
- isOfferer: boolean;
1368
- }): Session;
1369
1377
  acceptNewStream({ streamId, clientId }: {
1370
1378
  streamId: string;
1371
1379
  clientId: string;
@@ -1944,4 +1952,4 @@ declare const STREAM_TYPES: {
1944
1952
  };
1945
1953
 
1946
1954
  export { ADDITIONAL_SCREEN_SHARE_SETTINGS, AUDIO_SETTINGS, BandwidthTester, CAMERA_STREAM_ID, EVENTS, 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, isMobile, issueDetectorOrMetricEnabled, maybeTurnOnly, modifyMediaCapabilities, removePeerConnection, replaceTracksInStream, _default as rtcManagerEvents, rtcStats, setClientProvider, setCodecPreferenceSDP, setPeerConnectionsForTests, setVideoBandwidthUsingSetParameters, sortCodecs, standardDeviation, startPerformanceMonitor, stopStreamTracks, subscribeIssues, subscribeStats, trackAnnotations, turnServerOverride, variance };
1947
- export type { AddCameraStreamOptions, AddSpotlightRequest, AudioEnableRequest, AudioEnableRequestedEvent, AudioEnabledEvent, BreakoutConfig, BreakoutGroupJoinedEvent, BreakoutSessionUpdatedEvent, CannotJoinUnclaimedRoomError, ChatMessage, ClearableTimeout, ClientKickedEvent, ClientLeftEvent, ClientMetadataPayload, ClientMetadataReceivedEvent, ClientRole, ClientUnableToJoinEvent, CloudRecordingStartedEvent, Codec, Credentials, ForbiddenError, ForbiddenErrorNames, GetConstraintsOptions, GetDeviceDataResult, GetMediaConstraintsOptions, GetStreamOptions, GetStreamResult, GetUpdatedDevicesResult, HostPresenceControlsError, IdentifyDeviceRequest, InternalServerError, InvalidAssistantKeyError, IssuesAndMetricsByView, JoinRoomRequest, KnockAcceptedEvent, KnockRejectedEvent, KnockRoomRequest, KnockerLeftEvent, LiveTranscriptionStartedEvent, LiveTranscriptionStoppedEvent, MaxViewerLimitReachedError, 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, VegaRtcManagerOptions, VideoEnableRequest, VideoEnableRequestedEvent, VideoEnabledEvent, WebRTCProvider };
1955
+ export type { AddCameraStreamOptions, AddSpotlightRequest, AudioEnableRequest, AudioEnableRequestedEvent, AudioEnabledEvent, BreakoutConfig, BreakoutGroupJoinedEvent, BreakoutSessionUpdatedEvent, BuildDeviceListOptions, CannotJoinUnclaimedRoomError, ChatMessage, ClearableTimeout, ClientKickedEvent, ClientLeftEvent, ClientMetadataPayload, ClientMetadataReceivedEvent, ClientRole, ClientUnableToJoinEvent, CloudRecordingStartedEvent, Codec, Credentials, ForbiddenError, ForbiddenErrorNames, GetConstraintsOptions, GetDeviceDataResult, GetMediaConstraintsOptions, GetStreamOptions, GetStreamResult, GetUpdatedDevicesResult, HostPresenceControlsError, IdentifyDeviceRequest, InternalServerError, InvalidAssistantKeyError, IssuesAndMetricsByView, JoinRoomRequest, KnockAcceptedEvent, KnockRejectedEvent, KnockRoomRequest, KnockerLeftEvent, LiveTranscriptionStartedEvent, LiveTranscriptionStoppedEvent, MaxViewerLimitReachedError, 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, VegaRtcManagerOptions, VideoEnableRequest, VideoEnableRequestedEvent, VideoEnabledEvent, WebRTCProvider };
package/dist/index.mjs CHANGED
@@ -2196,8 +2196,7 @@ var _a$4;
2196
2196
  const adapter$4 = (_a$4 = adapterRaw.default) !== null && _a$4 !== void 0 ? _a$4 : adapterRaw;
2197
2197
  const logger$7 = new Logger();
2198
2198
  class Session {
2199
- constructor({ peerConnectionId, clientId, bandwidth, peerConnectionConfig, deprioritizeH264Encoding, incrementAnalyticMetric, }) {
2200
- this.peerConnectionId = peerConnectionId;
2199
+ constructor({ clientId, bandwidth, peerConnectionConfig, deprioritizeH264Encoding, incrementAnalyticMetric, }) {
2201
2200
  this.relayCandidateSeen = false;
2202
2201
  this.serverReflexiveCandidateSeen = false;
2203
2202
  this.publicHostCandidateSeen = false;
@@ -2734,8 +2733,8 @@ class P2pRtcManager {
2734
2733
  }
2735
2734
  disconnectAll() {
2736
2735
  logger$6.info("disconnectAll()");
2737
- Object.keys(this.peerConnections).forEach((peerConnectionId) => {
2738
- this.disconnect(peerConnectionId);
2736
+ Object.keys(this.peerConnections).forEach((clientId) => {
2737
+ this.disconnect(clientId);
2739
2738
  });
2740
2739
  this.peerConnections = {};
2741
2740
  this._socketListenerDeregisterFunctions.forEach((func) => {
@@ -2934,16 +2933,14 @@ class P2pRtcManager {
2934
2933
  _emit(eventName, data) {
2935
2934
  this._emitter.emit(eventName, data);
2936
2935
  }
2937
- _getSession(peerConnectionId) {
2938
- if (!(peerConnectionId in this.peerConnections)) {
2936
+ _getSession(clientId) {
2937
+ if (!(clientId in this.peerConnections)) {
2939
2938
  return null;
2940
2939
  }
2941
- return this.peerConnections[peerConnectionId];
2940
+ return this.peerConnections[clientId];
2942
2941
  }
2943
- _createSession({ clientId, initialBandwidth, isOfferer, peerConnectionId }) {
2944
- if (!peerConnectionId) {
2945
- throw new Error("peerConnectionId is missing");
2946
- }
2942
+ _createSession({ clientId, initialBandwidth, isOfferer }) {
2943
+ var _a, _b;
2947
2944
  if (!clientId) {
2948
2945
  throw new Error("clientId is missing");
2949
2946
  }
@@ -2958,17 +2955,121 @@ class P2pRtcManager {
2958
2955
  browserVersion >= 14 &&
2959
2956
  this._features.deprioritizeH264OnSafari;
2960
2957
  const session = new Session({
2961
- peerConnectionId,
2962
2958
  clientId,
2963
2959
  peerConnectionConfig,
2964
2960
  bandwidth: initialBandwidth,
2965
2961
  deprioritizeH264Encoding,
2966
2962
  incrementAnalyticMetric: (metric) => this.analytics[metric]++,
2967
2963
  });
2968
- this.peerConnections[peerConnectionId] = session;
2964
+ this.peerConnections[clientId] = session;
2969
2965
  setTimeout(() => this._emit(rtcManagerEvents.NEW_PC), 0);
2970
2966
  this.analytics.numNewPc++;
2971
2967
  const { pc } = session;
2968
+ pc.onicegatheringstatechange = (event) => {
2969
+ const connection = event.target;
2970
+ switch (connection.iceGatheringState) {
2971
+ case "gathering":
2972
+ if (this._icePublicIPGatheringTimeoutID)
2973
+ clearTimeout(this._icePublicIPGatheringTimeoutID);
2974
+ this._icePublicIPGatheringTimeoutID = setTimeout(() => {
2975
+ if (!session.publicHostCandidateSeen &&
2976
+ !session.relayCandidateSeen &&
2977
+ !session.serverReflexiveCandidateSeen) {
2978
+ if (pc.iceConnectionState !== "connected" && pc.iceConnectionState !== "completed")
2979
+ this.analytics.numIceNoPublicIpGatheredIn3sec++;
2980
+ }
2981
+ }, ICE_PUBLIC_IP_GATHERING_TIMEOUT);
2982
+ break;
2983
+ case "complete":
2984
+ if (this._icePublicIPGatheringTimeoutID)
2985
+ clearTimeout(this._icePublicIPGatheringTimeoutID);
2986
+ this._icePublicIPGatheringTimeoutID = null;
2987
+ break;
2988
+ }
2989
+ };
2990
+ pc.onicecandidate = (event) => {
2991
+ if (event.candidate) {
2992
+ if (event.candidate.type === "relayed") {
2993
+ this.analytics.P2PRelayedIceCandidate++;
2994
+ }
2995
+ switch (event.candidate.type) {
2996
+ case "host":
2997
+ const address = event.candidate.address;
2998
+ if (!address) {
2999
+ break;
3000
+ }
3001
+ try {
3002
+ if (ipRegex.v4({ exact: true }).test(address)) {
3003
+ const ipv4 = checkIp(address);
3004
+ if (ipv4.isPublicIp)
3005
+ session.publicHostCandidateSeen = true;
3006
+ }
3007
+ else if (ipRegex.v6({ exact: true }).test(address.replace(/^\[(.*)\]/, "$1"))) {
3008
+ const ipv6 = new Address6(address.replace(/^\[(.*)\]/, "$1"));
3009
+ session.ipv6HostCandidateSeen = true;
3010
+ if (ipv6.getScope() === "Global") {
3011
+ session.publicHostCandidateSeen = true;
3012
+ }
3013
+ if (ipv6.isTeredo()) {
3014
+ session.ipv6HostCandidateTeredoSeen = true;
3015
+ }
3016
+ if (ipv6.is6to4()) {
3017
+ session.ipv6HostCandidate6to4Seen = true;
3018
+ }
3019
+ }
3020
+ else {
3021
+ const uuidv4 = address.replace(/.local/, "");
3022
+ if (uuidv4 && validate(uuidv4, 4)) {
3023
+ session.mdnsHostCandidateSeen = true;
3024
+ }
3025
+ }
3026
+ }
3027
+ catch (error) {
3028
+ logger$6.info("Error during parsing candidates! Error: ", { error });
3029
+ }
3030
+ break;
3031
+ case "srflx":
3032
+ session.serverReflexiveCandidateSeen = true;
3033
+ break;
3034
+ case "relayed":
3035
+ case "relay":
3036
+ session.relayCandidateSeen = true;
3037
+ break;
3038
+ }
3039
+ this._emitServerEvent(RELAY_MESSAGES.ICE_CANDIDATE, {
3040
+ receiverId: clientId,
3041
+ message: event.candidate,
3042
+ });
3043
+ }
3044
+ else {
3045
+ this._emitServerEvent(RELAY_MESSAGES.ICE_END_OF_CANDIDATES, {
3046
+ receiverId: clientId,
3047
+ });
3048
+ if (!session.publicHostCandidateSeen &&
3049
+ !session.relayCandidateSeen &&
3050
+ !session.serverReflexiveCandidateSeen &&
3051
+ pc.iceConnectionState !== "connected" &&
3052
+ pc.iceConnectionState !== "completed") {
3053
+ this.analytics.numIceNoPublicIpGathered++;
3054
+ }
3055
+ if (session.ipv6HostCandidateSeen) {
3056
+ this.analytics.numIceIpv6Seen++;
3057
+ if (session.ipv6HostCandidate6to4Seen)
3058
+ this.analytics.numIceIpv6SixToFour++;
3059
+ if (session.ipv6HostCandidateTeredoSeen)
3060
+ this.analytics.numIceIpv6TeredoSeen++;
3061
+ }
3062
+ if (session.mdnsHostCandidateSeen)
3063
+ this.analytics.numIceMdnsSeen++;
3064
+ }
3065
+ };
3066
+ pc.onnegotiationneeded = () => {
3067
+ if (pc.iceConnectionState === "new" || !session.connectionStatus) {
3068
+ return;
3069
+ }
3070
+ logger$6.info(`onnegotiationneeded client ${clientId}`);
3071
+ this._negotiatePeerConnection({ clientId, session });
3072
+ };
2972
3073
  pc.ontrack = (event) => {
2973
3074
  const stream = event.streams[0];
2974
3075
  if (!stream) {
@@ -3100,16 +3201,22 @@ class P2pRtcManager {
3100
3201
  });
3101
3202
  }
3102
3203
  }
3204
+ if (this._features.increaseIncomingMediaBufferOn) {
3205
+ this._setJitterBufferTarget(pc);
3206
+ }
3207
+ if (((_b = (_a = this._localCameraStream) === null || _a === void 0 ? void 0 : _a.getVideoTracks()) === null || _b === void 0 ? void 0 : _b.length) && this._stoppedVideoTrack) {
3208
+ pc.addTrack(this._stoppedVideoTrack, this._localCameraStream);
3209
+ }
3103
3210
  return session;
3104
3211
  }
3105
- _cleanup(peerConnectionId) {
3106
- const session = this._getSession(peerConnectionId);
3212
+ _cleanup(clientId) {
3213
+ const session = this._getSession(clientId);
3107
3214
  if (!session) {
3108
- logger$6.warn("No RTCPeerConnection in RTCManager.disconnect()", peerConnectionId);
3215
+ logger$6.warn("No RTCPeerConnection in RTCManager.disconnect()", clientId);
3109
3216
  return;
3110
3217
  }
3111
3218
  session.close();
3112
- delete this.peerConnections[peerConnectionId];
3219
+ delete this.peerConnections[clientId];
3113
3220
  }
3114
3221
  _forEachPeerConnection(func) {
3115
3222
  Object.values(this.peerConnections).forEach((peerConnection) => {
@@ -3210,7 +3317,7 @@ class P2pRtcManager {
3210
3317
  else {
3211
3318
  initialBandwidth = this._changeBandwidthForAllClients(true);
3212
3319
  }
3213
- session = this._createP2pSession({
3320
+ session = this._createSession({
3214
3321
  clientId,
3215
3322
  initialBandwidth,
3216
3323
  isOfferer: true,
@@ -3374,128 +3481,6 @@ class P2pRtcManager {
3374
3481
  });
3375
3482
  return bandwidth;
3376
3483
  }
3377
- _createP2pSession({ clientId, initialBandwidth, isOfferer = false, }) {
3378
- var _a, _b;
3379
- const session = this._createSession({
3380
- peerConnectionId: clientId,
3381
- clientId,
3382
- initialBandwidth,
3383
- isOfferer,
3384
- });
3385
- const pc = session.pc;
3386
- if (this._features.increaseIncomingMediaBufferOn) {
3387
- this._setJitterBufferTarget(pc);
3388
- }
3389
- if (((_b = (_a = this._localCameraStream) === null || _a === void 0 ? void 0 : _a.getVideoTracks()) === null || _b === void 0 ? void 0 : _b.length) && this._stoppedVideoTrack) {
3390
- pc.addTrack(this._stoppedVideoTrack, this._localCameraStream);
3391
- }
3392
- pc.onicegatheringstatechange = (event) => {
3393
- const connection = event.target;
3394
- switch (connection.iceGatheringState) {
3395
- case "gathering":
3396
- if (this._icePublicIPGatheringTimeoutID)
3397
- clearTimeout(this._icePublicIPGatheringTimeoutID);
3398
- this._icePublicIPGatheringTimeoutID = setTimeout(() => {
3399
- if (!session.publicHostCandidateSeen &&
3400
- !session.relayCandidateSeen &&
3401
- !session.serverReflexiveCandidateSeen) {
3402
- if (pc.iceConnectionState !== "connected" && pc.iceConnectionState !== "completed")
3403
- this.analytics.numIceNoPublicIpGatheredIn3sec++;
3404
- }
3405
- }, ICE_PUBLIC_IP_GATHERING_TIMEOUT);
3406
- break;
3407
- case "complete":
3408
- if (this._icePublicIPGatheringTimeoutID)
3409
- clearTimeout(this._icePublicIPGatheringTimeoutID);
3410
- this._icePublicIPGatheringTimeoutID = null;
3411
- break;
3412
- }
3413
- };
3414
- pc.onicecandidate = (event) => {
3415
- if (event.candidate) {
3416
- if (event.candidate.type === "relayed") {
3417
- this.analytics.P2PRelayedIceCandidate++;
3418
- }
3419
- switch (event.candidate.type) {
3420
- case "host":
3421
- const address = event.candidate.address;
3422
- if (!address) {
3423
- break;
3424
- }
3425
- try {
3426
- if (ipRegex.v4({ exact: true }).test(address)) {
3427
- const ipv4 = checkIp(address);
3428
- if (ipv4.isPublicIp)
3429
- session.publicHostCandidateSeen = true;
3430
- }
3431
- else if (ipRegex.v6({ exact: true }).test(address.replace(/^\[(.*)\]/, "$1"))) {
3432
- const ipv6 = new Address6(address.replace(/^\[(.*)\]/, "$1"));
3433
- session.ipv6HostCandidateSeen = true;
3434
- if (ipv6.getScope() === "Global") {
3435
- session.publicHostCandidateSeen = true;
3436
- }
3437
- if (ipv6.isTeredo()) {
3438
- session.ipv6HostCandidateTeredoSeen = true;
3439
- }
3440
- if (ipv6.is6to4()) {
3441
- session.ipv6HostCandidate6to4Seen = true;
3442
- }
3443
- }
3444
- else {
3445
- const uuidv4 = address.replace(/.local/, "");
3446
- if (uuidv4 && validate(uuidv4, 4)) {
3447
- session.mdnsHostCandidateSeen = true;
3448
- }
3449
- }
3450
- }
3451
- catch (error) {
3452
- logger$6.info("Error during parsing candidates! Error: ", { error });
3453
- }
3454
- break;
3455
- case "srflx":
3456
- session.serverReflexiveCandidateSeen = true;
3457
- break;
3458
- case "relayed":
3459
- case "relay":
3460
- session.relayCandidateSeen = true;
3461
- break;
3462
- }
3463
- this._emitServerEvent(RELAY_MESSAGES.ICE_CANDIDATE, {
3464
- receiverId: clientId,
3465
- message: event.candidate,
3466
- });
3467
- }
3468
- else {
3469
- this._emitServerEvent(RELAY_MESSAGES.ICE_END_OF_CANDIDATES, {
3470
- receiverId: clientId,
3471
- });
3472
- if (!session.publicHostCandidateSeen &&
3473
- !session.relayCandidateSeen &&
3474
- !session.serverReflexiveCandidateSeen &&
3475
- pc.iceConnectionState !== "connected" &&
3476
- pc.iceConnectionState !== "completed") {
3477
- this.analytics.numIceNoPublicIpGathered++;
3478
- }
3479
- if (session.ipv6HostCandidateSeen) {
3480
- this.analytics.numIceIpv6Seen++;
3481
- if (session.ipv6HostCandidate6to4Seen)
3482
- this.analytics.numIceIpv6SixToFour++;
3483
- if (session.ipv6HostCandidateTeredoSeen)
3484
- this.analytics.numIceIpv6TeredoSeen++;
3485
- }
3486
- if (session.mdnsHostCandidateSeen)
3487
- this.analytics.numIceMdnsSeen++;
3488
- }
3489
- };
3490
- pc.onnegotiationneeded = () => {
3491
- if (pc.iceConnectionState === "new" || !session.connectionStatus) {
3492
- return;
3493
- }
3494
- logger$6.info(`onnegotiationneeded client ${clientId}`);
3495
- this._negotiatePeerConnection({ clientId, session });
3496
- };
3497
- return session;
3498
- }
3499
3484
  acceptNewStream({ streamId, clientId }) {
3500
3485
  logger$6.info("acceptNewStream() [streamId: %s}, clientId: %s]", streamId, clientId);
3501
3486
  let session = this._getSession(clientId);
@@ -3509,7 +3494,7 @@ class P2pRtcManager {
3509
3494
  else {
3510
3495
  initialBandwidth = this._changeBandwidthForAllClients(true);
3511
3496
  }
3512
- session = this._createP2pSession({
3497
+ session = this._createSession({
3513
3498
  clientId,
3514
3499
  initialBandwidth,
3515
3500
  isOfferer: false,
@@ -6741,11 +6726,11 @@ class BandwidthTester extends EventEmitter {
6741
6726
  const wsUrl = `wss://${host}`;
6742
6727
  this._vegaConnection = new VegaConnection(wsUrl, "whereby-sfu#bw-test-v1");
6743
6728
  this._vegaConnection.on("open", () => this._start());
6744
- this._vegaConnection.on("close", () => this.close());
6729
+ this._vegaConnection.on("close", () => this.close(true));
6745
6730
  this._vegaConnection.on("message", (message) => this._onMessage(message));
6746
6731
  this._startTimeout();
6747
6732
  }
6748
- close() {
6733
+ close(vegaConnectionClosed) {
6749
6734
  logger$1.info("close()");
6750
6735
  this.closed = true;
6751
6736
  if (!!this._timeout || Date.now() - this._startTime < 750) {
@@ -6753,6 +6738,12 @@ class BandwidthTester extends EventEmitter {
6753
6738
  error: true,
6754
6739
  });
6755
6740
  }
6741
+ else if (vegaConnectionClosed && this._resultTimeout) {
6742
+ this.emit("result", {
6743
+ error: true,
6744
+ });
6745
+ clearTimeout(this._resultTimeout);
6746
+ }
6756
6747
  this._clearTimeouts();
6757
6748
  clearInterval(this._drawInterval);
6758
6749
  this._drawInterval = null;
@@ -7095,9 +7086,7 @@ function buildDeviceList({ busyDeviceIds, devices, kind }) {
7095
7086
  label: `${busyDeviceIds.includes(d.deviceId) ? "(busy) " : ""}${d.label || d.deviceId.slice(0, 5)}`,
7096
7087
  busy: busyDeviceIds.includes(d.deviceId),
7097
7088
  }));
7098
- return deviceList && deviceList.length !== 0
7099
- ? deviceList
7100
- : [{ [idFieldsByKind[kind]]: "", label: "Default" }];
7089
+ return deviceList && deviceList.length !== 0 ? deviceList : [{ [idFieldsByKind[kind]]: "", label: "Default" }];
7101
7090
  }
7102
7091
  function getUserMedia(constraints) {
7103
7092
  if (!constraints.audio && !constraints.video) {