@webex/internal-media-core 1.35.5 → 1.35.7
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/cjs/index.js +242 -188
- package/dist/esm/index.js +242 -188
- package/package.json +3 -3
package/dist/cjs/index.js
CHANGED
|
@@ -4679,6 +4679,139 @@ var media = /*#__PURE__*/Object.freeze({
|
|
|
4679
4679
|
checkDevicePermissions: checkDevicePermissions,
|
|
4680
4680
|
ensureDevicePermissions: ensureDevicePermissions
|
|
4681
4681
|
});
|
|
4682
|
+
var ErrorTypes;
|
|
4683
|
+
(function (ErrorTypes) {
|
|
4684
|
+
ErrorTypes["DEVICE_PERMISSION_DENIED"] = "DEVICE_PERMISSION_DENIED";
|
|
4685
|
+
ErrorTypes["CREATE_CAMERA_TRACK_FAILED"] = "CREATE_CAMERA_TRACK_FAILED";
|
|
4686
|
+
ErrorTypes["CREATE_MICROPHONE_TRACK_FAILED"] = "CREATE_MICROPHONE_TRACK_FAILED";
|
|
4687
|
+
})(ErrorTypes || (ErrorTypes = {}));
|
|
4688
|
+
/**
|
|
4689
|
+
* Represents a WCME error, which contains error type and error message.
|
|
4690
|
+
*/
|
|
4691
|
+
class WcmeError {
|
|
4692
|
+
/**
|
|
4693
|
+
* Creates new error.
|
|
4694
|
+
*
|
|
4695
|
+
* @param type - Error type.
|
|
4696
|
+
* @param message - Error message.
|
|
4697
|
+
*/
|
|
4698
|
+
constructor(type) {
|
|
4699
|
+
var message = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
|
|
4700
|
+
this.type = type;
|
|
4701
|
+
this.message = message;
|
|
4702
|
+
}
|
|
4703
|
+
}
|
|
4704
|
+
/**
|
|
4705
|
+
* Creates a camera video track. Please note that the constraint params in second getUserMedia call would NOT take effect when:
|
|
4706
|
+
*
|
|
4707
|
+
* 1. Previous captured video track from the same device is not stopped .
|
|
4708
|
+
* 2. Previous createCameraTrack() call for the same device is in progress.
|
|
4709
|
+
*
|
|
4710
|
+
* @param constructor - Constructor for the local camera track.
|
|
4711
|
+
* @param constraints - Video device constraints.
|
|
4712
|
+
* @returns A LocalTrack object or an error.
|
|
4713
|
+
*/
|
|
4714
|
+
function createCameraTrack(constructor, constraints) {
|
|
4715
|
+
return __awaiter$1(this, void 0, void 0, function* () {
|
|
4716
|
+
var stream;
|
|
4717
|
+
try {
|
|
4718
|
+
stream = yield getUserMedia({
|
|
4719
|
+
video: Object.assign({}, constraints)
|
|
4720
|
+
});
|
|
4721
|
+
} catch (error) {
|
|
4722
|
+
throw new WcmeError(ErrorTypes.CREATE_CAMERA_TRACK_FAILED, "Failed to create camera track ".concat(error));
|
|
4723
|
+
}
|
|
4724
|
+
return new constructor(stream);
|
|
4725
|
+
});
|
|
4726
|
+
}
|
|
4727
|
+
/**
|
|
4728
|
+
* Creates a microphone audio track.
|
|
4729
|
+
*
|
|
4730
|
+
* @param constructor - Constructor for the local microphone track.
|
|
4731
|
+
* @param constraints - Audio device constraints.
|
|
4732
|
+
* @returns A LocalTrack object or an error.
|
|
4733
|
+
*/
|
|
4734
|
+
function createMicrophoneTrack(constructor, constraints) {
|
|
4735
|
+
return __awaiter$1(this, void 0, void 0, function* () {
|
|
4736
|
+
var stream;
|
|
4737
|
+
try {
|
|
4738
|
+
stream = yield getUserMedia({
|
|
4739
|
+
audio: Object.assign({}, constraints)
|
|
4740
|
+
});
|
|
4741
|
+
} catch (error) {
|
|
4742
|
+
throw new WcmeError(ErrorTypes.CREATE_MICROPHONE_TRACK_FAILED, "Failed to create microphone track ".concat(error));
|
|
4743
|
+
}
|
|
4744
|
+
return new constructor(stream);
|
|
4745
|
+
});
|
|
4746
|
+
}
|
|
4747
|
+
/**
|
|
4748
|
+
* Creates a display video track.
|
|
4749
|
+
*
|
|
4750
|
+
* @param constructor - Constructor for the local display track.
|
|
4751
|
+
* @param videoContentHint - An optional parameters to give a hint for the content of the track.
|
|
4752
|
+
* @returns A Promise that resolves to a LocalDisplayTrack.
|
|
4753
|
+
*/
|
|
4754
|
+
function createDisplayTrack(constructor, videoContentHint) {
|
|
4755
|
+
return __awaiter$1(this, void 0, void 0, function* () {
|
|
4756
|
+
var stream = yield getDisplayMedia({
|
|
4757
|
+
video: true
|
|
4758
|
+
});
|
|
4759
|
+
return new constructor(stream, videoContentHint);
|
|
4760
|
+
});
|
|
4761
|
+
}
|
|
4762
|
+
/**
|
|
4763
|
+
* Enumerates the media input and output devices available.
|
|
4764
|
+
*
|
|
4765
|
+
* @param deviceKind - Optional filter to return a specific device kind.
|
|
4766
|
+
* @returns List of media devices in an array of MediaDeviceInfo objects.
|
|
4767
|
+
*/
|
|
4768
|
+
function getDevices(deviceKind) {
|
|
4769
|
+
return __awaiter$1(this, void 0, void 0, function* () {
|
|
4770
|
+
var devices;
|
|
4771
|
+
try {
|
|
4772
|
+
devices = yield ensureDevicePermissions([DeviceKind.AudioInput, DeviceKind.VideoInput], enumerateDevices);
|
|
4773
|
+
} catch (error) {
|
|
4774
|
+
throw new WcmeError(ErrorTypes.DEVICE_PERMISSION_DENIED, 'Failed to ensure device permissions');
|
|
4775
|
+
}
|
|
4776
|
+
return devices.filter(v => deviceKind ? v.kind === deviceKind : true);
|
|
4777
|
+
});
|
|
4778
|
+
}
|
|
4779
|
+
/**
|
|
4780
|
+
* Helper function to get a list of microphone devices.
|
|
4781
|
+
*
|
|
4782
|
+
* @returns List of microphone devices in an array of MediaDeviceInfo objects.
|
|
4783
|
+
*/
|
|
4784
|
+
function getAudioInputDevices() {
|
|
4785
|
+
return __awaiter$1(this, void 0, void 0, function* () {
|
|
4786
|
+
return getDevices(DeviceKind.AudioInput);
|
|
4787
|
+
});
|
|
4788
|
+
}
|
|
4789
|
+
/**
|
|
4790
|
+
* Helper function to get a list of speaker devices.
|
|
4791
|
+
*
|
|
4792
|
+
* @returns List of speaker devices in an array of MediaDeviceInfo objects.
|
|
4793
|
+
*/
|
|
4794
|
+
function getAudioOutputDevices() {
|
|
4795
|
+
return __awaiter$1(this, void 0, void 0, function* () {
|
|
4796
|
+
return getDevices(DeviceKind.AudioOutput);
|
|
4797
|
+
});
|
|
4798
|
+
}
|
|
4799
|
+
/**
|
|
4800
|
+
* Helper function to get a list of camera devices.
|
|
4801
|
+
*
|
|
4802
|
+
* @returns List of camera devices in an array of MediaDeviceInfo objects.
|
|
4803
|
+
*/
|
|
4804
|
+
function getVideoInputDevices() {
|
|
4805
|
+
return __awaiter$1(this, void 0, void 0, function* () {
|
|
4806
|
+
return getDevices(DeviceKind.VideoInput);
|
|
4807
|
+
});
|
|
4808
|
+
}
|
|
4809
|
+
/**
|
|
4810
|
+
* Export the setOnDeviceChangeHandler method directly from the core lib.
|
|
4811
|
+
*/
|
|
4812
|
+
var {
|
|
4813
|
+
setOnDeviceChangeHandler
|
|
4814
|
+
} = media;
|
|
4682
4815
|
var events$1 = {
|
|
4683
4816
|
exports: {}
|
|
4684
4817
|
};
|
|
@@ -5351,141 +5484,32 @@ class LocalCameraTrack extends LocalTrack {}
|
|
|
5351
5484
|
/**
|
|
5352
5485
|
* Represents a local track for a display source.
|
|
5353
5486
|
*/
|
|
5354
|
-
class LocalDisplayTrack extends LocalTrack {
|
|
5355
|
-
|
|
5356
|
-
/**
|
|
5357
|
-
* Represents a local track for a microphone source.
|
|
5358
|
-
*/
|
|
5359
|
-
class LocalMicrophoneTrack extends LocalTrack {}
|
|
5360
|
-
var ErrorTypes;
|
|
5361
|
-
(function (ErrorTypes) {
|
|
5362
|
-
ErrorTypes["DEVICE_PERMISSION_DENIED"] = "DEVICE_PERMISSION_DENIED";
|
|
5363
|
-
ErrorTypes["CREATE_CAMERA_TRACK_FAILED"] = "CREATE_CAMERA_TRACK_FAILED";
|
|
5364
|
-
ErrorTypes["CREATE_MICROPHONE_TRACK_FAILED"] = "CREATE_MICROPHONE_TRACK_FAILED";
|
|
5365
|
-
})(ErrorTypes || (ErrorTypes = {}));
|
|
5366
|
-
/**
|
|
5367
|
-
* Represents a WCME error, which contains error type and error message.
|
|
5368
|
-
*/
|
|
5369
|
-
class WcmeError {
|
|
5487
|
+
class LocalDisplayTrack extends LocalTrack {
|
|
5370
5488
|
/**
|
|
5371
|
-
*
|
|
5489
|
+
* Create a LocalDisplayTrack from the given values.
|
|
5372
5490
|
*
|
|
5373
|
-
* @param
|
|
5374
|
-
* @param
|
|
5491
|
+
* @param stream - The MediaStream for this track.
|
|
5492
|
+
* @param videoContentHint - An optional content hint, describing the content of the track.
|
|
5375
5493
|
*/
|
|
5376
|
-
constructor(
|
|
5377
|
-
|
|
5378
|
-
this.
|
|
5379
|
-
this.
|
|
5494
|
+
constructor(stream, videoContentHint) {
|
|
5495
|
+
super(stream);
|
|
5496
|
+
this._videoContentHint = videoContentHint;
|
|
5497
|
+
this.underlyingTrack.contentHint = videoContentHint || '';
|
|
5498
|
+
}
|
|
5499
|
+
/**
|
|
5500
|
+
* Get the VideoContentHint for this track.
|
|
5501
|
+
*
|
|
5502
|
+
* @returns The VideoContentHint for this track.
|
|
5503
|
+
*/
|
|
5504
|
+
get videoContentHint() {
|
|
5505
|
+
return this._videoContentHint;
|
|
5380
5506
|
}
|
|
5381
5507
|
}
|
|
5508
|
+
|
|
5382
5509
|
/**
|
|
5383
|
-
*
|
|
5384
|
-
*
|
|
5385
|
-
* 1. Previous captured video track from the same device is not stopped .
|
|
5386
|
-
* 2. Previous createCameraTrack() call for the same device is in progress.
|
|
5387
|
-
*
|
|
5388
|
-
* @param constraints - Video device constraints.
|
|
5389
|
-
* @returns A LocalTrack object or an error.
|
|
5390
|
-
*/
|
|
5391
|
-
function createCameraTrack(constraints) {
|
|
5392
|
-
return __awaiter$1(this, void 0, void 0, function* () {
|
|
5393
|
-
var stream;
|
|
5394
|
-
try {
|
|
5395
|
-
stream = yield getUserMedia({
|
|
5396
|
-
video: Object.assign({}, constraints)
|
|
5397
|
-
});
|
|
5398
|
-
} catch (error) {
|
|
5399
|
-
throw new WcmeError(ErrorTypes.CREATE_CAMERA_TRACK_FAILED, "Failed to create camera track ".concat(error));
|
|
5400
|
-
}
|
|
5401
|
-
return new LocalCameraTrack(stream);
|
|
5402
|
-
});
|
|
5403
|
-
}
|
|
5404
|
-
/**
|
|
5405
|
-
* Creates a microphone audio track.
|
|
5406
|
-
*
|
|
5407
|
-
* @param constraints - Audio device constraints.
|
|
5408
|
-
* @returns A LocalTrack object or an error.
|
|
5409
|
-
*/
|
|
5410
|
-
function createMicrophoneTrack(constraints) {
|
|
5411
|
-
return __awaiter$1(this, void 0, void 0, function* () {
|
|
5412
|
-
var stream;
|
|
5413
|
-
try {
|
|
5414
|
-
stream = yield getUserMedia({
|
|
5415
|
-
audio: Object.assign({}, constraints)
|
|
5416
|
-
});
|
|
5417
|
-
} catch (error) {
|
|
5418
|
-
throw new WcmeError(ErrorTypes.CREATE_MICROPHONE_TRACK_FAILED, "Failed to create microphone track ".concat(error));
|
|
5419
|
-
}
|
|
5420
|
-
return new LocalMicrophoneTrack(stream);
|
|
5421
|
-
});
|
|
5422
|
-
}
|
|
5423
|
-
/**
|
|
5424
|
-
* Creates a display video track.
|
|
5425
|
-
*
|
|
5426
|
-
* @returns A Promise that resolves to a LocalDisplayTrack.
|
|
5427
|
-
*/
|
|
5428
|
-
function createDisplayTrack() {
|
|
5429
|
-
return __awaiter$1(this, void 0, void 0, function* () {
|
|
5430
|
-
var stream = yield getDisplayMedia({
|
|
5431
|
-
video: true
|
|
5432
|
-
});
|
|
5433
|
-
return new LocalDisplayTrack(stream);
|
|
5434
|
-
});
|
|
5435
|
-
}
|
|
5436
|
-
/**
|
|
5437
|
-
* Enumerates the media input and output devices available.
|
|
5438
|
-
*
|
|
5439
|
-
* @param deviceKind - Optional filter to return a specific device kind.
|
|
5440
|
-
* @returns List of media devices in an array of MediaDeviceInfo objects.
|
|
5441
|
-
*/
|
|
5442
|
-
function getDevices(deviceKind) {
|
|
5443
|
-
return __awaiter$1(this, void 0, void 0, function* () {
|
|
5444
|
-
var devices;
|
|
5445
|
-
try {
|
|
5446
|
-
devices = yield ensureDevicePermissions([DeviceKind.AudioInput, DeviceKind.VideoInput], enumerateDevices);
|
|
5447
|
-
} catch (error) {
|
|
5448
|
-
throw new WcmeError(ErrorTypes.DEVICE_PERMISSION_DENIED, 'Failed to ensure device permissions');
|
|
5449
|
-
}
|
|
5450
|
-
return devices.filter(v => deviceKind ? v.kind === deviceKind : true);
|
|
5451
|
-
});
|
|
5452
|
-
}
|
|
5453
|
-
/**
|
|
5454
|
-
* Helper function to get a list of microphone devices.
|
|
5455
|
-
*
|
|
5456
|
-
* @returns List of microphone devices in an array of MediaDeviceInfo objects.
|
|
5457
|
-
*/
|
|
5458
|
-
function getAudioInputDevices() {
|
|
5459
|
-
return __awaiter$1(this, void 0, void 0, function* () {
|
|
5460
|
-
return getDevices(DeviceKind.AudioInput);
|
|
5461
|
-
});
|
|
5462
|
-
}
|
|
5463
|
-
/**
|
|
5464
|
-
* Helper function to get a list of speaker devices.
|
|
5465
|
-
*
|
|
5466
|
-
* @returns List of speaker devices in an array of MediaDeviceInfo objects.
|
|
5467
|
-
*/
|
|
5468
|
-
function getAudioOutputDevices() {
|
|
5469
|
-
return __awaiter$1(this, void 0, void 0, function* () {
|
|
5470
|
-
return getDevices(DeviceKind.AudioOutput);
|
|
5471
|
-
});
|
|
5472
|
-
}
|
|
5473
|
-
/**
|
|
5474
|
-
* Helper function to get a list of camera devices.
|
|
5475
|
-
*
|
|
5476
|
-
* @returns List of camera devices in an array of MediaDeviceInfo objects.
|
|
5477
|
-
*/
|
|
5478
|
-
function getVideoInputDevices() {
|
|
5479
|
-
return __awaiter$1(this, void 0, void 0, function* () {
|
|
5480
|
-
return getDevices(DeviceKind.VideoInput);
|
|
5481
|
-
});
|
|
5482
|
-
}
|
|
5483
|
-
/**
|
|
5484
|
-
* Export the setOnDeviceChangeHandler method directly from the core lib.
|
|
5510
|
+
* Represents a local track for a microphone source.
|
|
5485
5511
|
*/
|
|
5486
|
-
|
|
5487
|
-
setOnDeviceChangeHandler
|
|
5488
|
-
} = media;
|
|
5512
|
+
class LocalMicrophoneTrack extends LocalTrack {}
|
|
5489
5513
|
|
|
5490
5514
|
// Overall connection state (based on the ICE and DTLS connection states)
|
|
5491
5515
|
exports.ConnectionState = void 0;
|
|
@@ -9480,11 +9504,12 @@ function compareStreamIds(id1, id2) {
|
|
|
9480
9504
|
return keys1.every(key => id1[key] === id2[key]);
|
|
9481
9505
|
}
|
|
9482
9506
|
class SourceIndicationMsg {
|
|
9483
|
-
constructor(seqNum, numTotalSources, numLiveSources, sources) {
|
|
9507
|
+
constructor(seqNum, numTotalSources, numLiveSources, sources, videoContentHint) {
|
|
9484
9508
|
this.seqNum = seqNum;
|
|
9485
9509
|
this.numTotalSources = numTotalSources;
|
|
9486
9510
|
this.numLiveSources = numLiveSources;
|
|
9487
9511
|
this.sources = sources;
|
|
9512
|
+
this.videoContentHint = videoContentHint;
|
|
9488
9513
|
}
|
|
9489
9514
|
sourcesToString() {
|
|
9490
9515
|
return this.sources.map(source => "Source(id=".concat(source.id, " state=").concat(source.state, " ").concat(source.csi ? "csi=".concat(source.csi) : '', ")")).join(', ');
|
|
@@ -9571,13 +9596,13 @@ class JmpSession extends EventEmitter$4 {
|
|
|
9571
9596
|
this.logger.warn("Retransmits for message expired: ".concat(expiredJmpMsg));
|
|
9572
9597
|
});
|
|
9573
9598
|
}
|
|
9574
|
-
updateSourceIndication(numTotalSources, numLiveSources, sources) {
|
|
9599
|
+
updateSourceIndication(numTotalSources, numLiveSources, sources, videoContentHint) {
|
|
9575
9600
|
var _a;
|
|
9576
9601
|
var filteredSources = sources.filter(source => {
|
|
9577
9602
|
var _a;
|
|
9578
9603
|
return (_a = this.lastReceivedScr) === null || _a === void 0 ? void 0 : _a.requests.some(req => req.ids.find(streamId => compareStreamIds(streamId, source.id)));
|
|
9579
9604
|
});
|
|
9580
|
-
var sourceIndicationMsg = new SourceIndicationMsg(this.currSourceIndicationSeqNum++, numTotalSources, numLiveSources, filteredSources);
|
|
9605
|
+
var sourceIndicationMsg = new SourceIndicationMsg(this.currSourceIndicationSeqNum++, numTotalSources, numLiveSources, filteredSources, videoContentHint);
|
|
9581
9606
|
var jmpMsg = new JmpMsg(this.mediaFamily, this.mediaContent, {
|
|
9582
9607
|
msgType: JmpMsgType$1.SourceIndication,
|
|
9583
9608
|
payload: sourceIndicationMsg
|
|
@@ -12722,7 +12747,9 @@ class SsrcIngressStreamSignaler {
|
|
|
12722
12747
|
mLine.addLine(new SsrcLine(this.ssrc, 'cname', "".concat(this.ssrc, "-cname")));
|
|
12723
12748
|
mLine.addLine(new SsrcLine(this.ssrc, 'msid', '-', '1'));
|
|
12724
12749
|
if (hasCodec('rtx', mLine)) {
|
|
12725
|
-
this.rtxSsrc
|
|
12750
|
+
if (!this.rtxSsrc) {
|
|
12751
|
+
this.rtxSsrc = generateSsrc();
|
|
12752
|
+
}
|
|
12726
12753
|
mLine.addLine(new SsrcLine(this.rtxSsrc, 'cname', "".concat(this.ssrc, "-cname")));
|
|
12727
12754
|
mLine.addLine(new SsrcLine(this.rtxSsrc, 'msid', '-', '1'));
|
|
12728
12755
|
mLine.addLine(new SsrcGroupLine('FID', [this.ssrc, this.rtxSsrc]));
|
|
@@ -12734,23 +12761,57 @@ class SsrcEgressStreamSignaler {
|
|
|
12734
12761
|
this.streamIds = [];
|
|
12735
12762
|
}
|
|
12736
12763
|
signalStreams(simulcastEnabled, rtxEnabled, mLine) {
|
|
12764
|
+
var _a;
|
|
12737
12765
|
mLine.rids = [];
|
|
12738
12766
|
mLine.simulcast = undefined;
|
|
12739
|
-
mLine.ssrcs = [];
|
|
12740
|
-
mLine.ssrcGroups = [];
|
|
12741
12767
|
mLine.extMaps = mLine.extMaps.filter(extMapLine => !/^urn:ietf:params:rtp-hdrext:sdes:(?:mid|rtp-stream-id|repaired-rtp-stream-id)$/.test(extMapLine.uri));
|
|
12742
|
-
|
|
12743
|
-
|
|
12744
|
-
|
|
12745
|
-
var
|
|
12746
|
-
|
|
12747
|
-
|
|
12748
|
-
|
|
12749
|
-
|
|
12768
|
+
var numStreams = simulcastEnabled ? 3 : 1;
|
|
12769
|
+
if (!this.streamIds.length) {
|
|
12770
|
+
if (mLine.ssrcs.length) {
|
|
12771
|
+
var ssrcs = [...new Set(mLine.ssrcs.map(ssrcLine => ssrcLine.ssrcId))];
|
|
12772
|
+
mLine.ssrcGroups.forEach(sg => {
|
|
12773
|
+
if (!sg.ssrcs.every(ssrc => ssrcs.includes(ssrc))) {
|
|
12774
|
+
throw new Error('SSRC present in SSRC groups is missing from SSRC lines');
|
|
12775
|
+
}
|
|
12776
|
+
});
|
|
12777
|
+
var rtxSsrcGroups = mLine.ssrcGroups.filter(sg => sg.semantics === 'FID');
|
|
12778
|
+
if (rtxSsrcGroups.length && rtxSsrcGroups.length !== numStreams) {
|
|
12779
|
+
throw new Error("Expect ".concat(numStreams, " RTX SSRC groups, got ").concat(rtxSsrcGroups.length));
|
|
12750
12780
|
}
|
|
12751
|
-
|
|
12752
|
-
|
|
12781
|
+
rtxSsrcGroups.forEach(sg => {
|
|
12782
|
+
this.streamIds.push({
|
|
12783
|
+
ssrc: sg.ssrcs[0],
|
|
12784
|
+
rtxSsrc: sg.ssrcs[1]
|
|
12785
|
+
});
|
|
12786
|
+
});
|
|
12787
|
+
var simulcastSsrcs = (_a = mLine.ssrcGroups.find(sg => sg.semantics === 'SIM')) === null || _a === void 0 ? void 0 : _a.ssrcs;
|
|
12788
|
+
if (simulcastSsrcs) {
|
|
12789
|
+
if (simulcastSsrcs.length !== numStreams || !this.streamIds.every(streamId => simulcastSsrcs.includes(streamId.ssrc))) {
|
|
12790
|
+
throw new Error('SSRCs in simulcast SSRC group do not match primary SSRCs in RTX SSRC groups');
|
|
12791
|
+
}
|
|
12792
|
+
this.streamIds.sort((a, b) => simulcastSsrcs.indexOf(a.ssrc) - simulcastSsrcs.indexOf(b.ssrc));
|
|
12793
|
+
} else if (rtxSsrcGroups.length > 1) {
|
|
12794
|
+
throw new Error('Multiple RTX SSRC groups but no simulcast SSRC group found');
|
|
12795
|
+
}
|
|
12796
|
+
if (!this.streamIds.length) {
|
|
12797
|
+
this.streamIds.push({
|
|
12798
|
+
ssrc: ssrcs[0]
|
|
12799
|
+
});
|
|
12800
|
+
}
|
|
12801
|
+
} else {
|
|
12802
|
+
[...Array(numStreams).keys()].forEach(() => {
|
|
12803
|
+
var newStreamId = {
|
|
12804
|
+
ssrc: generateSsrc()
|
|
12805
|
+
};
|
|
12806
|
+
if (rtxEnabled) {
|
|
12807
|
+
newStreamId.rtxSsrc = generateSsrc();
|
|
12808
|
+
}
|
|
12809
|
+
this.streamIds.push(newStreamId);
|
|
12810
|
+
});
|
|
12811
|
+
}
|
|
12753
12812
|
}
|
|
12813
|
+
mLine.ssrcs = [];
|
|
12814
|
+
mLine.ssrcGroups = [];
|
|
12754
12815
|
this.streamIds.forEach(streamId => {
|
|
12755
12816
|
var rtpSsrc = streamId.ssrc;
|
|
12756
12817
|
mLine.addLine(new SsrcLine(rtpSsrc, 'cname', "".concat(rtpSsrc, "-cname")));
|
|
@@ -14505,6 +14566,15 @@ function setLogHandler(logHandler) {
|
|
|
14505
14566
|
function toMediaStreamTrackKind(mediaType) {
|
|
14506
14567
|
return [MediaType.VideoMain, MediaType.VideoSlides].includes(mediaType) ? exports.MediaStreamTrackKind.Video : exports.MediaStreamTrackKind.Audio;
|
|
14507
14568
|
}
|
|
14569
|
+
function webRtcVideoContentHintToJmpVideoContentHint(hint) {
|
|
14570
|
+
if (hint === 'motion') {
|
|
14571
|
+
return 'motion';
|
|
14572
|
+
}
|
|
14573
|
+
if (hint === 'detail') {
|
|
14574
|
+
return 'sharpness';
|
|
14575
|
+
}
|
|
14576
|
+
return undefined;
|
|
14577
|
+
}
|
|
14508
14578
|
function toMediaFamily(kind) {
|
|
14509
14579
|
if (kind === exports.MediaStreamTrackKind.Video) {
|
|
14510
14580
|
return MediaFamily.Video;
|
|
@@ -14700,7 +14770,7 @@ class MultistreamConnection extends EventEmitter {
|
|
|
14700
14770
|
state: 'invalid source',
|
|
14701
14771
|
csi: sendTransceiver.csi
|
|
14702
14772
|
});
|
|
14703
|
-
} else if (signaler.getEncodingIndexForStreamId(id)
|
|
14773
|
+
} else if (signaler.getEncodingIndexForStreamId(id) >= activeSimulcastLayerNumber) {
|
|
14704
14774
|
sourceWarnings.push({
|
|
14705
14775
|
id,
|
|
14706
14776
|
state: 'no source',
|
|
@@ -14770,24 +14840,8 @@ class MultistreamConnection extends EventEmitter {
|
|
|
14770
14840
|
var dataChannel = this.pc.createDataChannel('datachannel', {});
|
|
14771
14841
|
dataChannel.onopen = e => {
|
|
14772
14842
|
logger$4.info('DataChannel opened: ', e);
|
|
14773
|
-
this.sendTransceivers.forEach(
|
|
14774
|
-
|
|
14775
|
-
if (track) {
|
|
14776
|
-
if (getMediaFamily$1(mediaType) === MediaFamily.Audio) {
|
|
14777
|
-
this.sendSourceIndication(mediaType, +!track.muted);
|
|
14778
|
-
} else {
|
|
14779
|
-
var signaler = this.streamSignalerManager.getEgressStreamSignalerOrThrow(transceiver.mid);
|
|
14780
|
-
var state = track.muted ? 'avatar' : 'live';
|
|
14781
|
-
var sources = signaler.getSenderIds().map(id => ({
|
|
14782
|
-
id,
|
|
14783
|
-
state,
|
|
14784
|
-
csi: transceiver.csi
|
|
14785
|
-
}));
|
|
14786
|
-
this.sendSourceIndication(mediaType, +!track.muted, sources);
|
|
14787
|
-
}
|
|
14788
|
-
} else {
|
|
14789
|
-
this.sendSourceIndication(mediaType, 0);
|
|
14790
|
-
}
|
|
14843
|
+
[...this.sendTransceivers.keys()].forEach(mediaType => {
|
|
14844
|
+
this.maybeSendSourceIndication(mediaType);
|
|
14791
14845
|
});
|
|
14792
14846
|
logger$4.info("Flushing pending JMP task queue");
|
|
14793
14847
|
this.pendingJmpTasks.forEach(t => t());
|
|
@@ -14835,12 +14889,31 @@ class MultistreamConnection extends EventEmitter {
|
|
|
14835
14889
|
});
|
|
14836
14890
|
this.pc.close();
|
|
14837
14891
|
}
|
|
14892
|
+
maybeSendSourceIndication(mediaType) {
|
|
14893
|
+
var _a;
|
|
14894
|
+
var transceiver = this.getSendTransceiverOrThrow(mediaType);
|
|
14895
|
+
var numLiveSources = ((_a = transceiver.publishedTrack) === null || _a === void 0 ? void 0 : _a.muted) === false ? 1 : 0;
|
|
14896
|
+
if (getMediaFamily$1(mediaType) === MediaFamily.Video) {
|
|
14897
|
+
var sources = this.getVideoSources(mediaType);
|
|
14898
|
+
if (sources === null) {
|
|
14899
|
+
return;
|
|
14900
|
+
}
|
|
14901
|
+
var webRtcVideoContentHint;
|
|
14902
|
+
if (transceiver.publishedTrack instanceof LocalDisplayTrack) {
|
|
14903
|
+
webRtcVideoContentHint = transceiver.publishedTrack.videoContentHint;
|
|
14904
|
+
}
|
|
14905
|
+
this.sendSourceIndication(mediaType, numLiveSources, sources, webRtcVideoContentHintToJmpVideoContentHint(webRtcVideoContentHint));
|
|
14906
|
+
} else {
|
|
14907
|
+
this.sendSourceIndication(mediaType, numLiveSources);
|
|
14908
|
+
}
|
|
14909
|
+
}
|
|
14838
14910
|
sendSourceIndication(mediaType, numLiveSources) {
|
|
14839
14911
|
var sources = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
|
|
14912
|
+
var videoContentHint = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : undefined;
|
|
14840
14913
|
var _a;
|
|
14841
14914
|
var task = () => {
|
|
14842
14915
|
var _a;
|
|
14843
|
-
(_a = this.jmpSessions.get(mediaType)) === null || _a === void 0 ? void 0 : _a.updateSourceIndication(1, numLiveSources, sources);
|
|
14916
|
+
(_a = this.jmpSessions.get(mediaType)) === null || _a === void 0 ? void 0 : _a.updateSourceIndication(1, numLiveSources, sources, videoContentHint);
|
|
14844
14917
|
};
|
|
14845
14918
|
if (((_a = this.dataChannel) === null || _a === void 0 ? void 0 : _a.readyState) === 'open') {
|
|
14846
14919
|
task();
|
|
@@ -14882,23 +14955,9 @@ class MultistreamConnection extends EventEmitter {
|
|
|
14882
14955
|
});
|
|
14883
14956
|
}
|
|
14884
14957
|
addTrackListeners(mediaType, track) {
|
|
14885
|
-
var onTrackResolutionChange = () =>
|
|
14886
|
-
var sources = this.getVideoSources(mediaType);
|
|
14887
|
-
if (sources != null) {
|
|
14888
|
-
this.sendSourceIndication(mediaType, 1, sources);
|
|
14889
|
-
}
|
|
14890
|
-
};
|
|
14958
|
+
var onTrackResolutionChange = () => this.maybeSendSourceIndication(mediaType);
|
|
14891
14959
|
track.on(LocalTrack.Events.TrackConstraintsChange, onTrackResolutionChange);
|
|
14892
|
-
var onTrackMute =
|
|
14893
|
-
if (getMediaFamily$1(mediaType) === MediaFamily.Audio) {
|
|
14894
|
-
this.sendSourceIndication(mediaType, +!event.trackState.muted);
|
|
14895
|
-
} else {
|
|
14896
|
-
var sources = this.getVideoSources(mediaType);
|
|
14897
|
-
if (sources != null) {
|
|
14898
|
-
this.sendSourceIndication(mediaType, +!event.trackState.muted, sources);
|
|
14899
|
-
}
|
|
14900
|
-
}
|
|
14901
|
-
};
|
|
14960
|
+
var onTrackMute = () => this.maybeSendSourceIndication(mediaType);
|
|
14902
14961
|
track.on(LocalTrack.Events.Muted, onTrackMute);
|
|
14903
14962
|
var onTrackPublish = event => {
|
|
14904
14963
|
if (!event.isPublished) {
|
|
@@ -14906,13 +14965,8 @@ class MultistreamConnection extends EventEmitter {
|
|
|
14906
14965
|
track.off(LocalTrack.Events.PublishedStateUpdate, onTrackPublish);
|
|
14907
14966
|
track.off(LocalTrack.Events.TrackConstraintsChange, onTrackResolutionChange);
|
|
14908
14967
|
}
|
|
14909
|
-
if (
|
|
14910
|
-
this.
|
|
14911
|
-
} else {
|
|
14912
|
-
var sources = this.getVideoSources(mediaType);
|
|
14913
|
-
if (sources != null) {
|
|
14914
|
-
this.sendSourceIndication(mediaType, +event.isPublished, sources);
|
|
14915
|
-
}
|
|
14968
|
+
if (!track.muted) {
|
|
14969
|
+
this.maybeSendSourceIndication(mediaType);
|
|
14916
14970
|
}
|
|
14917
14971
|
};
|
|
14918
14972
|
track.on(LocalTrack.Events.PublishedStateUpdate, onTrackPublish);
|
|
@@ -15183,7 +15237,7 @@ class MultistreamConnection extends EventEmitter {
|
|
|
15183
15237
|
}
|
|
15184
15238
|
renewPeerConnection(userOptions) {
|
|
15185
15239
|
if (userOptions) {
|
|
15186
|
-
this.options = Object.assign(Object.assign({},
|
|
15240
|
+
this.options = Object.assign(Object.assign({}, this.options), userOptions);
|
|
15187
15241
|
}
|
|
15188
15242
|
logger$4.info("Renewing multistream connection with options ".concat(JSON.stringify(this.options)));
|
|
15189
15243
|
this.clearMids();
|
package/dist/esm/index.js
CHANGED
|
@@ -4668,6 +4668,139 @@ var media = /*#__PURE__*/Object.freeze({
|
|
|
4668
4668
|
checkDevicePermissions: checkDevicePermissions,
|
|
4669
4669
|
ensureDevicePermissions: ensureDevicePermissions
|
|
4670
4670
|
});
|
|
4671
|
+
var ErrorTypes;
|
|
4672
|
+
(function (ErrorTypes) {
|
|
4673
|
+
ErrorTypes["DEVICE_PERMISSION_DENIED"] = "DEVICE_PERMISSION_DENIED";
|
|
4674
|
+
ErrorTypes["CREATE_CAMERA_TRACK_FAILED"] = "CREATE_CAMERA_TRACK_FAILED";
|
|
4675
|
+
ErrorTypes["CREATE_MICROPHONE_TRACK_FAILED"] = "CREATE_MICROPHONE_TRACK_FAILED";
|
|
4676
|
+
})(ErrorTypes || (ErrorTypes = {}));
|
|
4677
|
+
/**
|
|
4678
|
+
* Represents a WCME error, which contains error type and error message.
|
|
4679
|
+
*/
|
|
4680
|
+
class WcmeError {
|
|
4681
|
+
/**
|
|
4682
|
+
* Creates new error.
|
|
4683
|
+
*
|
|
4684
|
+
* @param type - Error type.
|
|
4685
|
+
* @param message - Error message.
|
|
4686
|
+
*/
|
|
4687
|
+
constructor(type) {
|
|
4688
|
+
var message = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
|
|
4689
|
+
this.type = type;
|
|
4690
|
+
this.message = message;
|
|
4691
|
+
}
|
|
4692
|
+
}
|
|
4693
|
+
/**
|
|
4694
|
+
* Creates a camera video track. Please note that the constraint params in second getUserMedia call would NOT take effect when:
|
|
4695
|
+
*
|
|
4696
|
+
* 1. Previous captured video track from the same device is not stopped .
|
|
4697
|
+
* 2. Previous createCameraTrack() call for the same device is in progress.
|
|
4698
|
+
*
|
|
4699
|
+
* @param constructor - Constructor for the local camera track.
|
|
4700
|
+
* @param constraints - Video device constraints.
|
|
4701
|
+
* @returns A LocalTrack object or an error.
|
|
4702
|
+
*/
|
|
4703
|
+
function createCameraTrack(constructor, constraints) {
|
|
4704
|
+
return __awaiter$1(this, void 0, void 0, function* () {
|
|
4705
|
+
var stream;
|
|
4706
|
+
try {
|
|
4707
|
+
stream = yield getUserMedia({
|
|
4708
|
+
video: Object.assign({}, constraints)
|
|
4709
|
+
});
|
|
4710
|
+
} catch (error) {
|
|
4711
|
+
throw new WcmeError(ErrorTypes.CREATE_CAMERA_TRACK_FAILED, "Failed to create camera track ".concat(error));
|
|
4712
|
+
}
|
|
4713
|
+
return new constructor(stream);
|
|
4714
|
+
});
|
|
4715
|
+
}
|
|
4716
|
+
/**
|
|
4717
|
+
* Creates a microphone audio track.
|
|
4718
|
+
*
|
|
4719
|
+
* @param constructor - Constructor for the local microphone track.
|
|
4720
|
+
* @param constraints - Audio device constraints.
|
|
4721
|
+
* @returns A LocalTrack object or an error.
|
|
4722
|
+
*/
|
|
4723
|
+
function createMicrophoneTrack(constructor, constraints) {
|
|
4724
|
+
return __awaiter$1(this, void 0, void 0, function* () {
|
|
4725
|
+
var stream;
|
|
4726
|
+
try {
|
|
4727
|
+
stream = yield getUserMedia({
|
|
4728
|
+
audio: Object.assign({}, constraints)
|
|
4729
|
+
});
|
|
4730
|
+
} catch (error) {
|
|
4731
|
+
throw new WcmeError(ErrorTypes.CREATE_MICROPHONE_TRACK_FAILED, "Failed to create microphone track ".concat(error));
|
|
4732
|
+
}
|
|
4733
|
+
return new constructor(stream);
|
|
4734
|
+
});
|
|
4735
|
+
}
|
|
4736
|
+
/**
|
|
4737
|
+
* Creates a display video track.
|
|
4738
|
+
*
|
|
4739
|
+
* @param constructor - Constructor for the local display track.
|
|
4740
|
+
* @param videoContentHint - An optional parameters to give a hint for the content of the track.
|
|
4741
|
+
* @returns A Promise that resolves to a LocalDisplayTrack.
|
|
4742
|
+
*/
|
|
4743
|
+
function createDisplayTrack(constructor, videoContentHint) {
|
|
4744
|
+
return __awaiter$1(this, void 0, void 0, function* () {
|
|
4745
|
+
var stream = yield getDisplayMedia({
|
|
4746
|
+
video: true
|
|
4747
|
+
});
|
|
4748
|
+
return new constructor(stream, videoContentHint);
|
|
4749
|
+
});
|
|
4750
|
+
}
|
|
4751
|
+
/**
|
|
4752
|
+
* Enumerates the media input and output devices available.
|
|
4753
|
+
*
|
|
4754
|
+
* @param deviceKind - Optional filter to return a specific device kind.
|
|
4755
|
+
* @returns List of media devices in an array of MediaDeviceInfo objects.
|
|
4756
|
+
*/
|
|
4757
|
+
function getDevices(deviceKind) {
|
|
4758
|
+
return __awaiter$1(this, void 0, void 0, function* () {
|
|
4759
|
+
var devices;
|
|
4760
|
+
try {
|
|
4761
|
+
devices = yield ensureDevicePermissions([DeviceKind.AudioInput, DeviceKind.VideoInput], enumerateDevices);
|
|
4762
|
+
} catch (error) {
|
|
4763
|
+
throw new WcmeError(ErrorTypes.DEVICE_PERMISSION_DENIED, 'Failed to ensure device permissions');
|
|
4764
|
+
}
|
|
4765
|
+
return devices.filter(v => deviceKind ? v.kind === deviceKind : true);
|
|
4766
|
+
});
|
|
4767
|
+
}
|
|
4768
|
+
/**
|
|
4769
|
+
* Helper function to get a list of microphone devices.
|
|
4770
|
+
*
|
|
4771
|
+
* @returns List of microphone devices in an array of MediaDeviceInfo objects.
|
|
4772
|
+
*/
|
|
4773
|
+
function getAudioInputDevices() {
|
|
4774
|
+
return __awaiter$1(this, void 0, void 0, function* () {
|
|
4775
|
+
return getDevices(DeviceKind.AudioInput);
|
|
4776
|
+
});
|
|
4777
|
+
}
|
|
4778
|
+
/**
|
|
4779
|
+
* Helper function to get a list of speaker devices.
|
|
4780
|
+
*
|
|
4781
|
+
* @returns List of speaker devices in an array of MediaDeviceInfo objects.
|
|
4782
|
+
*/
|
|
4783
|
+
function getAudioOutputDevices() {
|
|
4784
|
+
return __awaiter$1(this, void 0, void 0, function* () {
|
|
4785
|
+
return getDevices(DeviceKind.AudioOutput);
|
|
4786
|
+
});
|
|
4787
|
+
}
|
|
4788
|
+
/**
|
|
4789
|
+
* Helper function to get a list of camera devices.
|
|
4790
|
+
*
|
|
4791
|
+
* @returns List of camera devices in an array of MediaDeviceInfo objects.
|
|
4792
|
+
*/
|
|
4793
|
+
function getVideoInputDevices() {
|
|
4794
|
+
return __awaiter$1(this, void 0, void 0, function* () {
|
|
4795
|
+
return getDevices(DeviceKind.VideoInput);
|
|
4796
|
+
});
|
|
4797
|
+
}
|
|
4798
|
+
/**
|
|
4799
|
+
* Export the setOnDeviceChangeHandler method directly from the core lib.
|
|
4800
|
+
*/
|
|
4801
|
+
var {
|
|
4802
|
+
setOnDeviceChangeHandler
|
|
4803
|
+
} = media;
|
|
4671
4804
|
var events$1 = {
|
|
4672
4805
|
exports: {}
|
|
4673
4806
|
};
|
|
@@ -5340,141 +5473,32 @@ class LocalCameraTrack extends LocalTrack {}
|
|
|
5340
5473
|
/**
|
|
5341
5474
|
* Represents a local track for a display source.
|
|
5342
5475
|
*/
|
|
5343
|
-
class LocalDisplayTrack extends LocalTrack {
|
|
5344
|
-
|
|
5345
|
-
/**
|
|
5346
|
-
* Represents a local track for a microphone source.
|
|
5347
|
-
*/
|
|
5348
|
-
class LocalMicrophoneTrack extends LocalTrack {}
|
|
5349
|
-
var ErrorTypes;
|
|
5350
|
-
(function (ErrorTypes) {
|
|
5351
|
-
ErrorTypes["DEVICE_PERMISSION_DENIED"] = "DEVICE_PERMISSION_DENIED";
|
|
5352
|
-
ErrorTypes["CREATE_CAMERA_TRACK_FAILED"] = "CREATE_CAMERA_TRACK_FAILED";
|
|
5353
|
-
ErrorTypes["CREATE_MICROPHONE_TRACK_FAILED"] = "CREATE_MICROPHONE_TRACK_FAILED";
|
|
5354
|
-
})(ErrorTypes || (ErrorTypes = {}));
|
|
5355
|
-
/**
|
|
5356
|
-
* Represents a WCME error, which contains error type and error message.
|
|
5357
|
-
*/
|
|
5358
|
-
class WcmeError {
|
|
5476
|
+
class LocalDisplayTrack extends LocalTrack {
|
|
5359
5477
|
/**
|
|
5360
|
-
*
|
|
5478
|
+
* Create a LocalDisplayTrack from the given values.
|
|
5361
5479
|
*
|
|
5362
|
-
* @param
|
|
5363
|
-
* @param
|
|
5480
|
+
* @param stream - The MediaStream for this track.
|
|
5481
|
+
* @param videoContentHint - An optional content hint, describing the content of the track.
|
|
5364
5482
|
*/
|
|
5365
|
-
constructor(
|
|
5366
|
-
|
|
5367
|
-
this.
|
|
5368
|
-
this.
|
|
5483
|
+
constructor(stream, videoContentHint) {
|
|
5484
|
+
super(stream);
|
|
5485
|
+
this._videoContentHint = videoContentHint;
|
|
5486
|
+
this.underlyingTrack.contentHint = videoContentHint || '';
|
|
5487
|
+
}
|
|
5488
|
+
/**
|
|
5489
|
+
* Get the VideoContentHint for this track.
|
|
5490
|
+
*
|
|
5491
|
+
* @returns The VideoContentHint for this track.
|
|
5492
|
+
*/
|
|
5493
|
+
get videoContentHint() {
|
|
5494
|
+
return this._videoContentHint;
|
|
5369
5495
|
}
|
|
5370
5496
|
}
|
|
5497
|
+
|
|
5371
5498
|
/**
|
|
5372
|
-
*
|
|
5373
|
-
*
|
|
5374
|
-
* 1. Previous captured video track from the same device is not stopped .
|
|
5375
|
-
* 2. Previous createCameraTrack() call for the same device is in progress.
|
|
5376
|
-
*
|
|
5377
|
-
* @param constraints - Video device constraints.
|
|
5378
|
-
* @returns A LocalTrack object or an error.
|
|
5379
|
-
*/
|
|
5380
|
-
function createCameraTrack(constraints) {
|
|
5381
|
-
return __awaiter$1(this, void 0, void 0, function* () {
|
|
5382
|
-
var stream;
|
|
5383
|
-
try {
|
|
5384
|
-
stream = yield getUserMedia({
|
|
5385
|
-
video: Object.assign({}, constraints)
|
|
5386
|
-
});
|
|
5387
|
-
} catch (error) {
|
|
5388
|
-
throw new WcmeError(ErrorTypes.CREATE_CAMERA_TRACK_FAILED, "Failed to create camera track ".concat(error));
|
|
5389
|
-
}
|
|
5390
|
-
return new LocalCameraTrack(stream);
|
|
5391
|
-
});
|
|
5392
|
-
}
|
|
5393
|
-
/**
|
|
5394
|
-
* Creates a microphone audio track.
|
|
5395
|
-
*
|
|
5396
|
-
* @param constraints - Audio device constraints.
|
|
5397
|
-
* @returns A LocalTrack object or an error.
|
|
5398
|
-
*/
|
|
5399
|
-
function createMicrophoneTrack(constraints) {
|
|
5400
|
-
return __awaiter$1(this, void 0, void 0, function* () {
|
|
5401
|
-
var stream;
|
|
5402
|
-
try {
|
|
5403
|
-
stream = yield getUserMedia({
|
|
5404
|
-
audio: Object.assign({}, constraints)
|
|
5405
|
-
});
|
|
5406
|
-
} catch (error) {
|
|
5407
|
-
throw new WcmeError(ErrorTypes.CREATE_MICROPHONE_TRACK_FAILED, "Failed to create microphone track ".concat(error));
|
|
5408
|
-
}
|
|
5409
|
-
return new LocalMicrophoneTrack(stream);
|
|
5410
|
-
});
|
|
5411
|
-
}
|
|
5412
|
-
/**
|
|
5413
|
-
* Creates a display video track.
|
|
5414
|
-
*
|
|
5415
|
-
* @returns A Promise that resolves to a LocalDisplayTrack.
|
|
5416
|
-
*/
|
|
5417
|
-
function createDisplayTrack() {
|
|
5418
|
-
return __awaiter$1(this, void 0, void 0, function* () {
|
|
5419
|
-
var stream = yield getDisplayMedia({
|
|
5420
|
-
video: true
|
|
5421
|
-
});
|
|
5422
|
-
return new LocalDisplayTrack(stream);
|
|
5423
|
-
});
|
|
5424
|
-
}
|
|
5425
|
-
/**
|
|
5426
|
-
* Enumerates the media input and output devices available.
|
|
5427
|
-
*
|
|
5428
|
-
* @param deviceKind - Optional filter to return a specific device kind.
|
|
5429
|
-
* @returns List of media devices in an array of MediaDeviceInfo objects.
|
|
5430
|
-
*/
|
|
5431
|
-
function getDevices(deviceKind) {
|
|
5432
|
-
return __awaiter$1(this, void 0, void 0, function* () {
|
|
5433
|
-
var devices;
|
|
5434
|
-
try {
|
|
5435
|
-
devices = yield ensureDevicePermissions([DeviceKind.AudioInput, DeviceKind.VideoInput], enumerateDevices);
|
|
5436
|
-
} catch (error) {
|
|
5437
|
-
throw new WcmeError(ErrorTypes.DEVICE_PERMISSION_DENIED, 'Failed to ensure device permissions');
|
|
5438
|
-
}
|
|
5439
|
-
return devices.filter(v => deviceKind ? v.kind === deviceKind : true);
|
|
5440
|
-
});
|
|
5441
|
-
}
|
|
5442
|
-
/**
|
|
5443
|
-
* Helper function to get a list of microphone devices.
|
|
5444
|
-
*
|
|
5445
|
-
* @returns List of microphone devices in an array of MediaDeviceInfo objects.
|
|
5446
|
-
*/
|
|
5447
|
-
function getAudioInputDevices() {
|
|
5448
|
-
return __awaiter$1(this, void 0, void 0, function* () {
|
|
5449
|
-
return getDevices(DeviceKind.AudioInput);
|
|
5450
|
-
});
|
|
5451
|
-
}
|
|
5452
|
-
/**
|
|
5453
|
-
* Helper function to get a list of speaker devices.
|
|
5454
|
-
*
|
|
5455
|
-
* @returns List of speaker devices in an array of MediaDeviceInfo objects.
|
|
5456
|
-
*/
|
|
5457
|
-
function getAudioOutputDevices() {
|
|
5458
|
-
return __awaiter$1(this, void 0, void 0, function* () {
|
|
5459
|
-
return getDevices(DeviceKind.AudioOutput);
|
|
5460
|
-
});
|
|
5461
|
-
}
|
|
5462
|
-
/**
|
|
5463
|
-
* Helper function to get a list of camera devices.
|
|
5464
|
-
*
|
|
5465
|
-
* @returns List of camera devices in an array of MediaDeviceInfo objects.
|
|
5466
|
-
*/
|
|
5467
|
-
function getVideoInputDevices() {
|
|
5468
|
-
return __awaiter$1(this, void 0, void 0, function* () {
|
|
5469
|
-
return getDevices(DeviceKind.VideoInput);
|
|
5470
|
-
});
|
|
5471
|
-
}
|
|
5472
|
-
/**
|
|
5473
|
-
* Export the setOnDeviceChangeHandler method directly from the core lib.
|
|
5499
|
+
* Represents a local track for a microphone source.
|
|
5474
5500
|
*/
|
|
5475
|
-
|
|
5476
|
-
setOnDeviceChangeHandler
|
|
5477
|
-
} = media;
|
|
5501
|
+
class LocalMicrophoneTrack extends LocalTrack {}
|
|
5478
5502
|
|
|
5479
5503
|
// Overall connection state (based on the ICE and DTLS connection states)
|
|
5480
5504
|
var ConnectionState;
|
|
@@ -9469,11 +9493,12 @@ function compareStreamIds(id1, id2) {
|
|
|
9469
9493
|
return keys1.every(key => id1[key] === id2[key]);
|
|
9470
9494
|
}
|
|
9471
9495
|
class SourceIndicationMsg {
|
|
9472
|
-
constructor(seqNum, numTotalSources, numLiveSources, sources) {
|
|
9496
|
+
constructor(seqNum, numTotalSources, numLiveSources, sources, videoContentHint) {
|
|
9473
9497
|
this.seqNum = seqNum;
|
|
9474
9498
|
this.numTotalSources = numTotalSources;
|
|
9475
9499
|
this.numLiveSources = numLiveSources;
|
|
9476
9500
|
this.sources = sources;
|
|
9501
|
+
this.videoContentHint = videoContentHint;
|
|
9477
9502
|
}
|
|
9478
9503
|
sourcesToString() {
|
|
9479
9504
|
return this.sources.map(source => "Source(id=".concat(source.id, " state=").concat(source.state, " ").concat(source.csi ? "csi=".concat(source.csi) : '', ")")).join(', ');
|
|
@@ -9560,13 +9585,13 @@ class JmpSession extends EventEmitter$4 {
|
|
|
9560
9585
|
this.logger.warn("Retransmits for message expired: ".concat(expiredJmpMsg));
|
|
9561
9586
|
});
|
|
9562
9587
|
}
|
|
9563
|
-
updateSourceIndication(numTotalSources, numLiveSources, sources) {
|
|
9588
|
+
updateSourceIndication(numTotalSources, numLiveSources, sources, videoContentHint) {
|
|
9564
9589
|
var _a;
|
|
9565
9590
|
var filteredSources = sources.filter(source => {
|
|
9566
9591
|
var _a;
|
|
9567
9592
|
return (_a = this.lastReceivedScr) === null || _a === void 0 ? void 0 : _a.requests.some(req => req.ids.find(streamId => compareStreamIds(streamId, source.id)));
|
|
9568
9593
|
});
|
|
9569
|
-
var sourceIndicationMsg = new SourceIndicationMsg(this.currSourceIndicationSeqNum++, numTotalSources, numLiveSources, filteredSources);
|
|
9594
|
+
var sourceIndicationMsg = new SourceIndicationMsg(this.currSourceIndicationSeqNum++, numTotalSources, numLiveSources, filteredSources, videoContentHint);
|
|
9570
9595
|
var jmpMsg = new JmpMsg(this.mediaFamily, this.mediaContent, {
|
|
9571
9596
|
msgType: JmpMsgType$1.SourceIndication,
|
|
9572
9597
|
payload: sourceIndicationMsg
|
|
@@ -12711,7 +12736,9 @@ class SsrcIngressStreamSignaler {
|
|
|
12711
12736
|
mLine.addLine(new SsrcLine(this.ssrc, 'cname', "".concat(this.ssrc, "-cname")));
|
|
12712
12737
|
mLine.addLine(new SsrcLine(this.ssrc, 'msid', '-', '1'));
|
|
12713
12738
|
if (hasCodec('rtx', mLine)) {
|
|
12714
|
-
this.rtxSsrc
|
|
12739
|
+
if (!this.rtxSsrc) {
|
|
12740
|
+
this.rtxSsrc = generateSsrc();
|
|
12741
|
+
}
|
|
12715
12742
|
mLine.addLine(new SsrcLine(this.rtxSsrc, 'cname', "".concat(this.ssrc, "-cname")));
|
|
12716
12743
|
mLine.addLine(new SsrcLine(this.rtxSsrc, 'msid', '-', '1'));
|
|
12717
12744
|
mLine.addLine(new SsrcGroupLine('FID', [this.ssrc, this.rtxSsrc]));
|
|
@@ -12723,23 +12750,57 @@ class SsrcEgressStreamSignaler {
|
|
|
12723
12750
|
this.streamIds = [];
|
|
12724
12751
|
}
|
|
12725
12752
|
signalStreams(simulcastEnabled, rtxEnabled, mLine) {
|
|
12753
|
+
var _a;
|
|
12726
12754
|
mLine.rids = [];
|
|
12727
12755
|
mLine.simulcast = undefined;
|
|
12728
|
-
mLine.ssrcs = [];
|
|
12729
|
-
mLine.ssrcGroups = [];
|
|
12730
12756
|
mLine.extMaps = mLine.extMaps.filter(extMapLine => !/^urn:ietf:params:rtp-hdrext:sdes:(?:mid|rtp-stream-id|repaired-rtp-stream-id)$/.test(extMapLine.uri));
|
|
12731
|
-
|
|
12732
|
-
|
|
12733
|
-
|
|
12734
|
-
var
|
|
12735
|
-
|
|
12736
|
-
|
|
12737
|
-
|
|
12738
|
-
|
|
12757
|
+
var numStreams = simulcastEnabled ? 3 : 1;
|
|
12758
|
+
if (!this.streamIds.length) {
|
|
12759
|
+
if (mLine.ssrcs.length) {
|
|
12760
|
+
var ssrcs = [...new Set(mLine.ssrcs.map(ssrcLine => ssrcLine.ssrcId))];
|
|
12761
|
+
mLine.ssrcGroups.forEach(sg => {
|
|
12762
|
+
if (!sg.ssrcs.every(ssrc => ssrcs.includes(ssrc))) {
|
|
12763
|
+
throw new Error('SSRC present in SSRC groups is missing from SSRC lines');
|
|
12764
|
+
}
|
|
12765
|
+
});
|
|
12766
|
+
var rtxSsrcGroups = mLine.ssrcGroups.filter(sg => sg.semantics === 'FID');
|
|
12767
|
+
if (rtxSsrcGroups.length && rtxSsrcGroups.length !== numStreams) {
|
|
12768
|
+
throw new Error("Expect ".concat(numStreams, " RTX SSRC groups, got ").concat(rtxSsrcGroups.length));
|
|
12739
12769
|
}
|
|
12740
|
-
|
|
12741
|
-
|
|
12770
|
+
rtxSsrcGroups.forEach(sg => {
|
|
12771
|
+
this.streamIds.push({
|
|
12772
|
+
ssrc: sg.ssrcs[0],
|
|
12773
|
+
rtxSsrc: sg.ssrcs[1]
|
|
12774
|
+
});
|
|
12775
|
+
});
|
|
12776
|
+
var simulcastSsrcs = (_a = mLine.ssrcGroups.find(sg => sg.semantics === 'SIM')) === null || _a === void 0 ? void 0 : _a.ssrcs;
|
|
12777
|
+
if (simulcastSsrcs) {
|
|
12778
|
+
if (simulcastSsrcs.length !== numStreams || !this.streamIds.every(streamId => simulcastSsrcs.includes(streamId.ssrc))) {
|
|
12779
|
+
throw new Error('SSRCs in simulcast SSRC group do not match primary SSRCs in RTX SSRC groups');
|
|
12780
|
+
}
|
|
12781
|
+
this.streamIds.sort((a, b) => simulcastSsrcs.indexOf(a.ssrc) - simulcastSsrcs.indexOf(b.ssrc));
|
|
12782
|
+
} else if (rtxSsrcGroups.length > 1) {
|
|
12783
|
+
throw new Error('Multiple RTX SSRC groups but no simulcast SSRC group found');
|
|
12784
|
+
}
|
|
12785
|
+
if (!this.streamIds.length) {
|
|
12786
|
+
this.streamIds.push({
|
|
12787
|
+
ssrc: ssrcs[0]
|
|
12788
|
+
});
|
|
12789
|
+
}
|
|
12790
|
+
} else {
|
|
12791
|
+
[...Array(numStreams).keys()].forEach(() => {
|
|
12792
|
+
var newStreamId = {
|
|
12793
|
+
ssrc: generateSsrc()
|
|
12794
|
+
};
|
|
12795
|
+
if (rtxEnabled) {
|
|
12796
|
+
newStreamId.rtxSsrc = generateSsrc();
|
|
12797
|
+
}
|
|
12798
|
+
this.streamIds.push(newStreamId);
|
|
12799
|
+
});
|
|
12800
|
+
}
|
|
12742
12801
|
}
|
|
12802
|
+
mLine.ssrcs = [];
|
|
12803
|
+
mLine.ssrcGroups = [];
|
|
12743
12804
|
this.streamIds.forEach(streamId => {
|
|
12744
12805
|
var rtpSsrc = streamId.ssrc;
|
|
12745
12806
|
mLine.addLine(new SsrcLine(rtpSsrc, 'cname', "".concat(rtpSsrc, "-cname")));
|
|
@@ -14494,6 +14555,15 @@ function setLogHandler(logHandler) {
|
|
|
14494
14555
|
function toMediaStreamTrackKind(mediaType) {
|
|
14495
14556
|
return [MediaType$1.VideoMain, MediaType$1.VideoSlides].includes(mediaType) ? MediaStreamTrackKind.Video : MediaStreamTrackKind.Audio;
|
|
14496
14557
|
}
|
|
14558
|
+
function webRtcVideoContentHintToJmpVideoContentHint(hint) {
|
|
14559
|
+
if (hint === 'motion') {
|
|
14560
|
+
return 'motion';
|
|
14561
|
+
}
|
|
14562
|
+
if (hint === 'detail') {
|
|
14563
|
+
return 'sharpness';
|
|
14564
|
+
}
|
|
14565
|
+
return undefined;
|
|
14566
|
+
}
|
|
14497
14567
|
function toMediaFamily(kind) {
|
|
14498
14568
|
if (kind === MediaStreamTrackKind.Video) {
|
|
14499
14569
|
return MediaFamily$1.Video;
|
|
@@ -14689,7 +14759,7 @@ class MultistreamConnection extends EventEmitter {
|
|
|
14689
14759
|
state: 'invalid source',
|
|
14690
14760
|
csi: sendTransceiver.csi
|
|
14691
14761
|
});
|
|
14692
|
-
} else if (signaler.getEncodingIndexForStreamId(id)
|
|
14762
|
+
} else if (signaler.getEncodingIndexForStreamId(id) >= activeSimulcastLayerNumber) {
|
|
14693
14763
|
sourceWarnings.push({
|
|
14694
14764
|
id,
|
|
14695
14765
|
state: 'no source',
|
|
@@ -14759,24 +14829,8 @@ class MultistreamConnection extends EventEmitter {
|
|
|
14759
14829
|
var dataChannel = this.pc.createDataChannel('datachannel', {});
|
|
14760
14830
|
dataChannel.onopen = e => {
|
|
14761
14831
|
logger$4.info('DataChannel opened: ', e);
|
|
14762
|
-
this.sendTransceivers.forEach(
|
|
14763
|
-
|
|
14764
|
-
if (track) {
|
|
14765
|
-
if (getMediaFamily$1(mediaType) === MediaFamily$1.Audio) {
|
|
14766
|
-
this.sendSourceIndication(mediaType, +!track.muted);
|
|
14767
|
-
} else {
|
|
14768
|
-
var signaler = this.streamSignalerManager.getEgressStreamSignalerOrThrow(transceiver.mid);
|
|
14769
|
-
var state = track.muted ? 'avatar' : 'live';
|
|
14770
|
-
var sources = signaler.getSenderIds().map(id => ({
|
|
14771
|
-
id,
|
|
14772
|
-
state,
|
|
14773
|
-
csi: transceiver.csi
|
|
14774
|
-
}));
|
|
14775
|
-
this.sendSourceIndication(mediaType, +!track.muted, sources);
|
|
14776
|
-
}
|
|
14777
|
-
} else {
|
|
14778
|
-
this.sendSourceIndication(mediaType, 0);
|
|
14779
|
-
}
|
|
14832
|
+
[...this.sendTransceivers.keys()].forEach(mediaType => {
|
|
14833
|
+
this.maybeSendSourceIndication(mediaType);
|
|
14780
14834
|
});
|
|
14781
14835
|
logger$4.info("Flushing pending JMP task queue");
|
|
14782
14836
|
this.pendingJmpTasks.forEach(t => t());
|
|
@@ -14824,12 +14878,31 @@ class MultistreamConnection extends EventEmitter {
|
|
|
14824
14878
|
});
|
|
14825
14879
|
this.pc.close();
|
|
14826
14880
|
}
|
|
14881
|
+
maybeSendSourceIndication(mediaType) {
|
|
14882
|
+
var _a;
|
|
14883
|
+
var transceiver = this.getSendTransceiverOrThrow(mediaType);
|
|
14884
|
+
var numLiveSources = ((_a = transceiver.publishedTrack) === null || _a === void 0 ? void 0 : _a.muted) === false ? 1 : 0;
|
|
14885
|
+
if (getMediaFamily$1(mediaType) === MediaFamily$1.Video) {
|
|
14886
|
+
var sources = this.getVideoSources(mediaType);
|
|
14887
|
+
if (sources === null) {
|
|
14888
|
+
return;
|
|
14889
|
+
}
|
|
14890
|
+
var webRtcVideoContentHint;
|
|
14891
|
+
if (transceiver.publishedTrack instanceof LocalDisplayTrack) {
|
|
14892
|
+
webRtcVideoContentHint = transceiver.publishedTrack.videoContentHint;
|
|
14893
|
+
}
|
|
14894
|
+
this.sendSourceIndication(mediaType, numLiveSources, sources, webRtcVideoContentHintToJmpVideoContentHint(webRtcVideoContentHint));
|
|
14895
|
+
} else {
|
|
14896
|
+
this.sendSourceIndication(mediaType, numLiveSources);
|
|
14897
|
+
}
|
|
14898
|
+
}
|
|
14827
14899
|
sendSourceIndication(mediaType, numLiveSources) {
|
|
14828
14900
|
var sources = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
|
|
14901
|
+
var videoContentHint = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : undefined;
|
|
14829
14902
|
var _a;
|
|
14830
14903
|
var task = () => {
|
|
14831
14904
|
var _a;
|
|
14832
|
-
(_a = this.jmpSessions.get(mediaType)) === null || _a === void 0 ? void 0 : _a.updateSourceIndication(1, numLiveSources, sources);
|
|
14905
|
+
(_a = this.jmpSessions.get(mediaType)) === null || _a === void 0 ? void 0 : _a.updateSourceIndication(1, numLiveSources, sources, videoContentHint);
|
|
14833
14906
|
};
|
|
14834
14907
|
if (((_a = this.dataChannel) === null || _a === void 0 ? void 0 : _a.readyState) === 'open') {
|
|
14835
14908
|
task();
|
|
@@ -14871,23 +14944,9 @@ class MultistreamConnection extends EventEmitter {
|
|
|
14871
14944
|
});
|
|
14872
14945
|
}
|
|
14873
14946
|
addTrackListeners(mediaType, track) {
|
|
14874
|
-
var onTrackResolutionChange = () =>
|
|
14875
|
-
var sources = this.getVideoSources(mediaType);
|
|
14876
|
-
if (sources != null) {
|
|
14877
|
-
this.sendSourceIndication(mediaType, 1, sources);
|
|
14878
|
-
}
|
|
14879
|
-
};
|
|
14947
|
+
var onTrackResolutionChange = () => this.maybeSendSourceIndication(mediaType);
|
|
14880
14948
|
track.on(LocalTrack.Events.TrackConstraintsChange, onTrackResolutionChange);
|
|
14881
|
-
var onTrackMute =
|
|
14882
|
-
if (getMediaFamily$1(mediaType) === MediaFamily$1.Audio) {
|
|
14883
|
-
this.sendSourceIndication(mediaType, +!event.trackState.muted);
|
|
14884
|
-
} else {
|
|
14885
|
-
var sources = this.getVideoSources(mediaType);
|
|
14886
|
-
if (sources != null) {
|
|
14887
|
-
this.sendSourceIndication(mediaType, +!event.trackState.muted, sources);
|
|
14888
|
-
}
|
|
14889
|
-
}
|
|
14890
|
-
};
|
|
14949
|
+
var onTrackMute = () => this.maybeSendSourceIndication(mediaType);
|
|
14891
14950
|
track.on(LocalTrack.Events.Muted, onTrackMute);
|
|
14892
14951
|
var onTrackPublish = event => {
|
|
14893
14952
|
if (!event.isPublished) {
|
|
@@ -14895,13 +14954,8 @@ class MultistreamConnection extends EventEmitter {
|
|
|
14895
14954
|
track.off(LocalTrack.Events.PublishedStateUpdate, onTrackPublish);
|
|
14896
14955
|
track.off(LocalTrack.Events.TrackConstraintsChange, onTrackResolutionChange);
|
|
14897
14956
|
}
|
|
14898
|
-
if (
|
|
14899
|
-
this.
|
|
14900
|
-
} else {
|
|
14901
|
-
var sources = this.getVideoSources(mediaType);
|
|
14902
|
-
if (sources != null) {
|
|
14903
|
-
this.sendSourceIndication(mediaType, +event.isPublished, sources);
|
|
14904
|
-
}
|
|
14957
|
+
if (!track.muted) {
|
|
14958
|
+
this.maybeSendSourceIndication(mediaType);
|
|
14905
14959
|
}
|
|
14906
14960
|
};
|
|
14907
14961
|
track.on(LocalTrack.Events.PublishedStateUpdate, onTrackPublish);
|
|
@@ -15172,7 +15226,7 @@ class MultistreamConnection extends EventEmitter {
|
|
|
15172
15226
|
}
|
|
15173
15227
|
renewPeerConnection(userOptions) {
|
|
15174
15228
|
if (userOptions) {
|
|
15175
|
-
this.options = Object.assign(Object.assign({},
|
|
15229
|
+
this.options = Object.assign(Object.assign({}, this.options), userOptions);
|
|
15176
15230
|
}
|
|
15177
15231
|
logger$4.info("Renewing multistream connection with options ".concat(JSON.stringify(this.options)));
|
|
15178
15232
|
this.clearMids();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webex/internal-media-core",
|
|
3
|
-
"version": "1.35.
|
|
3
|
+
"version": "1.35.7",
|
|
4
4
|
"files": [
|
|
5
5
|
"dist/cjs",
|
|
6
6
|
"dist/esm",
|
|
@@ -45,9 +45,9 @@
|
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"@babel/runtime": "^7.18.9",
|
|
48
|
-
"@webex/json-multistream": "1.
|
|
48
|
+
"@webex/json-multistream": "1.22.0",
|
|
49
49
|
"@webex/ts-sdp": "1.3.2",
|
|
50
|
-
"@webex/web-client-media-engine": "1.40.
|
|
50
|
+
"@webex/web-client-media-engine": "1.40.6",
|
|
51
51
|
"detectrtc": "^1.4.1",
|
|
52
52
|
"events": "^3.3.0",
|
|
53
53
|
"typed-emitter": "^2.1.0",
|