@stream-io/video-client 0.3.29 → 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 +7 -0
- package/dist/index.browser.es.js +379 -116
- package/dist/index.browser.es.js.map +1 -1
- package/dist/index.cjs.js +379 -114
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +379 -116
- 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/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;
|
|
@@ -9665,17 +9734,22 @@ class DynascaleManager {
|
|
|
9665
9734
|
*
|
|
9666
9735
|
* @param audioElement the audio element to bind to.
|
|
9667
9736
|
* @param sessionId the session id.
|
|
9737
|
+
* @param trackType the kind of audio.
|
|
9668
9738
|
* @returns a cleanup function that will unbind the audio element.
|
|
9669
9739
|
*/
|
|
9670
|
-
this.bindAudioElement = (audioElement, sessionId) => {
|
|
9740
|
+
this.bindAudioElement = (audioElement, sessionId, trackType) => {
|
|
9671
9741
|
const participant = this.call.state.findParticipantBySessionId(sessionId);
|
|
9672
9742
|
if (!participant || participant.isLocalParticipant)
|
|
9673
9743
|
return;
|
|
9674
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 }));
|
|
9675
9745
|
const updateMediaStreamSubscription = participant$
|
|
9676
|
-
.pipe(rxjs.distinctUntilKeyChanged('
|
|
9746
|
+
.pipe(rxjs.distinctUntilKeyChanged(trackType === 'screenShareAudioTrack'
|
|
9747
|
+
? 'screenShareAudioStream'
|
|
9748
|
+
: 'audioStream'))
|
|
9677
9749
|
.subscribe((p) => {
|
|
9678
|
-
const source =
|
|
9750
|
+
const source = trackType === 'screenShareAudioTrack'
|
|
9751
|
+
? p.screenShareAudioStream
|
|
9752
|
+
: p.audioStream;
|
|
9679
9753
|
if (audioElement.srcObject === source)
|
|
9680
9754
|
return;
|
|
9681
9755
|
setTimeout(() => {
|
|
@@ -9990,7 +10064,16 @@ const getVideoStream = (trackConstraints) => __awaiter(void 0, void 0, void 0, f
|
|
|
9990
10064
|
*/
|
|
9991
10065
|
const getScreenShareStream = (options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
9992
10066
|
try {
|
|
9993
|
-
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));
|
|
9994
10077
|
}
|
|
9995
10078
|
catch (e) {
|
|
9996
10079
|
getLogger(['devices'])('error', 'Failed to get screen share stream', e);
|
|
@@ -10119,7 +10202,7 @@ class InputMediaDeviceManager {
|
|
|
10119
10202
|
return this.getDevices();
|
|
10120
10203
|
}
|
|
10121
10204
|
/**
|
|
10122
|
-
* Starts
|
|
10205
|
+
* Starts stream.
|
|
10123
10206
|
*/
|
|
10124
10207
|
enable() {
|
|
10125
10208
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -10138,9 +10221,7 @@ class InputMediaDeviceManager {
|
|
|
10138
10221
|
});
|
|
10139
10222
|
}
|
|
10140
10223
|
/**
|
|
10141
|
-
* Stops
|
|
10142
|
-
*
|
|
10143
|
-
* @returns
|
|
10224
|
+
* Stops the stream.
|
|
10144
10225
|
*/
|
|
10145
10226
|
disable() {
|
|
10146
10227
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -10161,7 +10242,7 @@ class InputMediaDeviceManager {
|
|
|
10161
10242
|
});
|
|
10162
10243
|
}
|
|
10163
10244
|
/**
|
|
10164
|
-
* If status was previously enabled, it will
|
|
10245
|
+
* If status was previously enabled, it will re-enable the device.
|
|
10165
10246
|
*/
|
|
10166
10247
|
resume() {
|
|
10167
10248
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -10172,9 +10253,8 @@ class InputMediaDeviceManager {
|
|
|
10172
10253
|
});
|
|
10173
10254
|
}
|
|
10174
10255
|
/**
|
|
10175
|
-
* If current device
|
|
10176
|
-
*
|
|
10177
|
-
* @returns
|
|
10256
|
+
* If the current device status is disabled, it will enable the device,
|
|
10257
|
+
* else it will disable it.
|
|
10178
10258
|
*/
|
|
10179
10259
|
toggle() {
|
|
10180
10260
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -10186,6 +10266,16 @@ class InputMediaDeviceManager {
|
|
|
10186
10266
|
}
|
|
10187
10267
|
});
|
|
10188
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
|
+
}
|
|
10189
10279
|
/**
|
|
10190
10280
|
* Select device
|
|
10191
10281
|
*
|
|
@@ -10213,8 +10303,11 @@ class InputMediaDeviceManager {
|
|
|
10213
10303
|
}
|
|
10214
10304
|
});
|
|
10215
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
|
+
}
|
|
10216
10310
|
muteStream(stopTracks = true) {
|
|
10217
|
-
var _a;
|
|
10218
10311
|
return __awaiter(this, void 0, void 0, function* () {
|
|
10219
10312
|
if (!this.state.mediaStream) {
|
|
10220
10313
|
return;
|
|
@@ -10224,57 +10317,63 @@ class InputMediaDeviceManager {
|
|
|
10224
10317
|
yield this.stopPublishStream(stopTracks);
|
|
10225
10318
|
}
|
|
10226
10319
|
this.muteLocalStream(stopTracks);
|
|
10227
|
-
|
|
10228
|
-
|
|
10229
|
-
|
|
10230
|
-
//
|
|
10231
|
-
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);
|
|
10232
10329
|
}
|
|
10233
|
-
|
|
10234
|
-
}
|
|
10330
|
+
});
|
|
10235
10331
|
});
|
|
10236
10332
|
}
|
|
10237
|
-
|
|
10238
|
-
|
|
10239
|
-
|
|
10240
|
-
|
|
10241
|
-
}
|
|
10242
|
-
track.enabled = false;
|
|
10333
|
+
muteTracks() {
|
|
10334
|
+
this.getTracks().forEach((track) => {
|
|
10335
|
+
if (track.enabled)
|
|
10336
|
+
track.enabled = false;
|
|
10337
|
+
});
|
|
10243
10338
|
}
|
|
10244
|
-
|
|
10245
|
-
|
|
10246
|
-
|
|
10247
|
-
|
|
10248
|
-
}
|
|
10249
|
-
track.enabled = true;
|
|
10339
|
+
unmuteTracks() {
|
|
10340
|
+
this.getTracks().forEach((track) => {
|
|
10341
|
+
if (!track.enabled)
|
|
10342
|
+
track.enabled = true;
|
|
10343
|
+
});
|
|
10250
10344
|
}
|
|
10251
|
-
|
|
10252
|
-
|
|
10253
|
-
|
|
10254
|
-
|
|
10255
|
-
}
|
|
10256
|
-
track.stop();
|
|
10345
|
+
stopTracks() {
|
|
10346
|
+
this.getTracks().forEach((track) => {
|
|
10347
|
+
if (track.readyState === 'live')
|
|
10348
|
+
track.stop();
|
|
10349
|
+
});
|
|
10257
10350
|
}
|
|
10258
10351
|
muteLocalStream(stopTracks) {
|
|
10259
10352
|
if (!this.state.mediaStream) {
|
|
10260
10353
|
return;
|
|
10261
10354
|
}
|
|
10262
|
-
|
|
10355
|
+
if (stopTracks) {
|
|
10356
|
+
this.stopTracks();
|
|
10357
|
+
}
|
|
10358
|
+
else {
|
|
10359
|
+
this.muteTracks();
|
|
10360
|
+
}
|
|
10263
10361
|
}
|
|
10264
10362
|
unmuteStream() {
|
|
10265
|
-
var _a;
|
|
10266
10363
|
return __awaiter(this, void 0, void 0, function* () {
|
|
10267
10364
|
this.logger('debug', 'Starting stream');
|
|
10268
10365
|
let stream;
|
|
10269
|
-
if (this.state.mediaStream &&
|
|
10366
|
+
if (this.state.mediaStream &&
|
|
10367
|
+
this.getTracks().every((t) => t.readyState === 'live')) {
|
|
10270
10368
|
stream = this.state.mediaStream;
|
|
10271
|
-
this.
|
|
10369
|
+
this.unmuteTracks();
|
|
10272
10370
|
}
|
|
10273
10371
|
else {
|
|
10274
10372
|
if (this.state.mediaStream) {
|
|
10275
|
-
this.
|
|
10373
|
+
this.stopTracks();
|
|
10276
10374
|
}
|
|
10277
|
-
const
|
|
10375
|
+
const defaultConstraints = this.state.defaultConstraints;
|
|
10376
|
+
const constraints = Object.assign(Object.assign({}, defaultConstraints), { deviceId: this.state.selectedDevice });
|
|
10278
10377
|
stream = yield this.getStream(constraints);
|
|
10279
10378
|
}
|
|
10280
10379
|
if (this.call.state.callingState === exports.CallingState.JOINED) {
|
|
@@ -10293,6 +10392,26 @@ class InputMediaDeviceManagerState {
|
|
|
10293
10392
|
this.statusSubject = new rxjs.BehaviorSubject(undefined);
|
|
10294
10393
|
this.mediaStreamSubject = new rxjs.BehaviorSubject(undefined);
|
|
10295
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();
|
|
10296
10415
|
/**
|
|
10297
10416
|
* Gets the current value of an observable, or undefined if the observable has
|
|
10298
10417
|
* not emitted a value yet.
|
|
@@ -10312,13 +10431,6 @@ class InputMediaDeviceManagerState {
|
|
|
10312
10431
|
* @return the updated value.
|
|
10313
10432
|
*/
|
|
10314
10433
|
this.setCurrentValue = setCurrentValue;
|
|
10315
|
-
this.mediaStream$ = this.mediaStreamSubject.asObservable();
|
|
10316
|
-
this.selectedDevice$ = this.selectedDeviceSubject
|
|
10317
|
-
.asObservable()
|
|
10318
|
-
.pipe(rxjs.distinctUntilChanged());
|
|
10319
|
-
this.status$ = this.statusSubject
|
|
10320
|
-
.asObservable()
|
|
10321
|
-
.pipe(rxjs.distinctUntilChanged());
|
|
10322
10434
|
}
|
|
10323
10435
|
/**
|
|
10324
10436
|
* The device status
|
|
@@ -10362,6 +10474,21 @@ class InputMediaDeviceManagerState {
|
|
|
10362
10474
|
setDevice(deviceId) {
|
|
10363
10475
|
this.setCurrentValue(this.selectedDeviceSubject, deviceId);
|
|
10364
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
|
+
}
|
|
10365
10492
|
}
|
|
10366
10493
|
|
|
10367
10494
|
class CameraManagerState extends InputMediaDeviceManagerState {
|
|
@@ -10486,10 +10613,6 @@ class CameraManager extends InputMediaDeviceManager {
|
|
|
10486
10613
|
stopPublishStream(stopTracks) {
|
|
10487
10614
|
return this.call.stopPublish(TrackType.VIDEO, stopTracks);
|
|
10488
10615
|
}
|
|
10489
|
-
getTrack() {
|
|
10490
|
-
var _a;
|
|
10491
|
-
return (_a = this.state.mediaStream) === null || _a === void 0 ? void 0 : _a.getVideoTracks()[0];
|
|
10492
|
-
}
|
|
10493
10616
|
}
|
|
10494
10617
|
|
|
10495
10618
|
class MicrophoneManagerState extends InputMediaDeviceManagerState {
|
|
@@ -10614,10 +10737,6 @@ class MicrophoneManager extends InputMediaDeviceManager {
|
|
|
10614
10737
|
stopPublishStream(stopTracks) {
|
|
10615
10738
|
return this.call.stopPublish(TrackType.AUDIO, stopTracks);
|
|
10616
10739
|
}
|
|
10617
|
-
getTrack() {
|
|
10618
|
-
var _a;
|
|
10619
|
-
return (_a = this.state.mediaStream) === null || _a === void 0 ? void 0 : _a.getAudioTracks()[0];
|
|
10620
|
-
}
|
|
10621
10740
|
startSpeakingWhileMutedDetection(deviceId) {
|
|
10622
10741
|
return __awaiter(this, void 0, void 0, function* () {
|
|
10623
10742
|
if (isReactNative()) {
|
|
@@ -10649,6 +10768,128 @@ class MicrophoneManager extends InputMediaDeviceManager {
|
|
|
10649
10768
|
}
|
|
10650
10769
|
}
|
|
10651
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
|
+
|
|
10652
10893
|
class SpeakerState {
|
|
10653
10894
|
constructor() {
|
|
10654
10895
|
this.selectedDeviceSubject = new rxjs.BehaviorSubject('');
|
|
@@ -11022,7 +11263,17 @@ class Call {
|
|
|
11022
11263
|
// as the underlying peer connection will take care of it as part
|
|
11023
11264
|
// of the ice-restart process
|
|
11024
11265
|
if (localParticipant && !migrate) {
|
|
11025
|
-
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
|
+
}
|
|
11026
11277
|
// restore previous publishing state
|
|
11027
11278
|
if (audioStream)
|
|
11028
11279
|
yield this.publishAudioStream(audioStream);
|
|
@@ -11276,7 +11527,6 @@ class Call {
|
|
|
11276
11527
|
* Consecutive calls to this method will replace the audio stream that is currently being published.
|
|
11277
11528
|
* The previous audio stream will be stopped.
|
|
11278
11529
|
*
|
|
11279
|
-
*
|
|
11280
11530
|
* @param audioStream the audio stream to publish.
|
|
11281
11531
|
*/
|
|
11282
11532
|
this.publishAudioStream = (audioStream) => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -11300,10 +11550,10 @@ class Call {
|
|
|
11300
11550
|
* Consecutive calls to this method will replace the previous screen-share stream.
|
|
11301
11551
|
* The previous screen-share stream will be stopped.
|
|
11302
11552
|
*
|
|
11303
|
-
*
|
|
11304
11553
|
* @param screenShareStream the screen-share stream to publish.
|
|
11554
|
+
* @param opts the options to use when publishing the stream.
|
|
11305
11555
|
*/
|
|
11306
|
-
this.publishScreenShareStream = (screenShareStream) => __awaiter(this, void 0, void 0, function* () {
|
|
11556
|
+
this.publishScreenShareStream = (screenShareStream, opts = {}) => __awaiter(this, void 0, void 0, function* () {
|
|
11307
11557
|
// we should wait until we get a JoinResponse from the SFU,
|
|
11308
11558
|
// otherwise we risk breaking the ICETrickle flow.
|
|
11309
11559
|
yield this.assertCallJoined();
|
|
@@ -11316,7 +11566,11 @@ class Call {
|
|
|
11316
11566
|
this.logger('error', `There is no video track in the screen share stream to publish`);
|
|
11317
11567
|
return;
|
|
11318
11568
|
}
|
|
11319
|
-
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
|
+
}
|
|
11320
11574
|
});
|
|
11321
11575
|
/**
|
|
11322
11576
|
* Stops publishing the given track type to the call, if it is currently being published.
|
|
@@ -11401,6 +11655,13 @@ class Call {
|
|
|
11401
11655
|
dimension: p.screenShareDimension,
|
|
11402
11656
|
});
|
|
11403
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
|
+
}
|
|
11404
11665
|
}
|
|
11405
11666
|
// schedule update
|
|
11406
11667
|
this.trackSubscriptionsSubject.next({ type, data: subscriptions });
|
|
@@ -11871,9 +12132,10 @@ class Call {
|
|
|
11871
12132
|
*
|
|
11872
12133
|
* @param audioElement the audio element to bind to.
|
|
11873
12134
|
* @param sessionId the session id.
|
|
12135
|
+
* @param trackType the kind of audio.
|
|
11874
12136
|
*/
|
|
11875
|
-
this.bindAudioElement = (audioElement, sessionId) => {
|
|
11876
|
-
const unbind = this.dynascaleManager.bindAudioElement(audioElement, sessionId);
|
|
12137
|
+
this.bindAudioElement = (audioElement, sessionId, trackType = 'audioTrack') => {
|
|
12138
|
+
const unbind = this.dynascaleManager.bindAudioElement(audioElement, sessionId, trackType);
|
|
11877
12139
|
if (!unbind)
|
|
11878
12140
|
return;
|
|
11879
12141
|
this.leaveCallHooks.add(unbind);
|
|
@@ -11935,6 +12197,7 @@ class Call {
|
|
|
11935
12197
|
this.camera = new CameraManager(this);
|
|
11936
12198
|
this.microphone = new MicrophoneManager(this);
|
|
11937
12199
|
this.speaker = new SpeakerManager();
|
|
12200
|
+
this.screenShare = new ScreenShareManager(this);
|
|
11938
12201
|
}
|
|
11939
12202
|
registerEffects() {
|
|
11940
12203
|
this.leaveCallHooks.add(
|
|
@@ -13243,7 +13506,7 @@ class WSConnectionFallback {
|
|
|
13243
13506
|
}
|
|
13244
13507
|
}
|
|
13245
13508
|
|
|
13246
|
-
const version = '0.3.
|
|
13509
|
+
const version = '0.3.30';
|
|
13247
13510
|
|
|
13248
13511
|
const logger = getLogger(['location']);
|
|
13249
13512
|
const HINT_URL = `https://hint.stream-io-video.com/`;
|
|
@@ -14249,6 +14512,8 @@ exports.OwnCapability = OwnCapability;
|
|
|
14249
14512
|
exports.RecordSettingsRequestModeEnum = RecordSettingsRequestModeEnum;
|
|
14250
14513
|
exports.RecordSettingsRequestQualityEnum = RecordSettingsRequestQualityEnum;
|
|
14251
14514
|
exports.RxUtils = rxUtils;
|
|
14515
|
+
exports.ScreenShareManager = ScreenShareManager;
|
|
14516
|
+
exports.ScreenShareState = ScreenShareState;
|
|
14252
14517
|
exports.SfuEvents = events;
|
|
14253
14518
|
exports.SfuModels = models;
|
|
14254
14519
|
exports.SpeakerManager = SpeakerManager;
|