@stream-io/video-client 0.3.28 → 0.3.30
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/CHANGELOG.md +14 -0
- package/README.md +6 -4
- package/dist/index.browser.es.js +382 -118
- package/dist/index.browser.es.js.map +1 -1
- package/dist/index.cjs.js +382 -116
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +382 -118
- package/dist/index.es.js.map +1 -1
- package/dist/src/Call.d.ts +14 -10
- package/dist/src/devices/CameraManager.d.ts +0 -1
- package/dist/src/devices/InputMediaDeviceManager.d.ts +18 -15
- package/dist/src/devices/InputMediaDeviceManagerState.d.ts +22 -6
- package/dist/src/devices/MicrophoneManager.d.ts +0 -1
- package/dist/src/devices/ScreenShareManager.d.ts +39 -0
- package/dist/src/devices/ScreenShareState.d.ts +36 -0
- package/dist/src/devices/__tests__/ScreenShareManager.test.d.ts +1 -0
- package/dist/src/devices/__tests__/mocks.d.ts +3 -7
- package/dist/src/devices/index.d.ts +2 -0
- package/dist/src/helpers/DynascaleManager.d.ts +3 -2
- package/dist/src/helpers/__tests__/hq-audio-sdp.d.ts +1 -0
- package/dist/src/helpers/sdp-munging.d.ts +8 -0
- package/dist/src/rtc/Publisher.d.ts +7 -4
- package/dist/src/rtc/helpers/tracks.d.ts +2 -1
- package/dist/src/rtc/videoLayers.d.ts +2 -1
- package/dist/src/types.d.ts +20 -0
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/Call.ts +56 -12
- package/src/devices/CameraManager.ts +3 -4
- package/src/devices/InputMediaDeviceManager.ts +60 -45
- package/src/devices/InputMediaDeviceManagerState.ts +34 -14
- package/src/devices/MicrophoneManager.ts +3 -4
- package/src/devices/ScreenShareManager.ts +85 -0
- package/src/devices/ScreenShareState.ts +63 -0
- package/src/devices/__tests__/InputMediaDeviceManager.test.ts +16 -1
- package/src/devices/__tests__/ScreenShareManager.test.ts +119 -0
- package/src/devices/__tests__/mocks.ts +38 -1
- package/src/devices/devices.ts +10 -1
- package/src/devices/index.ts +2 -0
- package/src/helpers/DynascaleManager.ts +18 -3
- package/src/helpers/__tests__/DynascaleManager.test.ts +36 -1
- package/src/helpers/__tests__/hq-audio-sdp.ts +332 -0
- package/src/helpers/__tests__/sdp-munging.test.ts +13 -1
- package/src/helpers/sdp-munging.ts +49 -0
- package/src/rtc/Publisher.ts +87 -48
- package/src/rtc/Subscriber.ts +4 -1
- package/src/rtc/helpers/tracks.ts +16 -6
- package/src/rtc/videoLayers.ts +4 -2
- package/src/store/CallState.ts +3 -2
- package/src/store/__tests__/CallState.test.ts +1 -1
- package/src/types.ts +27 -0
package/dist/index.cjs.js
CHANGED
|
@@ -6219,7 +6219,8 @@ const withSimulcastConstraints = (settings, optimalVideoLayers) => {
|
|
|
6219
6219
|
const ridMapping = ['q', 'h', 'f'];
|
|
6220
6220
|
return layers.map((layer, index) => (Object.assign(Object.assign({}, layer), { rid: ridMapping[index] })));
|
|
6221
6221
|
};
|
|
6222
|
-
const findOptimalScreenSharingLayers = (videoTrack) => {
|
|
6222
|
+
const findOptimalScreenSharingLayers = (videoTrack, preferences) => {
|
|
6223
|
+
var _a, _b;
|
|
6223
6224
|
const settings = videoTrack.getSettings();
|
|
6224
6225
|
return [
|
|
6225
6226
|
{
|
|
@@ -6227,9 +6228,9 @@ const findOptimalScreenSharingLayers = (videoTrack) => {
|
|
|
6227
6228
|
rid: 'q',
|
|
6228
6229
|
width: settings.width || 0,
|
|
6229
6230
|
height: settings.height || 0,
|
|
6230
|
-
maxBitrate: 3000000,
|
|
6231
6231
|
scaleResolutionDownBy: 1,
|
|
6232
|
-
|
|
6232
|
+
maxBitrate: (_a = preferences === null || preferences === void 0 ? void 0 : preferences.maxBitrate) !== null && _a !== void 0 ? _a : 3000000,
|
|
6233
|
+
maxFramerate: (_b = preferences === null || preferences === void 0 ? void 0 : preferences.maxFramerate) !== null && _b !== void 0 ? _b : 30,
|
|
6233
6234
|
},
|
|
6234
6235
|
];
|
|
6235
6236
|
};
|
|
@@ -6238,12 +6239,17 @@ const trackTypeToParticipantStreamKey = (trackType) => {
|
|
|
6238
6239
|
switch (trackType) {
|
|
6239
6240
|
case TrackType.SCREEN_SHARE:
|
|
6240
6241
|
return 'screenShareStream';
|
|
6242
|
+
case TrackType.SCREEN_SHARE_AUDIO:
|
|
6243
|
+
return 'screenShareAudioStream';
|
|
6241
6244
|
case TrackType.VIDEO:
|
|
6242
6245
|
return 'videoStream';
|
|
6243
6246
|
case TrackType.AUDIO:
|
|
6244
6247
|
return 'audioStream';
|
|
6248
|
+
case TrackType.UNSPECIFIED:
|
|
6249
|
+
throw new Error('Track type is unspecified');
|
|
6245
6250
|
default:
|
|
6246
|
-
|
|
6251
|
+
const exhaustiveTrackTypeCheck = trackType;
|
|
6252
|
+
throw new Error(`Unknown track type: ${exhaustiveTrackTypeCheck}`);
|
|
6247
6253
|
}
|
|
6248
6254
|
};
|
|
6249
6255
|
const trackTypeToDeviceIdKey = (trackType) => {
|
|
@@ -6253,9 +6259,12 @@ const trackTypeToDeviceIdKey = (trackType) => {
|
|
|
6253
6259
|
case TrackType.VIDEO:
|
|
6254
6260
|
return 'videoDeviceId';
|
|
6255
6261
|
case TrackType.SCREEN_SHARE:
|
|
6262
|
+
case TrackType.SCREEN_SHARE_AUDIO:
|
|
6263
|
+
case TrackType.UNSPECIFIED:
|
|
6256
6264
|
return undefined;
|
|
6257
6265
|
default:
|
|
6258
|
-
|
|
6266
|
+
const exhaustiveTrackTypeCheck = trackType;
|
|
6267
|
+
throw new Error(`Unknown track type: ${exhaustiveTrackTypeCheck}`);
|
|
6259
6268
|
}
|
|
6260
6269
|
};
|
|
6261
6270
|
const muteTypeToTrackType = (muteType) => {
|
|
@@ -6266,8 +6275,11 @@ const muteTypeToTrackType = (muteType) => {
|
|
|
6266
6275
|
return TrackType.VIDEO;
|
|
6267
6276
|
case 'screenshare':
|
|
6268
6277
|
return TrackType.SCREEN_SHARE;
|
|
6278
|
+
case 'screenshare_audio':
|
|
6279
|
+
return TrackType.SCREEN_SHARE_AUDIO;
|
|
6269
6280
|
default:
|
|
6270
|
-
|
|
6281
|
+
const exhaustiveMuteTypeCheck = muteType;
|
|
6282
|
+
throw new Error(`Unknown mute type: ${exhaustiveMuteTypeCheck}`);
|
|
6271
6283
|
}
|
|
6272
6284
|
};
|
|
6273
6285
|
|
|
@@ -6383,6 +6395,41 @@ const toggleDtx = (sdp, enable) => {
|
|
|
6383
6395
|
}
|
|
6384
6396
|
return sdp;
|
|
6385
6397
|
};
|
|
6398
|
+
/**
|
|
6399
|
+
* Enables high-quality audio through SDP munging for the given trackMid.
|
|
6400
|
+
*
|
|
6401
|
+
* @param sdp the SDP to munge.
|
|
6402
|
+
* @param trackMid the trackMid.
|
|
6403
|
+
* @param maxBitrate the max bitrate to set.
|
|
6404
|
+
*/
|
|
6405
|
+
const enableHighQualityAudio = (sdp, trackMid, maxBitrate = 510000) => {
|
|
6406
|
+
maxBitrate = Math.max(Math.min(maxBitrate, 510000), 96000);
|
|
6407
|
+
const parsedSdp = SDP__namespace.parse(sdp);
|
|
6408
|
+
const audioMedia = parsedSdp.media.find((m) => m.type === 'audio' && String(m.mid) === trackMid);
|
|
6409
|
+
if (!audioMedia)
|
|
6410
|
+
return sdp;
|
|
6411
|
+
const opusRtp = audioMedia.rtp.find((r) => r.codec === 'opus');
|
|
6412
|
+
if (!opusRtp)
|
|
6413
|
+
return sdp;
|
|
6414
|
+
const opusFmtp = audioMedia.fmtp.find((f) => f.payload === opusRtp.payload);
|
|
6415
|
+
if (!opusFmtp)
|
|
6416
|
+
return sdp;
|
|
6417
|
+
// enable stereo, if not already enabled
|
|
6418
|
+
if (opusFmtp.config.match(/stereo=(\d)/)) {
|
|
6419
|
+
opusFmtp.config = opusFmtp.config.replace(/stereo=(\d)/, 'stereo=1');
|
|
6420
|
+
}
|
|
6421
|
+
else {
|
|
6422
|
+
opusFmtp.config = `${opusFmtp.config};stereo=1`;
|
|
6423
|
+
}
|
|
6424
|
+
// set maxaveragebitrate, to the given value
|
|
6425
|
+
if (opusFmtp.config.match(/maxaveragebitrate=(\d*)/)) {
|
|
6426
|
+
opusFmtp.config = opusFmtp.config.replace(/maxaveragebitrate=(\d*)/, `maxaveragebitrate=${maxBitrate}`);
|
|
6427
|
+
}
|
|
6428
|
+
else {
|
|
6429
|
+
opusFmtp.config = `${opusFmtp.config};maxaveragebitrate=${maxBitrate}`;
|
|
6430
|
+
}
|
|
6431
|
+
return SDP__namespace.write(parsedSdp);
|
|
6432
|
+
};
|
|
6386
6433
|
|
|
6387
6434
|
const logger$3 = getLogger(['Publisher']);
|
|
6388
6435
|
/**
|
|
@@ -6409,6 +6456,7 @@ class Publisher {
|
|
|
6409
6456
|
[TrackType.SCREEN_SHARE_AUDIO]: undefined,
|
|
6410
6457
|
[TrackType.UNSPECIFIED]: undefined,
|
|
6411
6458
|
};
|
|
6459
|
+
this.publishOptionsPerTrackType = new Map();
|
|
6412
6460
|
/**
|
|
6413
6461
|
* An array maintaining the order how transceivers were added to the peer connection.
|
|
6414
6462
|
* This is needed because some browsers (Firefox) don't reliably report
|
|
@@ -6421,7 +6469,7 @@ class Publisher {
|
|
|
6421
6469
|
[TrackType.AUDIO]: 'audio',
|
|
6422
6470
|
[TrackType.VIDEO]: 'video',
|
|
6423
6471
|
[TrackType.SCREEN_SHARE]: 'video',
|
|
6424
|
-
[TrackType.SCREEN_SHARE_AUDIO]:
|
|
6472
|
+
[TrackType.SCREEN_SHARE_AUDIO]: 'audio',
|
|
6425
6473
|
[TrackType.UNSPECIFIED]: undefined,
|
|
6426
6474
|
};
|
|
6427
6475
|
this.trackLayersCache = {
|
|
@@ -6466,10 +6514,11 @@ class Publisher {
|
|
|
6466
6514
|
*
|
|
6467
6515
|
* Consecutive calls to this method will replace the stream.
|
|
6468
6516
|
* The previous stream will be stopped.
|
|
6469
|
-
*
|
|
6470
|
-
* @param
|
|
6471
|
-
* @param
|
|
6472
|
-
* @param
|
|
6517
|
+
*
|
|
6518
|
+
* @param mediaStream the media stream to publish.
|
|
6519
|
+
* @param track the track to publish.
|
|
6520
|
+
* @param trackType the track type to publish.
|
|
6521
|
+
* @param opts the optional publish options to use.
|
|
6473
6522
|
*/
|
|
6474
6523
|
this.publishStream = (mediaStream, track, trackType, opts = {}) => __awaiter(this, void 0, void 0, function* () {
|
|
6475
6524
|
var _a;
|
|
@@ -6499,7 +6548,9 @@ class Publisher {
|
|
|
6499
6548
|
const targetResolution = settings === null || settings === void 0 ? void 0 : settings.video.target_resolution;
|
|
6500
6549
|
const videoEncodings = trackType === TrackType.VIDEO
|
|
6501
6550
|
? findOptimalVideoLayers(track, targetResolution)
|
|
6502
|
-
:
|
|
6551
|
+
: trackType === TrackType.SCREEN_SHARE
|
|
6552
|
+
? findOptimalScreenSharingLayers(track, opts.screenShareSettings)
|
|
6553
|
+
: undefined;
|
|
6503
6554
|
let preferredCodec = opts.preferredCodec;
|
|
6504
6555
|
if (!preferredCodec && trackType === TrackType.VIDEO) {
|
|
6505
6556
|
const isRNAndroid = isReactNative() && ((_a = getOSInfo()) === null || _a === void 0 ? void 0 : _a.name.toLowerCase()) === 'android';
|
|
@@ -6525,6 +6576,7 @@ class Publisher {
|
|
|
6525
6576
|
logger$3('debug', `Added ${TrackType[trackType]} transceiver`);
|
|
6526
6577
|
this.transceiverInitOrder.push(trackType);
|
|
6527
6578
|
this.transceiverRegistry[trackType] = transceiver;
|
|
6579
|
+
this.publishOptionsPerTrackType.set(trackType, opts);
|
|
6528
6580
|
if ('setCodecPreferences' in transceiver && codecPreferences) {
|
|
6529
6581
|
logger$3('info', `Setting ${TrackType[trackType]} codec preferences`, codecPreferences);
|
|
6530
6582
|
transceiver.setCodecPreferences(codecPreferences);
|
|
@@ -6734,10 +6786,19 @@ class Publisher {
|
|
|
6734
6786
|
* @param options the optional offer options to use.
|
|
6735
6787
|
*/
|
|
6736
6788
|
this.negotiate = (options) => __awaiter(this, void 0, void 0, function* () {
|
|
6737
|
-
var _d;
|
|
6789
|
+
var _d, _e;
|
|
6738
6790
|
this.isIceRestarting = (_d = options === null || options === void 0 ? void 0 : options.iceRestart) !== null && _d !== void 0 ? _d : false;
|
|
6739
6791
|
const offer = yield this.pc.createOffer(options);
|
|
6740
|
-
|
|
6792
|
+
let sdp = this.mungeCodecs(offer.sdp);
|
|
6793
|
+
if (sdp && this.isPublishing(TrackType.SCREEN_SHARE_AUDIO)) {
|
|
6794
|
+
const transceiver = this.transceiverRegistry[TrackType.SCREEN_SHARE_AUDIO];
|
|
6795
|
+
if (transceiver && transceiver.sender.track) {
|
|
6796
|
+
const mid = (_e = transceiver.mid) !== null && _e !== void 0 ? _e : this.extractMid(sdp, transceiver.sender.track, TrackType.SCREEN_SHARE_AUDIO);
|
|
6797
|
+
sdp = enableHighQualityAudio(sdp, mid);
|
|
6798
|
+
}
|
|
6799
|
+
}
|
|
6800
|
+
// set the munged SDP back to the offer
|
|
6801
|
+
offer.sdp = sdp;
|
|
6741
6802
|
const trackInfos = this.getCurrentTrackInfos(offer.sdp);
|
|
6742
6803
|
if (trackInfos.length === 0) {
|
|
6743
6804
|
throw new Error(`Can't initiate negotiation without announcing any tracks`);
|
|
@@ -6776,50 +6837,50 @@ class Publisher {
|
|
|
6776
6837
|
}
|
|
6777
6838
|
return sdp;
|
|
6778
6839
|
};
|
|
6840
|
+
this.extractMid = (sdp, track, trackType) => {
|
|
6841
|
+
if (!sdp) {
|
|
6842
|
+
logger$3('warn', 'No SDP found. Returning empty mid');
|
|
6843
|
+
return '';
|
|
6844
|
+
}
|
|
6845
|
+
logger$3('debug', `No 'mid' found for track. Trying to find it from the Offer SDP`);
|
|
6846
|
+
const parsedSdp = SDP__namespace.parse(sdp);
|
|
6847
|
+
const media = parsedSdp.media.find((m) => {
|
|
6848
|
+
var _a, _b;
|
|
6849
|
+
return (m.type === track.kind &&
|
|
6850
|
+
// if `msid` is not present, we assume that the track is the first one
|
|
6851
|
+
((_b = (_a = m.msid) === null || _a === void 0 ? void 0 : _a.includes(track.id)) !== null && _b !== void 0 ? _b : true));
|
|
6852
|
+
});
|
|
6853
|
+
if (typeof (media === null || media === void 0 ? void 0 : media.mid) === 'undefined') {
|
|
6854
|
+
logger$3('debug', `No mid found in SDP for track type ${track.kind} and id ${track.id}. Attempting to find a heuristic mid`);
|
|
6855
|
+
const heuristicMid = this.transceiverInitOrder.indexOf(trackType);
|
|
6856
|
+
if (heuristicMid !== -1) {
|
|
6857
|
+
return String(heuristicMid);
|
|
6858
|
+
}
|
|
6859
|
+
logger$3('debug', 'No heuristic mid found. Returning empty mid');
|
|
6860
|
+
return '';
|
|
6861
|
+
}
|
|
6862
|
+
return String(media.mid);
|
|
6863
|
+
};
|
|
6779
6864
|
this.getCurrentTrackInfos = (sdp) => {
|
|
6780
6865
|
var _a;
|
|
6781
6866
|
sdp = sdp || ((_a = this.pc.localDescription) === null || _a === void 0 ? void 0 : _a.sdp);
|
|
6782
|
-
const extractMid = (defaultMid, track, trackType) => {
|
|
6783
|
-
if (defaultMid)
|
|
6784
|
-
return defaultMid;
|
|
6785
|
-
if (!sdp) {
|
|
6786
|
-
logger$3('warn', 'No SDP found. Returning empty mid');
|
|
6787
|
-
return '';
|
|
6788
|
-
}
|
|
6789
|
-
logger$3('debug', `No 'mid' found for track. Trying to find it from the Offer SDP`);
|
|
6790
|
-
const parsedSdp = SDP__namespace.parse(sdp);
|
|
6791
|
-
const media = parsedSdp.media.find((m) => {
|
|
6792
|
-
var _a, _b;
|
|
6793
|
-
return (m.type === track.kind &&
|
|
6794
|
-
// if `msid` is not present, we assume that the track is the first one
|
|
6795
|
-
((_b = (_a = m.msid) === null || _a === void 0 ? void 0 : _a.includes(track.id)) !== null && _b !== void 0 ? _b : true));
|
|
6796
|
-
});
|
|
6797
|
-
if (typeof (media === null || media === void 0 ? void 0 : media.mid) === 'undefined') {
|
|
6798
|
-
logger$3('debug', `No mid found in SDP for track type ${track.kind} and id ${track.id}. Attempting to find a heuristic mid`);
|
|
6799
|
-
const heuristicMid = this.transceiverInitOrder.indexOf(trackType);
|
|
6800
|
-
if (heuristicMid !== -1) {
|
|
6801
|
-
return String(heuristicMid);
|
|
6802
|
-
}
|
|
6803
|
-
logger$3('debug', 'No heuristic mid found. Returning empty mid');
|
|
6804
|
-
return '';
|
|
6805
|
-
}
|
|
6806
|
-
return String(media.mid);
|
|
6807
|
-
};
|
|
6808
6867
|
const { settings } = this.state;
|
|
6809
6868
|
const targetResolution = settings === null || settings === void 0 ? void 0 : settings.video.target_resolution;
|
|
6810
6869
|
return this.pc
|
|
6811
6870
|
.getTransceivers()
|
|
6812
6871
|
.filter((t) => t.direction === 'sendonly' && t.sender.track)
|
|
6813
6872
|
.map((transceiver) => {
|
|
6873
|
+
var _a;
|
|
6814
6874
|
const trackType = Number(Object.keys(this.transceiverRegistry).find((key) => this.transceiverRegistry[key] === transceiver));
|
|
6815
6875
|
const track = transceiver.sender.track;
|
|
6816
6876
|
let optimalLayers;
|
|
6817
6877
|
if (track.readyState === 'live') {
|
|
6878
|
+
const publishOpts = this.publishOptionsPerTrackType.get(trackType);
|
|
6818
6879
|
optimalLayers =
|
|
6819
6880
|
trackType === TrackType.VIDEO
|
|
6820
6881
|
? findOptimalVideoLayers(track, targetResolution)
|
|
6821
6882
|
: trackType === TrackType.SCREEN_SHARE
|
|
6822
|
-
? findOptimalScreenSharingLayers(track)
|
|
6883
|
+
? findOptimalScreenSharingLayers(track, publishOpts === null || publishOpts === void 0 ? void 0 : publishOpts.screenShareSettings)
|
|
6823
6884
|
: [];
|
|
6824
6885
|
this.trackLayersCache[trackType] = optimalLayers;
|
|
6825
6886
|
}
|
|
@@ -6838,15 +6899,21 @@ class Publisher {
|
|
|
6838
6899
|
height: optimalLayer.height,
|
|
6839
6900
|
},
|
|
6840
6901
|
}));
|
|
6902
|
+
const isAudioTrack = [
|
|
6903
|
+
TrackType.AUDIO,
|
|
6904
|
+
TrackType.SCREEN_SHARE_AUDIO,
|
|
6905
|
+
].includes(trackType);
|
|
6906
|
+
const trackSettings = track.getSettings();
|
|
6907
|
+
// @ts-expect-error - `channelCount` is not defined on `MediaTrackSettings`
|
|
6908
|
+
const isStereo = isAudioTrack && trackSettings.channelCount === 2;
|
|
6841
6909
|
return {
|
|
6842
6910
|
trackId: track.id,
|
|
6843
6911
|
layers: layers,
|
|
6844
6912
|
trackType,
|
|
6845
|
-
mid:
|
|
6846
|
-
|
|
6847
|
-
|
|
6848
|
-
|
|
6849
|
-
red: TrackType.AUDIO === trackType && this.isRedEnabled,
|
|
6913
|
+
mid: (_a = transceiver.mid) !== null && _a !== void 0 ? _a : this.extractMid(sdp, track, trackType),
|
|
6914
|
+
stereo: isStereo,
|
|
6915
|
+
dtx: isAudioTrack && this.isDtxEnabled,
|
|
6916
|
+
red: isAudioTrack && this.isRedEnabled,
|
|
6850
6917
|
};
|
|
6851
6918
|
});
|
|
6852
6919
|
};
|
|
@@ -7064,6 +7131,7 @@ class Subscriber {
|
|
|
7064
7131
|
TRACK_TYPE_AUDIO: 'audioStream',
|
|
7065
7132
|
TRACK_TYPE_VIDEO: 'videoStream',
|
|
7066
7133
|
TRACK_TYPE_SCREEN_SHARE: 'screenShareStream',
|
|
7134
|
+
TRACK_TYPE_SCREEN_SHARE_AUDIO: 'screenShareAudioStream',
|
|
7067
7135
|
}[trackType];
|
|
7068
7136
|
if (!streamKindProp) {
|
|
7069
7137
|
logger$2('error', `Unknown track type: ${trackType}`);
|
|
@@ -7152,7 +7220,8 @@ class Subscriber {
|
|
|
7152
7220
|
this.onIceCandidateError = (e) => {
|
|
7153
7221
|
const errorMessage = e instanceof RTCPeerConnectionIceErrorEvent &&
|
|
7154
7222
|
`${e.errorCode}: ${e.errorText}`;
|
|
7155
|
-
|
|
7223
|
+
const logLevel = this.pc.iceConnectionState === 'connected' ? 'debug' : 'error';
|
|
7224
|
+
logger$2(logLevel, `ICE Candidate error`, errorMessage);
|
|
7156
7225
|
};
|
|
7157
7226
|
this.sfuClient = sfuClient;
|
|
7158
7227
|
this.dispatcher = dispatcher;
|
|
@@ -8357,8 +8426,9 @@ class CallState {
|
|
|
8357
8426
|
};
|
|
8358
8427
|
this.logger = getLogger(['CallState']);
|
|
8359
8428
|
this.participants$ = this.participantsSubject.asObservable().pipe(
|
|
8360
|
-
//
|
|
8361
|
-
|
|
8429
|
+
// maintain stable-sort by mutating the participants stored
|
|
8430
|
+
// in the original subject
|
|
8431
|
+
operators.map((ps) => ps.sort(this.sortParticipantsBy)), operators.shareReplay({ bufferSize: 1, refCount: true }));
|
|
8362
8432
|
this.localParticipant$ = this.participants$.pipe(operators.map((participants) => participants.find(isStreamVideoLocalParticipant)), operators.shareReplay({ bufferSize: 1, refCount: true }));
|
|
8363
8433
|
this.remoteParticipants$ = this.participants$.pipe(operators.map((participants) => participants.filter((p) => !p.isLocalParticipant)), operators.shareReplay({ bufferSize: 1, refCount: true }));
|
|
8364
8434
|
this.pinnedParticipants$ = this.participants$.pipe(operators.map((participants) => participants.filter((p) => !!p.pin)), operators.shareReplay({ bufferSize: 1, refCount: true }));
|
|
@@ -9664,17 +9734,22 @@ class DynascaleManager {
|
|
|
9664
9734
|
*
|
|
9665
9735
|
* @param audioElement the audio element to bind to.
|
|
9666
9736
|
* @param sessionId the session id.
|
|
9737
|
+
* @param trackType the kind of audio.
|
|
9667
9738
|
* @returns a cleanup function that will unbind the audio element.
|
|
9668
9739
|
*/
|
|
9669
|
-
this.bindAudioElement = (audioElement, sessionId) => {
|
|
9740
|
+
this.bindAudioElement = (audioElement, sessionId, trackType) => {
|
|
9670
9741
|
const participant = this.call.state.findParticipantBySessionId(sessionId);
|
|
9671
9742
|
if (!participant || participant.isLocalParticipant)
|
|
9672
9743
|
return;
|
|
9673
9744
|
const participant$ = this.call.state.participants$.pipe(rxjs.map((participants) => participants.find((p) => p.sessionId === sessionId)), rxjs.takeWhile((p) => !!p), rxjs.distinctUntilChanged(), rxjs.shareReplay({ bufferSize: 1, refCount: true }));
|
|
9674
9745
|
const updateMediaStreamSubscription = participant$
|
|
9675
|
-
.pipe(rxjs.distinctUntilKeyChanged('
|
|
9746
|
+
.pipe(rxjs.distinctUntilKeyChanged(trackType === 'screenShareAudioTrack'
|
|
9747
|
+
? 'screenShareAudioStream'
|
|
9748
|
+
: 'audioStream'))
|
|
9676
9749
|
.subscribe((p) => {
|
|
9677
|
-
const source =
|
|
9750
|
+
const source = trackType === 'screenShareAudioTrack'
|
|
9751
|
+
? p.screenShareAudioStream
|
|
9752
|
+
: p.audioStream;
|
|
9678
9753
|
if (audioElement.srcObject === source)
|
|
9679
9754
|
return;
|
|
9680
9755
|
setTimeout(() => {
|
|
@@ -9989,7 +10064,16 @@ const getVideoStream = (trackConstraints) => __awaiter(void 0, void 0, void 0, f
|
|
|
9989
10064
|
*/
|
|
9990
10065
|
const getScreenShareStream = (options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
9991
10066
|
try {
|
|
9992
|
-
return yield navigator.mediaDevices.getDisplayMedia(Object.assign({ video: true, audio:
|
|
10067
|
+
return yield navigator.mediaDevices.getDisplayMedia(Object.assign({ video: true, audio: {
|
|
10068
|
+
channelCount: {
|
|
10069
|
+
ideal: 2,
|
|
10070
|
+
},
|
|
10071
|
+
echoCancellation: false,
|
|
10072
|
+
autoGainControl: false,
|
|
10073
|
+
noiseSuppression: false,
|
|
10074
|
+
},
|
|
10075
|
+
// @ts-expect-error - not present in types yet
|
|
10076
|
+
systemAudio: 'include' }, options));
|
|
9993
10077
|
}
|
|
9994
10078
|
catch (e) {
|
|
9995
10079
|
getLogger(['devices'])('error', 'Failed to get screen share stream', e);
|
|
@@ -10118,7 +10202,7 @@ class InputMediaDeviceManager {
|
|
|
10118
10202
|
return this.getDevices();
|
|
10119
10203
|
}
|
|
10120
10204
|
/**
|
|
10121
|
-
* Starts
|
|
10205
|
+
* Starts stream.
|
|
10122
10206
|
*/
|
|
10123
10207
|
enable() {
|
|
10124
10208
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -10137,9 +10221,7 @@ class InputMediaDeviceManager {
|
|
|
10137
10221
|
});
|
|
10138
10222
|
}
|
|
10139
10223
|
/**
|
|
10140
|
-
* Stops
|
|
10141
|
-
*
|
|
10142
|
-
* @returns
|
|
10224
|
+
* Stops the stream.
|
|
10143
10225
|
*/
|
|
10144
10226
|
disable() {
|
|
10145
10227
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -10160,7 +10242,7 @@ class InputMediaDeviceManager {
|
|
|
10160
10242
|
});
|
|
10161
10243
|
}
|
|
10162
10244
|
/**
|
|
10163
|
-
* If status was previously enabled, it will
|
|
10245
|
+
* If status was previously enabled, it will re-enable the device.
|
|
10164
10246
|
*/
|
|
10165
10247
|
resume() {
|
|
10166
10248
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -10171,9 +10253,8 @@ class InputMediaDeviceManager {
|
|
|
10171
10253
|
});
|
|
10172
10254
|
}
|
|
10173
10255
|
/**
|
|
10174
|
-
* If current device
|
|
10175
|
-
*
|
|
10176
|
-
* @returns
|
|
10256
|
+
* If the current device status is disabled, it will enable the device,
|
|
10257
|
+
* else it will disable it.
|
|
10177
10258
|
*/
|
|
10178
10259
|
toggle() {
|
|
10179
10260
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -10185,6 +10266,16 @@ class InputMediaDeviceManager {
|
|
|
10185
10266
|
}
|
|
10186
10267
|
});
|
|
10187
10268
|
}
|
|
10269
|
+
/**
|
|
10270
|
+
* Will set the default constraints for the device.
|
|
10271
|
+
*
|
|
10272
|
+
* @param constraints the constraints to set.
|
|
10273
|
+
*/
|
|
10274
|
+
setDefaultConstraints(constraints) {
|
|
10275
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
10276
|
+
this.state.setDefaultConstraints(constraints);
|
|
10277
|
+
});
|
|
10278
|
+
}
|
|
10188
10279
|
/**
|
|
10189
10280
|
* Select device
|
|
10190
10281
|
*
|
|
@@ -10212,8 +10303,11 @@ class InputMediaDeviceManager {
|
|
|
10212
10303
|
}
|
|
10213
10304
|
});
|
|
10214
10305
|
}
|
|
10306
|
+
getTracks() {
|
|
10307
|
+
var _a, _b;
|
|
10308
|
+
return (_b = (_a = this.state.mediaStream) === null || _a === void 0 ? void 0 : _a.getTracks()) !== null && _b !== void 0 ? _b : [];
|
|
10309
|
+
}
|
|
10215
10310
|
muteStream(stopTracks = true) {
|
|
10216
|
-
var _a;
|
|
10217
10311
|
return __awaiter(this, void 0, void 0, function* () {
|
|
10218
10312
|
if (!this.state.mediaStream) {
|
|
10219
10313
|
return;
|
|
@@ -10223,57 +10317,63 @@ class InputMediaDeviceManager {
|
|
|
10223
10317
|
yield this.stopPublishStream(stopTracks);
|
|
10224
10318
|
}
|
|
10225
10319
|
this.muteLocalStream(stopTracks);
|
|
10226
|
-
|
|
10227
|
-
|
|
10228
|
-
|
|
10229
|
-
//
|
|
10230
|
-
this.state.mediaStream.release
|
|
10320
|
+
this.getTracks().forEach((track) => {
|
|
10321
|
+
if (track.readyState === 'ended') {
|
|
10322
|
+
// @ts-expect-error release() is present in react-native-webrtc
|
|
10323
|
+
// and must be called to dispose the stream
|
|
10324
|
+
if (typeof this.state.mediaStream.release === 'function') {
|
|
10325
|
+
// @ts-expect-error
|
|
10326
|
+
this.state.mediaStream.release();
|
|
10327
|
+
}
|
|
10328
|
+
this.state.setMediaStream(undefined);
|
|
10231
10329
|
}
|
|
10232
|
-
|
|
10233
|
-
}
|
|
10330
|
+
});
|
|
10234
10331
|
});
|
|
10235
10332
|
}
|
|
10236
|
-
|
|
10237
|
-
|
|
10238
|
-
|
|
10239
|
-
|
|
10240
|
-
}
|
|
10241
|
-
track.enabled = false;
|
|
10333
|
+
muteTracks() {
|
|
10334
|
+
this.getTracks().forEach((track) => {
|
|
10335
|
+
if (track.enabled)
|
|
10336
|
+
track.enabled = false;
|
|
10337
|
+
});
|
|
10242
10338
|
}
|
|
10243
|
-
|
|
10244
|
-
|
|
10245
|
-
|
|
10246
|
-
|
|
10247
|
-
}
|
|
10248
|
-
track.enabled = true;
|
|
10339
|
+
unmuteTracks() {
|
|
10340
|
+
this.getTracks().forEach((track) => {
|
|
10341
|
+
if (!track.enabled)
|
|
10342
|
+
track.enabled = true;
|
|
10343
|
+
});
|
|
10249
10344
|
}
|
|
10250
|
-
|
|
10251
|
-
|
|
10252
|
-
|
|
10253
|
-
|
|
10254
|
-
}
|
|
10255
|
-
track.stop();
|
|
10345
|
+
stopTracks() {
|
|
10346
|
+
this.getTracks().forEach((track) => {
|
|
10347
|
+
if (track.readyState === 'live')
|
|
10348
|
+
track.stop();
|
|
10349
|
+
});
|
|
10256
10350
|
}
|
|
10257
10351
|
muteLocalStream(stopTracks) {
|
|
10258
10352
|
if (!this.state.mediaStream) {
|
|
10259
10353
|
return;
|
|
10260
10354
|
}
|
|
10261
|
-
|
|
10355
|
+
if (stopTracks) {
|
|
10356
|
+
this.stopTracks();
|
|
10357
|
+
}
|
|
10358
|
+
else {
|
|
10359
|
+
this.muteTracks();
|
|
10360
|
+
}
|
|
10262
10361
|
}
|
|
10263
10362
|
unmuteStream() {
|
|
10264
|
-
var _a;
|
|
10265
10363
|
return __awaiter(this, void 0, void 0, function* () {
|
|
10266
10364
|
this.logger('debug', 'Starting stream');
|
|
10267
10365
|
let stream;
|
|
10268
|
-
if (this.state.mediaStream &&
|
|
10366
|
+
if (this.state.mediaStream &&
|
|
10367
|
+
this.getTracks().every((t) => t.readyState === 'live')) {
|
|
10269
10368
|
stream = this.state.mediaStream;
|
|
10270
|
-
this.
|
|
10369
|
+
this.unmuteTracks();
|
|
10271
10370
|
}
|
|
10272
10371
|
else {
|
|
10273
10372
|
if (this.state.mediaStream) {
|
|
10274
|
-
this.
|
|
10373
|
+
this.stopTracks();
|
|
10275
10374
|
}
|
|
10276
|
-
const
|
|
10375
|
+
const defaultConstraints = this.state.defaultConstraints;
|
|
10376
|
+
const constraints = Object.assign(Object.assign({}, defaultConstraints), { deviceId: this.state.selectedDevice });
|
|
10277
10377
|
stream = yield this.getStream(constraints);
|
|
10278
10378
|
}
|
|
10279
10379
|
if (this.call.state.callingState === exports.CallingState.JOINED) {
|
|
@@ -10292,6 +10392,26 @@ class InputMediaDeviceManagerState {
|
|
|
10292
10392
|
this.statusSubject = new rxjs.BehaviorSubject(undefined);
|
|
10293
10393
|
this.mediaStreamSubject = new rxjs.BehaviorSubject(undefined);
|
|
10294
10394
|
this.selectedDeviceSubject = new rxjs.BehaviorSubject(undefined);
|
|
10395
|
+
this.defaultConstraintsSubject = new rxjs.BehaviorSubject(undefined);
|
|
10396
|
+
/**
|
|
10397
|
+
* An Observable that emits the current media stream, or `undefined` if the device is currently disabled.
|
|
10398
|
+
*
|
|
10399
|
+
*/
|
|
10400
|
+
this.mediaStream$ = this.mediaStreamSubject.asObservable();
|
|
10401
|
+
/**
|
|
10402
|
+
* An Observable that emits the currently selected device
|
|
10403
|
+
*/
|
|
10404
|
+
this.selectedDevice$ = this.selectedDeviceSubject
|
|
10405
|
+
.asObservable()
|
|
10406
|
+
.pipe(rxjs.distinctUntilChanged());
|
|
10407
|
+
/**
|
|
10408
|
+
* An Observable that emits the device status
|
|
10409
|
+
*/
|
|
10410
|
+
this.status$ = this.statusSubject.asObservable().pipe(rxjs.distinctUntilChanged());
|
|
10411
|
+
/**
|
|
10412
|
+
* The default constraints for the device.
|
|
10413
|
+
*/
|
|
10414
|
+
this.defaultConstraints$ = this.defaultConstraintsSubject.asObservable();
|
|
10295
10415
|
/**
|
|
10296
10416
|
* Gets the current value of an observable, or undefined if the observable has
|
|
10297
10417
|
* not emitted a value yet.
|
|
@@ -10311,13 +10431,6 @@ class InputMediaDeviceManagerState {
|
|
|
10311
10431
|
* @return the updated value.
|
|
10312
10432
|
*/
|
|
10313
10433
|
this.setCurrentValue = setCurrentValue;
|
|
10314
|
-
this.mediaStream$ = this.mediaStreamSubject.asObservable();
|
|
10315
|
-
this.selectedDevice$ = this.selectedDeviceSubject
|
|
10316
|
-
.asObservable()
|
|
10317
|
-
.pipe(rxjs.distinctUntilChanged());
|
|
10318
|
-
this.status$ = this.statusSubject
|
|
10319
|
-
.asObservable()
|
|
10320
|
-
.pipe(rxjs.distinctUntilChanged());
|
|
10321
10434
|
}
|
|
10322
10435
|
/**
|
|
10323
10436
|
* The device status
|
|
@@ -10361,6 +10474,21 @@ class InputMediaDeviceManagerState {
|
|
|
10361
10474
|
setDevice(deviceId) {
|
|
10362
10475
|
this.setCurrentValue(this.selectedDeviceSubject, deviceId);
|
|
10363
10476
|
}
|
|
10477
|
+
/**
|
|
10478
|
+
* Gets the default constraints for the device.
|
|
10479
|
+
*/
|
|
10480
|
+
get defaultConstraints() {
|
|
10481
|
+
return this.getCurrentValue(this.defaultConstraints$);
|
|
10482
|
+
}
|
|
10483
|
+
/**
|
|
10484
|
+
* Sets the default constraints for the device.
|
|
10485
|
+
*
|
|
10486
|
+
* @internal
|
|
10487
|
+
* @param constraints the constraints to set.
|
|
10488
|
+
*/
|
|
10489
|
+
setDefaultConstraints(constraints) {
|
|
10490
|
+
this.setCurrentValue(this.defaultConstraintsSubject, constraints);
|
|
10491
|
+
}
|
|
10364
10492
|
}
|
|
10365
10493
|
|
|
10366
10494
|
class CameraManagerState extends InputMediaDeviceManagerState {
|
|
@@ -10485,10 +10613,6 @@ class CameraManager extends InputMediaDeviceManager {
|
|
|
10485
10613
|
stopPublishStream(stopTracks) {
|
|
10486
10614
|
return this.call.stopPublish(TrackType.VIDEO, stopTracks);
|
|
10487
10615
|
}
|
|
10488
|
-
getTrack() {
|
|
10489
|
-
var _a;
|
|
10490
|
-
return (_a = this.state.mediaStream) === null || _a === void 0 ? void 0 : _a.getVideoTracks()[0];
|
|
10491
|
-
}
|
|
10492
10616
|
}
|
|
10493
10617
|
|
|
10494
10618
|
class MicrophoneManagerState extends InputMediaDeviceManagerState {
|
|
@@ -10613,10 +10737,6 @@ class MicrophoneManager extends InputMediaDeviceManager {
|
|
|
10613
10737
|
stopPublishStream(stopTracks) {
|
|
10614
10738
|
return this.call.stopPublish(TrackType.AUDIO, stopTracks);
|
|
10615
10739
|
}
|
|
10616
|
-
getTrack() {
|
|
10617
|
-
var _a;
|
|
10618
|
-
return (_a = this.state.mediaStream) === null || _a === void 0 ? void 0 : _a.getAudioTracks()[0];
|
|
10619
|
-
}
|
|
10620
10740
|
startSpeakingWhileMutedDetection(deviceId) {
|
|
10621
10741
|
return __awaiter(this, void 0, void 0, function* () {
|
|
10622
10742
|
if (isReactNative()) {
|
|
@@ -10648,6 +10768,128 @@ class MicrophoneManager extends InputMediaDeviceManager {
|
|
|
10648
10768
|
}
|
|
10649
10769
|
}
|
|
10650
10770
|
|
|
10771
|
+
class ScreenShareState extends InputMediaDeviceManagerState {
|
|
10772
|
+
constructor() {
|
|
10773
|
+
super(...arguments);
|
|
10774
|
+
this.audioEnabledSubject = new rxjs.BehaviorSubject(true);
|
|
10775
|
+
this.settingsSubject = new rxjs.BehaviorSubject(undefined);
|
|
10776
|
+
/**
|
|
10777
|
+
* An Observable that emits the current screen share audio status.
|
|
10778
|
+
*/
|
|
10779
|
+
this.audioEnabled$ = this.audioEnabledSubject
|
|
10780
|
+
.asObservable()
|
|
10781
|
+
.pipe(operators.distinctUntilChanged());
|
|
10782
|
+
/**
|
|
10783
|
+
* An Observable that emits the current screen share settings.
|
|
10784
|
+
*/
|
|
10785
|
+
this.settings$ = this.settingsSubject.asObservable();
|
|
10786
|
+
/**
|
|
10787
|
+
* @internal
|
|
10788
|
+
*/
|
|
10789
|
+
this.getDeviceIdFromStream = (stream) => {
|
|
10790
|
+
const [track] = stream.getTracks();
|
|
10791
|
+
return track === null || track === void 0 ? void 0 : track.getSettings().deviceId;
|
|
10792
|
+
};
|
|
10793
|
+
}
|
|
10794
|
+
/**
|
|
10795
|
+
* The current screen share audio status.
|
|
10796
|
+
*/
|
|
10797
|
+
get audioEnabled() {
|
|
10798
|
+
return this.getCurrentValue(this.audioEnabled$);
|
|
10799
|
+
}
|
|
10800
|
+
/**
|
|
10801
|
+
* Set the current screen share audio status.
|
|
10802
|
+
*/
|
|
10803
|
+
setAudioEnabled(isEnabled) {
|
|
10804
|
+
this.setCurrentValue(this.audioEnabledSubject, isEnabled);
|
|
10805
|
+
}
|
|
10806
|
+
/**
|
|
10807
|
+
* The current screen share settings.
|
|
10808
|
+
*/
|
|
10809
|
+
get settings() {
|
|
10810
|
+
return this.getCurrentValue(this.settings$);
|
|
10811
|
+
}
|
|
10812
|
+
/**
|
|
10813
|
+
* Set the current screen share settings.
|
|
10814
|
+
*
|
|
10815
|
+
* @param settings the screen share settings to set.
|
|
10816
|
+
*/
|
|
10817
|
+
setSettings(settings) {
|
|
10818
|
+
this.setCurrentValue(this.settingsSubject, settings);
|
|
10819
|
+
}
|
|
10820
|
+
}
|
|
10821
|
+
|
|
10822
|
+
class ScreenShareManager extends InputMediaDeviceManager {
|
|
10823
|
+
constructor(call) {
|
|
10824
|
+
super(call, new ScreenShareState(), TrackType.SCREEN_SHARE);
|
|
10825
|
+
}
|
|
10826
|
+
/**
|
|
10827
|
+
* Will enable screen share audio options on supported platforms.
|
|
10828
|
+
*
|
|
10829
|
+
* Note: for ongoing screen share, audio won't be enabled until you
|
|
10830
|
+
* re-publish the screen share stream.
|
|
10831
|
+
*/
|
|
10832
|
+
enableScreenShareAudio() {
|
|
10833
|
+
this.state.setAudioEnabled(true);
|
|
10834
|
+
}
|
|
10835
|
+
/**
|
|
10836
|
+
* Will disable screen share audio options on supported platforms.
|
|
10837
|
+
*/
|
|
10838
|
+
disableScreenShareAudio() {
|
|
10839
|
+
var _a;
|
|
10840
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
10841
|
+
this.state.setAudioEnabled(false);
|
|
10842
|
+
if ((_a = this.call.publisher) === null || _a === void 0 ? void 0 : _a.isPublishing(TrackType.SCREEN_SHARE_AUDIO)) {
|
|
10843
|
+
yield this.call.stopPublish(TrackType.SCREEN_SHARE_AUDIO, true);
|
|
10844
|
+
}
|
|
10845
|
+
});
|
|
10846
|
+
}
|
|
10847
|
+
/**
|
|
10848
|
+
* Returns the current screen share settings.
|
|
10849
|
+
*/
|
|
10850
|
+
getSettings() {
|
|
10851
|
+
return this.state.settings;
|
|
10852
|
+
}
|
|
10853
|
+
/**
|
|
10854
|
+
* Sets the current screen share settings.
|
|
10855
|
+
*
|
|
10856
|
+
* @param settings the settings to set.
|
|
10857
|
+
*/
|
|
10858
|
+
setSettings(settings) {
|
|
10859
|
+
this.state.setSettings(settings);
|
|
10860
|
+
}
|
|
10861
|
+
getDevices() {
|
|
10862
|
+
return rxjs.of([]); // there are no devices to be listed for Screen Share
|
|
10863
|
+
}
|
|
10864
|
+
getStream(constraints) {
|
|
10865
|
+
if (!this.state.audioEnabled) {
|
|
10866
|
+
constraints.audio = false;
|
|
10867
|
+
}
|
|
10868
|
+
return getScreenShareStream(constraints);
|
|
10869
|
+
}
|
|
10870
|
+
publishStream(stream) {
|
|
10871
|
+
return this.call.publishScreenShareStream(stream, {
|
|
10872
|
+
screenShareSettings: this.state.settings,
|
|
10873
|
+
});
|
|
10874
|
+
}
|
|
10875
|
+
stopPublishStream(stopTracks) {
|
|
10876
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
10877
|
+
yield this.call.stopPublish(TrackType.SCREEN_SHARE, stopTracks);
|
|
10878
|
+
yield this.call.stopPublish(TrackType.SCREEN_SHARE_AUDIO, stopTracks);
|
|
10879
|
+
});
|
|
10880
|
+
}
|
|
10881
|
+
/**
|
|
10882
|
+
* Overrides the default `select` method to throw an error.
|
|
10883
|
+
*
|
|
10884
|
+
* @param deviceId ignored.
|
|
10885
|
+
*/
|
|
10886
|
+
select(deviceId) {
|
|
10887
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
10888
|
+
throw new Error('This method is not supported in for Screen Share');
|
|
10889
|
+
});
|
|
10890
|
+
}
|
|
10891
|
+
}
|
|
10892
|
+
|
|
10651
10893
|
class SpeakerState {
|
|
10652
10894
|
constructor() {
|
|
10653
10895
|
this.selectedDeviceSubject = new rxjs.BehaviorSubject('');
|
|
@@ -11021,7 +11263,17 @@ class Call {
|
|
|
11021
11263
|
// as the underlying peer connection will take care of it as part
|
|
11022
11264
|
// of the ice-restart process
|
|
11023
11265
|
if (localParticipant && !migrate) {
|
|
11024
|
-
const { audioStream, videoStream, screenShareStream
|
|
11266
|
+
const { audioStream, videoStream, screenShareStream, screenShareAudioStream, } = localParticipant;
|
|
11267
|
+
let screenShare;
|
|
11268
|
+
if (screenShareStream || screenShareAudioStream) {
|
|
11269
|
+
screenShare = new MediaStream();
|
|
11270
|
+
screenShareStream === null || screenShareStream === void 0 ? void 0 : screenShareStream.getVideoTracks().forEach((track) => {
|
|
11271
|
+
screenShare === null || screenShare === void 0 ? void 0 : screenShare.addTrack(track);
|
|
11272
|
+
});
|
|
11273
|
+
screenShareAudioStream === null || screenShareAudioStream === void 0 ? void 0 : screenShareAudioStream.getAudioTracks().forEach((track) => {
|
|
11274
|
+
screenShare === null || screenShare === void 0 ? void 0 : screenShare.addTrack(track);
|
|
11275
|
+
});
|
|
11276
|
+
}
|
|
11025
11277
|
// restore previous publishing state
|
|
11026
11278
|
if (audioStream)
|
|
11027
11279
|
yield this.publishAudioStream(audioStream);
|
|
@@ -11275,7 +11527,6 @@ class Call {
|
|
|
11275
11527
|
* Consecutive calls to this method will replace the audio stream that is currently being published.
|
|
11276
11528
|
* The previous audio stream will be stopped.
|
|
11277
11529
|
*
|
|
11278
|
-
*
|
|
11279
11530
|
* @param audioStream the audio stream to publish.
|
|
11280
11531
|
*/
|
|
11281
11532
|
this.publishAudioStream = (audioStream) => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -11299,10 +11550,10 @@ class Call {
|
|
|
11299
11550
|
* Consecutive calls to this method will replace the previous screen-share stream.
|
|
11300
11551
|
* The previous screen-share stream will be stopped.
|
|
11301
11552
|
*
|
|
11302
|
-
*
|
|
11303
11553
|
* @param screenShareStream the screen-share stream to publish.
|
|
11554
|
+
* @param opts the options to use when publishing the stream.
|
|
11304
11555
|
*/
|
|
11305
|
-
this.publishScreenShareStream = (screenShareStream) => __awaiter(this, void 0, void 0, function* () {
|
|
11556
|
+
this.publishScreenShareStream = (screenShareStream, opts = {}) => __awaiter(this, void 0, void 0, function* () {
|
|
11306
11557
|
// we should wait until we get a JoinResponse from the SFU,
|
|
11307
11558
|
// otherwise we risk breaking the ICETrickle flow.
|
|
11308
11559
|
yield this.assertCallJoined();
|
|
@@ -11315,7 +11566,11 @@ class Call {
|
|
|
11315
11566
|
this.logger('error', `There is no video track in the screen share stream to publish`);
|
|
11316
11567
|
return;
|
|
11317
11568
|
}
|
|
11318
|
-
yield this.publisher.publishStream(screenShareStream, screenShareTrack, TrackType.SCREEN_SHARE);
|
|
11569
|
+
yield this.publisher.publishStream(screenShareStream, screenShareTrack, TrackType.SCREEN_SHARE, opts);
|
|
11570
|
+
const [screenShareAudioTrack] = screenShareStream.getAudioTracks();
|
|
11571
|
+
if (screenShareAudioTrack) {
|
|
11572
|
+
yield this.publisher.publishStream(screenShareStream, screenShareAudioTrack, TrackType.SCREEN_SHARE_AUDIO, opts);
|
|
11573
|
+
}
|
|
11319
11574
|
});
|
|
11320
11575
|
/**
|
|
11321
11576
|
* Stops publishing the given track type to the call, if it is currently being published.
|
|
@@ -11400,6 +11655,13 @@ class Call {
|
|
|
11400
11655
|
dimension: p.screenShareDimension,
|
|
11401
11656
|
});
|
|
11402
11657
|
}
|
|
11658
|
+
if (p.publishedTracks.includes(TrackType.SCREEN_SHARE_AUDIO)) {
|
|
11659
|
+
subscriptions.push({
|
|
11660
|
+
userId: p.userId,
|
|
11661
|
+
sessionId: p.sessionId,
|
|
11662
|
+
trackType: TrackType.SCREEN_SHARE_AUDIO,
|
|
11663
|
+
});
|
|
11664
|
+
}
|
|
11403
11665
|
}
|
|
11404
11666
|
// schedule update
|
|
11405
11667
|
this.trackSubscriptionsSubject.next({ type, data: subscriptions });
|
|
@@ -11870,9 +12132,10 @@ class Call {
|
|
|
11870
12132
|
*
|
|
11871
12133
|
* @param audioElement the audio element to bind to.
|
|
11872
12134
|
* @param sessionId the session id.
|
|
12135
|
+
* @param trackType the kind of audio.
|
|
11873
12136
|
*/
|
|
11874
|
-
this.bindAudioElement = (audioElement, sessionId) => {
|
|
11875
|
-
const unbind = this.dynascaleManager.bindAudioElement(audioElement, sessionId);
|
|
12137
|
+
this.bindAudioElement = (audioElement, sessionId, trackType = 'audioTrack') => {
|
|
12138
|
+
const unbind = this.dynascaleManager.bindAudioElement(audioElement, sessionId, trackType);
|
|
11876
12139
|
if (!unbind)
|
|
11877
12140
|
return;
|
|
11878
12141
|
this.leaveCallHooks.add(unbind);
|
|
@@ -11934,6 +12197,7 @@ class Call {
|
|
|
11934
12197
|
this.camera = new CameraManager(this);
|
|
11935
12198
|
this.microphone = new MicrophoneManager(this);
|
|
11936
12199
|
this.speaker = new SpeakerManager();
|
|
12200
|
+
this.screenShare = new ScreenShareManager(this);
|
|
11937
12201
|
}
|
|
11938
12202
|
registerEffects() {
|
|
11939
12203
|
this.leaveCallHooks.add(
|
|
@@ -13242,7 +13506,7 @@ class WSConnectionFallback {
|
|
|
13242
13506
|
}
|
|
13243
13507
|
}
|
|
13244
13508
|
|
|
13245
|
-
const version = '0.3.
|
|
13509
|
+
const version = '0.3.30';
|
|
13246
13510
|
|
|
13247
13511
|
const logger = getLogger(['location']);
|
|
13248
13512
|
const HINT_URL = `https://hint.stream-io-video.com/`;
|
|
@@ -14248,6 +14512,8 @@ exports.OwnCapability = OwnCapability;
|
|
|
14248
14512
|
exports.RecordSettingsRequestModeEnum = RecordSettingsRequestModeEnum;
|
|
14249
14513
|
exports.RecordSettingsRequestQualityEnum = RecordSettingsRequestQualityEnum;
|
|
14250
14514
|
exports.RxUtils = rxUtils;
|
|
14515
|
+
exports.ScreenShareManager = ScreenShareManager;
|
|
14516
|
+
exports.ScreenShareState = ScreenShareState;
|
|
14251
14517
|
exports.SfuEvents = events;
|
|
14252
14518
|
exports.SfuModels = models;
|
|
14253
14519
|
exports.SpeakerManager = SpeakerManager;
|