livekit-client 2.11.0 → 2.11.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.
@@ -11186,7 +11186,7 @@ function getOSVersion(ua) {
11186
11186
  return ua.includes('mac os') ? getMatch(/\(.+?(\d+_\d+(:?_\d+)?)/, ua, 1).replace(/_/g, '.') : undefined;
11187
11187
  }
11188
11188
 
11189
- var version$1 = "2.11.0";
11189
+ var version$1 = "2.11.2";
11190
11190
 
11191
11191
  const version = version$1;
11192
11192
  const protocolVersion = 15;
@@ -19434,6 +19434,176 @@ class LocalTrackPublication extends TrackPublication {
19434
19434
  }
19435
19435
  }
19436
19436
 
19437
+ /**
19438
+ * Creates a local video and audio track at the same time. When acquiring both
19439
+ * audio and video tracks together, it'll display a single permission prompt to
19440
+ * the user instead of two separate ones.
19441
+ * @param options
19442
+ */
19443
+ function createLocalTracks(options, loggerOptions) {
19444
+ return __awaiter(this, void 0, void 0, function* () {
19445
+ // set default options to true
19446
+ const internalOptions = Object.assign({}, options !== null && options !== void 0 ? options : {});
19447
+ let attemptExactMatch = false;
19448
+ let retryAudioOptions = options === null || options === void 0 ? void 0 : options.audio;
19449
+ let retryVideoOptions = options === null || options === void 0 ? void 0 : options.video;
19450
+ // if the user passes a device id as a string, we default to exact match
19451
+ if (internalOptions.audio && typeof internalOptions.audio === 'object' && typeof internalOptions.audio.deviceId === 'string') {
19452
+ const deviceId = internalOptions.audio.deviceId;
19453
+ internalOptions.audio.deviceId = {
19454
+ exact: deviceId
19455
+ };
19456
+ attemptExactMatch = true;
19457
+ retryAudioOptions = Object.assign(Object.assign({}, internalOptions.audio), {
19458
+ deviceId: {
19459
+ ideal: deviceId
19460
+ }
19461
+ });
19462
+ }
19463
+ if (internalOptions.video && typeof internalOptions.video === 'object' && typeof internalOptions.video.deviceId === 'string') {
19464
+ const deviceId = internalOptions.video.deviceId;
19465
+ internalOptions.video.deviceId = {
19466
+ exact: deviceId
19467
+ };
19468
+ attemptExactMatch = true;
19469
+ retryVideoOptions = Object.assign(Object.assign({}, internalOptions.video), {
19470
+ deviceId: {
19471
+ ideal: deviceId
19472
+ }
19473
+ });
19474
+ }
19475
+ // TODO if internal options don't have device Id specified, set it to 'default'
19476
+ if (internalOptions.audio === true || typeof internalOptions.audio === 'object' && !internalOptions.audio.deviceId) {
19477
+ internalOptions.audio = {
19478
+ deviceId: 'default'
19479
+ };
19480
+ }
19481
+ if (internalOptions.video === true || typeof internalOptions.video === 'object' && !internalOptions.video.deviceId) {
19482
+ internalOptions.video = {
19483
+ deviceId: 'default'
19484
+ };
19485
+ }
19486
+ const {
19487
+ audioProcessor,
19488
+ videoProcessor
19489
+ } = extractProcessorsFromOptions(internalOptions);
19490
+ const opts = mergeDefaultOptions(internalOptions, audioDefaults, videoDefaults);
19491
+ const constraints = constraintsForOptions(opts);
19492
+ // Keep a reference to the promise on DeviceManager and await it in getLocalDevices()
19493
+ // works around iOS Safari Bug https://bugs.webkit.org/show_bug.cgi?id=179363
19494
+ const mediaPromise = navigator.mediaDevices.getUserMedia(constraints);
19495
+ if (internalOptions.audio) {
19496
+ DeviceManager.userMediaPromiseMap.set('audioinput', mediaPromise);
19497
+ mediaPromise.catch(() => DeviceManager.userMediaPromiseMap.delete('audioinput'));
19498
+ }
19499
+ if (internalOptions.video) {
19500
+ DeviceManager.userMediaPromiseMap.set('videoinput', mediaPromise);
19501
+ mediaPromise.catch(() => DeviceManager.userMediaPromiseMap.delete('videoinput'));
19502
+ }
19503
+ try {
19504
+ const stream = yield mediaPromise;
19505
+ return yield Promise.all(stream.getTracks().map(mediaStreamTrack => __awaiter(this, void 0, void 0, function* () {
19506
+ const isAudio = mediaStreamTrack.kind === 'audio';
19507
+ let trackOptions = isAudio ? opts.audio : opts.video;
19508
+ if (typeof trackOptions === 'boolean' || !trackOptions) {
19509
+ trackOptions = {};
19510
+ }
19511
+ let trackConstraints;
19512
+ const conOrBool = isAudio ? constraints.audio : constraints.video;
19513
+ if (typeof conOrBool !== 'boolean') {
19514
+ trackConstraints = conOrBool;
19515
+ }
19516
+ // update the constraints with the device id the user gave permissions to in the permission prompt
19517
+ // otherwise each track restart (e.g. mute - unmute) will try to initialize the device again -> causing additional permission prompts
19518
+ const newDeviceId = mediaStreamTrack.getSettings().deviceId;
19519
+ if ((trackConstraints === null || trackConstraints === void 0 ? void 0 : trackConstraints.deviceId) && unwrapConstraint(trackConstraints.deviceId) !== newDeviceId) {
19520
+ trackConstraints.deviceId = newDeviceId;
19521
+ } else if (!trackConstraints) {
19522
+ trackConstraints = {
19523
+ deviceId: newDeviceId
19524
+ };
19525
+ }
19526
+ const track = mediaTrackToLocalTrack(mediaStreamTrack, trackConstraints, loggerOptions);
19527
+ if (track.kind === Track.Kind.Video) {
19528
+ track.source = Track.Source.Camera;
19529
+ } else if (track.kind === Track.Kind.Audio) {
19530
+ track.source = Track.Source.Microphone;
19531
+ }
19532
+ track.mediaStream = stream;
19533
+ if (isAudioTrack(track) && audioProcessor) {
19534
+ yield track.setProcessor(audioProcessor);
19535
+ } else if (isVideoTrack(track) && videoProcessor) {
19536
+ yield track.setProcessor(videoProcessor);
19537
+ }
19538
+ return track;
19539
+ })));
19540
+ } catch (e) {
19541
+ if (!attemptExactMatch) {
19542
+ throw e;
19543
+ }
19544
+ return createLocalTracks(Object.assign(Object.assign({}, options), {
19545
+ audio: retryAudioOptions,
19546
+ video: retryVideoOptions
19547
+ }), loggerOptions);
19548
+ }
19549
+ });
19550
+ }
19551
+ /**
19552
+ * Creates a [[LocalVideoTrack]] with getUserMedia()
19553
+ * @param options
19554
+ */
19555
+ function createLocalVideoTrack(options) {
19556
+ return __awaiter(this, void 0, void 0, function* () {
19557
+ const tracks = yield createLocalTracks({
19558
+ audio: false,
19559
+ video: options !== null && options !== void 0 ? options : true
19560
+ });
19561
+ return tracks[0];
19562
+ });
19563
+ }
19564
+ function createLocalAudioTrack(options) {
19565
+ return __awaiter(this, void 0, void 0, function* () {
19566
+ const tracks = yield createLocalTracks({
19567
+ audio: options !== null && options !== void 0 ? options : true,
19568
+ video: false
19569
+ });
19570
+ return tracks[0];
19571
+ });
19572
+ }
19573
+ /**
19574
+ * Creates a screen capture tracks with getDisplayMedia().
19575
+ * A LocalVideoTrack is always created and returned.
19576
+ * If { audio: true }, and the browser supports audio capture, a LocalAudioTrack is also created.
19577
+ */
19578
+ function createLocalScreenTracks(options) {
19579
+ return __awaiter(this, void 0, void 0, function* () {
19580
+ if (options === undefined) {
19581
+ options = {};
19582
+ }
19583
+ if (options.resolution === undefined && !isSafari17()) {
19584
+ options.resolution = ScreenSharePresets.h1080fps30.resolution;
19585
+ }
19586
+ if (navigator.mediaDevices.getDisplayMedia === undefined) {
19587
+ throw new DeviceUnsupportedError('getDisplayMedia not supported');
19588
+ }
19589
+ const constraints = screenCaptureToDisplayMediaStreamOptions(options);
19590
+ const stream = yield navigator.mediaDevices.getDisplayMedia(constraints);
19591
+ const tracks = stream.getVideoTracks();
19592
+ if (tracks.length === 0) {
19593
+ throw new TrackInvalidError('no video track found');
19594
+ }
19595
+ const screenVideo = new LocalVideoTrack(tracks[0], undefined, false);
19596
+ screenVideo.source = Track.Source.ScreenShare;
19597
+ const localTracks = [screenVideo];
19598
+ if (stream.getAudioTracks().length > 0) {
19599
+ const screenAudio = new LocalAudioTrack(stream.getAudioTracks()[0], undefined, false);
19600
+ screenAudio.source = Track.Source.ScreenShareAudio;
19601
+ localTracks.push(screenAudio);
19602
+ }
19603
+ return localTracks;
19604
+ });
19605
+ }
19606
+
19437
19607
  var ConnectionQuality;
19438
19608
  (function (ConnectionQuality) {
19439
19609
  ConnectionQuality["Excellent"] = "excellent";
@@ -20203,58 +20373,36 @@ class LocalParticipant extends Participant {
20203
20373
  var _a, _b;
20204
20374
  options !== null && options !== void 0 ? options : options = {};
20205
20375
  const mergedOptionsWithProcessors = mergeDefaultOptions(options, (_a = this.roomOptions) === null || _a === void 0 ? void 0 : _a.audioCaptureDefaults, (_b = this.roomOptions) === null || _b === void 0 ? void 0 : _b.videoCaptureDefaults);
20206
- const {
20207
- audioProcessor,
20208
- videoProcessor,
20209
- optionsWithoutProcessor
20210
- } = extractProcessorsFromOptions(mergedOptionsWithProcessors);
20211
- const constraints = constraintsForOptions(optionsWithoutProcessor);
20212
- let stream;
20213
20376
  try {
20214
- stream = yield navigator.mediaDevices.getUserMedia(constraints);
20377
+ const tracks = yield createLocalTracks(mergedOptionsWithProcessors, {
20378
+ loggerName: this.roomOptions.loggerName,
20379
+ loggerContextCb: () => this.logContext
20380
+ });
20381
+ const localTracks = tracks.map(track => {
20382
+ if (isAudioTrack(track)) {
20383
+ this.microphoneError = undefined;
20384
+ track.setAudioContext(this.audioContext);
20385
+ track.source = Track.Source.Microphone;
20386
+ this.emit(ParticipantEvent.AudioStreamAcquired);
20387
+ }
20388
+ if (isVideoTrack(track)) {
20389
+ this.cameraError = undefined;
20390
+ track.source = Track.Source.Camera;
20391
+ }
20392
+ return track;
20393
+ });
20394
+ return localTracks;
20215
20395
  } catch (err) {
20216
20396
  if (err instanceof Error) {
20217
- if (constraints.audio) {
20397
+ if (options.audio) {
20218
20398
  this.microphoneError = err;
20219
20399
  }
20220
- if (constraints.video) {
20400
+ if (options.video) {
20221
20401
  this.cameraError = err;
20222
20402
  }
20223
20403
  }
20224
20404
  throw err;
20225
20405
  }
20226
- if (constraints.audio) {
20227
- this.microphoneError = undefined;
20228
- this.emit(ParticipantEvent.AudioStreamAcquired);
20229
- }
20230
- if (constraints.video) {
20231
- this.cameraError = undefined;
20232
- }
20233
- return Promise.all(stream.getTracks().map(mediaStreamTrack => __awaiter(this, void 0, void 0, function* () {
20234
- const isAudio = mediaStreamTrack.kind === 'audio';
20235
- let trackConstraints;
20236
- const conOrBool = isAudio ? constraints.audio : constraints.video;
20237
- if (typeof conOrBool !== 'boolean') {
20238
- trackConstraints = conOrBool;
20239
- }
20240
- const track = mediaTrackToLocalTrack(mediaStreamTrack, trackConstraints, {
20241
- loggerName: this.roomOptions.loggerName,
20242
- loggerContextCb: () => this.logContext
20243
- });
20244
- if (track.kind === Track.Kind.Video) {
20245
- track.source = Track.Source.Camera;
20246
- } else if (track.kind === Track.Kind.Audio) {
20247
- track.source = Track.Source.Microphone;
20248
- track.setAudioContext(this.audioContext);
20249
- }
20250
- track.mediaStream = stream;
20251
- if (isAudioTrack(track) && audioProcessor) {
20252
- yield track.setProcessor(audioProcessor);
20253
- } else if (isVideoTrack(track) && videoProcessor) {
20254
- yield track.setProcessor(videoProcessor);
20255
- }
20256
- return track;
20257
- })));
20258
20406
  });
20259
20407
  }
20260
20408
  /**
@@ -24266,172 +24414,6 @@ class ConnectionProtocolCheck extends Checker {
24266
24414
  }
24267
24415
  }
24268
24416
 
24269
- /**
24270
- * Creates a local video and audio track at the same time. When acquiring both
24271
- * audio and video tracks together, it'll display a single permission prompt to
24272
- * the user instead of two separate ones.
24273
- * @param options
24274
- */
24275
- function createLocalTracks(options) {
24276
- return __awaiter(this, void 0, void 0, function* () {
24277
- var _a, _b;
24278
- // set default options to true
24279
- const internalOptions = Object.assign({}, options !== null && options !== void 0 ? options : {});
24280
- let attemptExactMatch = false;
24281
- let retryAudioOptions = options === null || options === void 0 ? void 0 : options.audio;
24282
- let retryVideoOptions = options === null || options === void 0 ? void 0 : options.video;
24283
- // if the user passes a device id as a string, we default to exact match
24284
- if (internalOptions.audio && typeof internalOptions.audio === 'object' && typeof internalOptions.audio.deviceId === 'string') {
24285
- const deviceId = internalOptions.audio.deviceId;
24286
- internalOptions.audio.deviceId = {
24287
- exact: deviceId
24288
- };
24289
- attemptExactMatch = true;
24290
- retryAudioOptions = Object.assign(Object.assign({}, internalOptions.audio), {
24291
- deviceId: {
24292
- ideal: deviceId
24293
- }
24294
- });
24295
- }
24296
- if (internalOptions.video && typeof internalOptions.video === 'object' && typeof internalOptions.video.deviceId === 'string') {
24297
- const deviceId = internalOptions.video.deviceId;
24298
- internalOptions.video.deviceId = {
24299
- exact: deviceId
24300
- };
24301
- attemptExactMatch = true;
24302
- retryVideoOptions = Object.assign(Object.assign({}, internalOptions.video), {
24303
- deviceId: {
24304
- ideal: deviceId
24305
- }
24306
- });
24307
- }
24308
- (_a = internalOptions.audio) !== null && _a !== void 0 ? _a : internalOptions.audio = {
24309
- deviceId: 'default'
24310
- };
24311
- (_b = internalOptions.video) !== null && _b !== void 0 ? _b : internalOptions.video = {
24312
- deviceId: 'default'
24313
- };
24314
- const {
24315
- audioProcessor,
24316
- videoProcessor
24317
- } = extractProcessorsFromOptions(internalOptions);
24318
- const opts = mergeDefaultOptions(internalOptions, audioDefaults, videoDefaults);
24319
- const constraints = constraintsForOptions(opts);
24320
- // Keep a reference to the promise on DeviceManager and await it in getLocalDevices()
24321
- // works around iOS Safari Bug https://bugs.webkit.org/show_bug.cgi?id=179363
24322
- const mediaPromise = navigator.mediaDevices.getUserMedia(constraints);
24323
- if (internalOptions.audio) {
24324
- DeviceManager.userMediaPromiseMap.set('audioinput', mediaPromise);
24325
- mediaPromise.catch(() => DeviceManager.userMediaPromiseMap.delete('audioinput'));
24326
- }
24327
- if (internalOptions.video) {
24328
- DeviceManager.userMediaPromiseMap.set('videoinput', mediaPromise);
24329
- mediaPromise.catch(() => DeviceManager.userMediaPromiseMap.delete('videoinput'));
24330
- }
24331
- try {
24332
- const stream = yield mediaPromise;
24333
- return yield Promise.all(stream.getTracks().map(mediaStreamTrack => __awaiter(this, void 0, void 0, function* () {
24334
- const isAudio = mediaStreamTrack.kind === 'audio';
24335
- let trackOptions = isAudio ? opts.audio : opts.video;
24336
- if (typeof trackOptions === 'boolean' || !trackOptions) {
24337
- trackOptions = {};
24338
- }
24339
- let trackConstraints;
24340
- const conOrBool = isAudio ? constraints.audio : constraints.video;
24341
- if (typeof conOrBool !== 'boolean') {
24342
- trackConstraints = conOrBool;
24343
- }
24344
- // update the constraints with the device id the user gave permissions to in the permission prompt
24345
- // otherwise each track restart (e.g. mute - unmute) will try to initialize the device again -> causing additional permission prompts
24346
- const newDeviceId = mediaStreamTrack.getSettings().deviceId;
24347
- if ((trackConstraints === null || trackConstraints === void 0 ? void 0 : trackConstraints.deviceId) && unwrapConstraint(trackConstraints.deviceId) !== newDeviceId) {
24348
- trackConstraints.deviceId = newDeviceId;
24349
- } else if (!trackConstraints) {
24350
- trackConstraints = {
24351
- deviceId: newDeviceId
24352
- };
24353
- }
24354
- const track = mediaTrackToLocalTrack(mediaStreamTrack, trackConstraints);
24355
- if (track.kind === Track.Kind.Video) {
24356
- track.source = Track.Source.Camera;
24357
- } else if (track.kind === Track.Kind.Audio) {
24358
- track.source = Track.Source.Microphone;
24359
- }
24360
- track.mediaStream = stream;
24361
- if (isAudioTrack(track) && audioProcessor) {
24362
- yield track.setProcessor(audioProcessor);
24363
- } else if (isVideoTrack(track) && videoProcessor) {
24364
- yield track.setProcessor(videoProcessor);
24365
- }
24366
- return track;
24367
- })));
24368
- } catch (e) {
24369
- if (!attemptExactMatch) {
24370
- throw e;
24371
- }
24372
- return createLocalTracks(Object.assign(Object.assign({}, options), {
24373
- audio: retryAudioOptions,
24374
- video: retryVideoOptions
24375
- }));
24376
- }
24377
- });
24378
- }
24379
- /**
24380
- * Creates a [[LocalVideoTrack]] with getUserMedia()
24381
- * @param options
24382
- */
24383
- function createLocalVideoTrack(options) {
24384
- return __awaiter(this, void 0, void 0, function* () {
24385
- const tracks = yield createLocalTracks({
24386
- audio: false,
24387
- video: options
24388
- });
24389
- return tracks[0];
24390
- });
24391
- }
24392
- function createLocalAudioTrack(options) {
24393
- return __awaiter(this, void 0, void 0, function* () {
24394
- const tracks = yield createLocalTracks({
24395
- audio: options,
24396
- video: false
24397
- });
24398
- return tracks[0];
24399
- });
24400
- }
24401
- /**
24402
- * Creates a screen capture tracks with getDisplayMedia().
24403
- * A LocalVideoTrack is always created and returned.
24404
- * If { audio: true }, and the browser supports audio capture, a LocalAudioTrack is also created.
24405
- */
24406
- function createLocalScreenTracks(options) {
24407
- return __awaiter(this, void 0, void 0, function* () {
24408
- if (options === undefined) {
24409
- options = {};
24410
- }
24411
- if (options.resolution === undefined && !isSafari17()) {
24412
- options.resolution = ScreenSharePresets.h1080fps30.resolution;
24413
- }
24414
- if (navigator.mediaDevices.getDisplayMedia === undefined) {
24415
- throw new DeviceUnsupportedError('getDisplayMedia not supported');
24416
- }
24417
- const constraints = screenCaptureToDisplayMediaStreamOptions(options);
24418
- const stream = yield navigator.mediaDevices.getDisplayMedia(constraints);
24419
- const tracks = stream.getVideoTracks();
24420
- if (tracks.length === 0) {
24421
- throw new TrackInvalidError('no video track found');
24422
- }
24423
- const screenVideo = new LocalVideoTrack(tracks[0], undefined, false);
24424
- screenVideo.source = Track.Source.ScreenShare;
24425
- const localTracks = [screenVideo];
24426
- if (stream.getAudioTracks().length > 0) {
24427
- const screenAudio = new LocalAudioTrack(stream.getAudioTracks()[0], undefined, false);
24428
- screenAudio.source = Track.Source.ScreenShareAudio;
24429
- localTracks.push(screenAudio);
24430
- }
24431
- return localTracks;
24432
- });
24433
- }
24434
-
24435
24417
  class PublishAudioCheck extends Checker {
24436
24418
  get description() {
24437
24419
  return 'Can publish audio';