livekit-client 2.11.0 → 2.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/livekit-client.esm.mjs +191 -209
- package/dist/livekit-client.esm.mjs.map +1 -1
- package/dist/livekit-client.umd.js +1 -1
- package/dist/livekit-client.umd.js.map +1 -1
- package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
- package/dist/src/room/track/create.d.ts +2 -1
- package/dist/src/room/track/create.d.ts.map +1 -1
- package/dist/ts4.2/src/room/track/create.d.ts +2 -1
- package/package.json +1 -1
- package/src/room/participant/LocalParticipant.ts +21 -47
- package/src/room/track/create.ts +24 -9
@@ -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.
|
11189
|
+
var version$1 = "2.11.1";
|
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
|
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,
|
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
|
-
|
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 (
|
20397
|
+
if (options.audio) {
|
20218
20398
|
this.microphoneError = err;
|
20219
20399
|
}
|
20220
|
-
if (
|
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';
|