mediasoup-client 3.6.47 → 3.6.48
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/lib/Transport.d.ts +3 -0
- package/lib/Transport.d.ts.map +1 -1
- package/lib/Transport.js +110 -39
- package/lib/handlers/Chrome55.d.ts +1 -1
- package/lib/handlers/Chrome55.d.ts.map +1 -1
- package/lib/handlers/Chrome55.js +42 -28
- package/lib/handlers/Chrome67.d.ts +1 -1
- package/lib/handlers/Chrome67.d.ts.map +1 -1
- package/lib/handlers/Chrome67.js +45 -30
- package/lib/handlers/Chrome70.d.ts +1 -1
- package/lib/handlers/Chrome70.d.ts.map +1 -1
- package/lib/handlers/Chrome70.js +42 -29
- package/lib/handlers/Chrome74.d.ts +1 -1
- package/lib/handlers/Chrome74.d.ts.map +1 -1
- package/lib/handlers/Chrome74.js +45 -29
- package/lib/handlers/Edge11.d.ts +1 -1
- package/lib/handlers/Edge11.d.ts.map +1 -1
- package/lib/handlers/Edge11.js +28 -20
- package/lib/handlers/FakeHandler.d.ts +1 -1
- package/lib/handlers/FakeHandler.d.ts.map +1 -1
- package/lib/handlers/FakeHandler.js +13 -10
- package/lib/handlers/Firefox60.d.ts +1 -1
- package/lib/handlers/Firefox60.d.ts.map +1 -1
- package/lib/handlers/Firefox60.js +45 -30
- package/lib/handlers/HandlerInterface.d.ts +1 -1
- package/lib/handlers/HandlerInterface.d.ts.map +1 -1
- package/lib/handlers/ReactNative.d.ts +1 -1
- package/lib/handlers/ReactNative.d.ts.map +1 -1
- package/lib/handlers/ReactNative.js +48 -34
- package/lib/handlers/Safari11.d.ts +1 -1
- package/lib/handlers/Safari11.d.ts.map +1 -1
- package/lib/handlers/Safari11.js +43 -30
- package/lib/handlers/Safari12.d.ts +1 -1
- package/lib/handlers/Safari12.d.ts.map +1 -1
- package/lib/handlers/Safari12.js +42 -29
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -1
- package/lib/ortc.js +0 -2
- package/package.json +10 -10
- package/src/Transport.ts +162 -58
- package/src/handlers/Chrome55.ts +52 -31
- package/src/handlers/Chrome67.ts +54 -33
- package/src/handlers/Chrome70.ts +52 -32
- package/src/handlers/Chrome74.ts +56 -32
- package/src/handlers/Edge11.ts +39 -25
- package/src/handlers/FakeHandler.ts +18 -10
- package/src/handlers/Firefox60.ts +54 -33
- package/src/handlers/HandlerInterface.ts +2 -2
- package/src/handlers/ReactNative.ts +59 -38
- package/src/handlers/Safari11.ts +54 -33
- package/src/handlers/Safari12.ts +52 -32
- package/src/ortc.ts +0 -2
package/lib/handlers/Safari11.js
CHANGED
|
@@ -399,32 +399,39 @@ class Safari11 extends HandlerInterface_1.HandlerInterface {
|
|
|
399
399
|
};
|
|
400
400
|
return { dataChannel, sctpStreamParameters };
|
|
401
401
|
}
|
|
402
|
-
async receive(
|
|
402
|
+
async receive(optionsList) {
|
|
403
403
|
var _a;
|
|
404
404
|
this._assertRecvDirection();
|
|
405
|
-
|
|
406
|
-
const
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
mid
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
405
|
+
const results = [];
|
|
406
|
+
for (const options of optionsList) {
|
|
407
|
+
const { trackId, kind, rtpParameters } = options;
|
|
408
|
+
logger.debug('receive() [trackId:%s, kind:%s]', trackId, kind);
|
|
409
|
+
const mid = kind;
|
|
410
|
+
this._remoteSdp.receive({
|
|
411
|
+
mid,
|
|
412
|
+
kind,
|
|
413
|
+
offerRtpParameters: rtpParameters,
|
|
414
|
+
streamId: rtpParameters.rtcp.cname,
|
|
415
|
+
trackId
|
|
416
|
+
});
|
|
417
|
+
}
|
|
415
418
|
const offer = { type: 'offer', sdp: this._remoteSdp.getSdp() };
|
|
416
419
|
logger.debug('receive() | calling pc.setRemoteDescription() [offer:%o]', offer);
|
|
417
420
|
await this._pc.setRemoteDescription(offer);
|
|
418
421
|
let answer = await this._pc.createAnswer();
|
|
419
422
|
const localSdpObject = sdpTransform.parse(answer.sdp);
|
|
420
|
-
const
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
423
|
+
for (const options of optionsList) {
|
|
424
|
+
const { kind, rtpParameters } = options;
|
|
425
|
+
const mid = kind;
|
|
426
|
+
const answerMediaObject = localSdpObject.media
|
|
427
|
+
.find((m) => String(m.mid) === mid);
|
|
428
|
+
// May need to modify codec parameters in the answer based on codec
|
|
429
|
+
// parameters in the offer.
|
|
430
|
+
sdpCommonUtils.applyCodecParameters({
|
|
431
|
+
offerRtpParameters: rtpParameters,
|
|
432
|
+
answerMediaObject
|
|
433
|
+
});
|
|
434
|
+
}
|
|
428
435
|
answer = { type: 'answer', sdp: sdpTransform.write(localSdpObject) };
|
|
429
436
|
if (!this._transportReady) {
|
|
430
437
|
await this._setupTransport({
|
|
@@ -434,17 +441,23 @@ class Safari11 extends HandlerInterface_1.HandlerInterface {
|
|
|
434
441
|
}
|
|
435
442
|
logger.debug('receive() | calling pc.setLocalDescription() [answer:%o]', answer);
|
|
436
443
|
await this._pc.setLocalDescription(answer);
|
|
437
|
-
const
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
rtpReceiver
|
|
447
|
-
|
|
444
|
+
for (const options of optionsList) {
|
|
445
|
+
const { kind, trackId, rtpParameters } = options;
|
|
446
|
+
const mid = kind;
|
|
447
|
+
const localId = trackId;
|
|
448
|
+
const rtpReceiver = this._pc.getReceivers()
|
|
449
|
+
.find((r) => r.track && r.track.id === localId);
|
|
450
|
+
if (!rtpReceiver)
|
|
451
|
+
throw new Error('new RTCRtpReceiver not');
|
|
452
|
+
// Insert into the map.
|
|
453
|
+
this._mapRecvLocalIdInfo.set(localId, { mid, rtpParameters, rtpReceiver });
|
|
454
|
+
results.push({
|
|
455
|
+
localId,
|
|
456
|
+
track: rtpReceiver.track,
|
|
457
|
+
rtpReceiver
|
|
458
|
+
});
|
|
459
|
+
}
|
|
460
|
+
return results;
|
|
448
461
|
}
|
|
449
462
|
async stopReceiving(localId) {
|
|
450
463
|
this._assertRecvDirection();
|
|
@@ -34,7 +34,7 @@ export declare class Safari12 extends HandlerInterface {
|
|
|
34
34
|
setRtpEncodingParameters(localId: string, params: any): Promise<void>;
|
|
35
35
|
getSenderStats(localId: string): Promise<RTCStatsReport>;
|
|
36
36
|
sendDataChannel({ ordered, maxPacketLifeTime, maxRetransmits, label, protocol }: HandlerSendDataChannelOptions): Promise<HandlerSendDataChannelResult>;
|
|
37
|
-
receive(
|
|
37
|
+
receive(optionsList: HandlerReceiveOptions[]): Promise<HandlerReceiveResult[]>;
|
|
38
38
|
stopReceiving(localId: string): Promise<void>;
|
|
39
39
|
pauseReceiving(localId: string): Promise<void>;
|
|
40
40
|
resumeReceiving(localId: string): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Safari12.d.ts","sourceRoot":"","sources":["../../src/handlers/Safari12.ts"],"names":[],"mappings":"AAMA,OAAO,EACN,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,EACpB,6BAA6B,EAC7B,4BAA4B,EAC5B,gCAAgC,EAChC,+BAA+B,EAC/B,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,aAAa,EAAY,MAAM,cAAc,CAAC;AACvD,OAAO,EAAE,eAAe,EAAiB,MAAM,kBAAkB,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAwB,MAAM,mBAAmB,CAAC;AAM3E,qBAAa,QAAS,SAAQ,gBAAgB;IAG7C,OAAO,CAAC,UAAU,CAAC,CAAkB;IAErC,OAAO,CAAC,UAAU,CAAC,CAAY;IAE/B,OAAO,CAAC,2BAA2B,CAAC,CAAmC;IAGvE,OAAO,CAAC,iCAAiC,CAAC,CAAmC;IAG7E,OAAO,CAAC,oBAAoB,CAAC,CAAW;IAExC,OAAO,CAAC,GAAG,CAAM;IAEjB,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CACxB;IAEX,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IAEjD,OAAO,CAAC,2BAA2B,CAAS;IAE5C,OAAO,CAAC,qBAAqB,CAAK;IAElC,OAAO,CAAC,eAAe,CAAS;IAEhC;;OAEG;IACH,MAAM,CAAC,aAAa,IAAI,cAAc;;IAUtC,IAAI,IAAI,IAAI,MAAM,CAGjB;IAED,KAAK,IAAI,IAAI;IAYP,wBAAwB,IAAI,OAAO,CAAC,eAAe,CAAC;IAqCpD,yBAAyB,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAS5D,GAAG,CACF,EACC,SAAS,EACT,aAAa,EACb,aAAa,EACb,cAAc,EACd,cAAc,EACd,UAAU,EACV,kBAAkB,EAClB,kBAAkB,EAClB,sBAAsB,EACtB,uBAAuB,EACvB,EAAE,iBAAiB,GAClB,IAAI;IAoED,gBAAgB,CAAC,UAAU,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAW3D,UAAU,CAAC,aAAa,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAgDvD,iBAAiB,IAAI,OAAO,CAAC,cAAc,CAAC;IAK5C,IAAI,CACT,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,KAAK,EAAE,EAAE,kBAAkB,GAC3D,OAAO,CAAC,iBAAiB,CAAC;IAgIvB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkC3C,YAAY,CACjB,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,GAAG,IAAI,GAC7C,OAAO,CAAC,IAAI,CAAC;IAsBV,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BxE,wBAAwB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IAuBrE,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAYxD,eAAe,CACpB,EACC,OAAO,EACP,iBAAiB,EACjB,cAAc,EACd,KAAK,EACL,QAAQ,EACR,EAAE,6BAA6B,GAC9B,OAAO,CAAC,4BAA4B,CAAC;IAsElC,OAAO,CACZ,
|
|
1
|
+
{"version":3,"file":"Safari12.d.ts","sourceRoot":"","sources":["../../src/handlers/Safari12.ts"],"names":[],"mappings":"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"}
|
package/lib/handlers/Safari12.js
CHANGED
|
@@ -372,31 +372,39 @@ class Safari12 extends HandlerInterface_1.HandlerInterface {
|
|
|
372
372
|
};
|
|
373
373
|
return { dataChannel, sctpStreamParameters };
|
|
374
374
|
}
|
|
375
|
-
async receive(
|
|
375
|
+
async receive(optionsList) {
|
|
376
376
|
var _a;
|
|
377
377
|
this._assertRecvDirection();
|
|
378
|
-
|
|
379
|
-
const
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
378
|
+
const results = [];
|
|
379
|
+
for (const options of optionsList) {
|
|
380
|
+
const { trackId, kind, rtpParameters } = options;
|
|
381
|
+
logger.debug('receive() [trackId:%s, kind:%s]', trackId, kind);
|
|
382
|
+
const localId = rtpParameters.mid || String(this._mapMidTransceiver.size);
|
|
383
|
+
this._remoteSdp.receive({
|
|
384
|
+
mid: localId,
|
|
385
|
+
kind,
|
|
386
|
+
offerRtpParameters: rtpParameters,
|
|
387
|
+
streamId: rtpParameters.rtcp.cname,
|
|
388
|
+
trackId
|
|
389
|
+
});
|
|
390
|
+
}
|
|
387
391
|
const offer = { type: 'offer', sdp: this._remoteSdp.getSdp() };
|
|
388
392
|
logger.debug('receive() | calling pc.setRemoteDescription() [offer:%o]', offer);
|
|
389
393
|
await this._pc.setRemoteDescription(offer);
|
|
390
394
|
let answer = await this._pc.createAnswer();
|
|
391
395
|
const localSdpObject = sdpTransform.parse(answer.sdp);
|
|
392
|
-
const
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
396
|
+
for (const options of optionsList) {
|
|
397
|
+
const { rtpParameters } = options;
|
|
398
|
+
const localId = rtpParameters.mid || String(this._mapMidTransceiver.size);
|
|
399
|
+
const answerMediaObject = localSdpObject.media
|
|
400
|
+
.find((m) => String(m.mid) === localId);
|
|
401
|
+
// May need to modify codec parameters in the answer based on codec
|
|
402
|
+
// parameters in the offer.
|
|
403
|
+
sdpCommonUtils.applyCodecParameters({
|
|
404
|
+
offerRtpParameters: rtpParameters,
|
|
405
|
+
answerMediaObject
|
|
406
|
+
});
|
|
407
|
+
}
|
|
400
408
|
answer = { type: 'answer', sdp: sdpTransform.write(localSdpObject) };
|
|
401
409
|
if (!this._transportReady) {
|
|
402
410
|
await this._setupTransport({
|
|
@@ -406,17 +414,22 @@ class Safari12 extends HandlerInterface_1.HandlerInterface {
|
|
|
406
414
|
}
|
|
407
415
|
logger.debug('receive() | calling pc.setLocalDescription() [answer:%o]', answer);
|
|
408
416
|
await this._pc.setLocalDescription(answer);
|
|
409
|
-
const
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
417
|
+
for (const options of optionsList) {
|
|
418
|
+
const { rtpParameters } = options;
|
|
419
|
+
const localId = rtpParameters.mid || String(this._mapMidTransceiver.size);
|
|
420
|
+
const transceiver = this._pc.getTransceivers()
|
|
421
|
+
.find((t) => t.mid === localId);
|
|
422
|
+
if (!transceiver)
|
|
423
|
+
throw new Error('new RTCRtpTransceiver not found');
|
|
424
|
+
// Store in the map.
|
|
425
|
+
this._mapMidTransceiver.set(localId, transceiver);
|
|
426
|
+
results.push({
|
|
427
|
+
localId,
|
|
428
|
+
track: transceiver.receiver.track,
|
|
429
|
+
rtpReceiver: transceiver.receiver
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
return results;
|
|
420
433
|
}
|
|
421
434
|
async stopReceiving(localId) {
|
|
422
435
|
this._assertRecvDirection();
|
package/lib/index.d.ts
CHANGED
package/lib/index.js
CHANGED
package/lib/ortc.js
CHANGED
|
@@ -780,7 +780,6 @@ function matchCodecs(aCodec, bCodec, { strict = false, modify = false } = {}) {
|
|
|
780
780
|
switch (aMimeType) {
|
|
781
781
|
case 'video/h264':
|
|
782
782
|
{
|
|
783
|
-
// If strict matching check profile-level-id.
|
|
784
783
|
if (strict) {
|
|
785
784
|
const aPacketizationMode = aCodec.parameters['packetization-mode'] || 0;
|
|
786
785
|
const bPacketizationMode = bCodec.parameters['packetization-mode'] || 0;
|
|
@@ -811,7 +810,6 @@ function matchCodecs(aCodec, bCodec, { strict = false, modify = false } = {}) {
|
|
|
811
810
|
}
|
|
812
811
|
case 'video/vp9':
|
|
813
812
|
{
|
|
814
|
-
// If strict matching check profile-id.
|
|
815
813
|
if (strict) {
|
|
816
814
|
const aProfileId = aCodec.parameters['profile-id'] || 0;
|
|
817
815
|
const bProfileId = bCodec.parameters['profile-id'] || 0;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mediasoup-client",
|
|
3
|
-
"version": "3.6.
|
|
3
|
+
"version": "3.6.48",
|
|
4
4
|
"description": "mediasoup client side JavaScript library",
|
|
5
5
|
"contributors": [
|
|
6
6
|
"Iñaki Baz Castillo <ibc@aliax.net> (https://inakibaz.me)",
|
|
@@ -39,25 +39,25 @@
|
|
|
39
39
|
"@types/events": "^3.0.0",
|
|
40
40
|
"awaitqueue": "^2.3.3",
|
|
41
41
|
"bowser": "^2.11.0",
|
|
42
|
-
"debug": "^4.3.
|
|
42
|
+
"debug": "^4.3.3",
|
|
43
43
|
"events": "^3.3.0",
|
|
44
44
|
"fake-mediastreamtrack": "^1.1.6",
|
|
45
45
|
"h264-profile-level-id": "^1.0.1",
|
|
46
46
|
"sdp-transform": "^2.14.1",
|
|
47
|
-
"supports-color": "^9.1
|
|
47
|
+
"supports-color": "^9.2.1"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"@types/sdp-transform": "^2.4.5",
|
|
51
51
|
"@types/uuid": "^3.4.9",
|
|
52
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
|
53
|
-
"@typescript-eslint/parser": "^5.
|
|
54
|
-
"eslint": "^8.
|
|
55
|
-
"eslint-plugin-jest": "^25.3.
|
|
56
|
-
"jest": "^27.
|
|
52
|
+
"@typescript-eslint/eslint-plugin": "^5.9.1",
|
|
53
|
+
"@typescript-eslint/parser": "^5.9.1",
|
|
54
|
+
"eslint": "^8.6.0",
|
|
55
|
+
"eslint-plugin-jest": "^25.3.4",
|
|
56
|
+
"jest": "^27.4.7",
|
|
57
57
|
"jest-tobetype": "^1.2.3",
|
|
58
58
|
"open-cli": "^7.0.1",
|
|
59
|
-
"tsc-watch": "^4.
|
|
60
|
-
"typescript": "^4.5.
|
|
59
|
+
"tsc-watch": "^4.6.0",
|
|
60
|
+
"typescript": "^4.5.4",
|
|
61
61
|
"uuid": "^3.4.0"
|
|
62
62
|
}
|
|
63
63
|
}
|
package/src/Transport.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { EnhancedEventEmitter } from './EnhancedEventEmitter';
|
|
|
4
4
|
import { UnsupportedError, InvalidStateError } from './errors';
|
|
5
5
|
import * as utils from './utils';
|
|
6
6
|
import * as ortc from './ortc';
|
|
7
|
-
import { HandlerFactory, HandlerInterface } from './handlers/HandlerInterface';
|
|
7
|
+
import { HandlerFactory, HandlerInterface, HandlerReceiveOptions } from './handlers/HandlerInterface';
|
|
8
8
|
import { Producer, ProducerOptions } from './Producer';
|
|
9
9
|
import { Consumer, ConsumerOptions } from './Consumer';
|
|
10
10
|
import { DataProducer, DataProducerOptions } from './DataProducer';
|
|
@@ -19,6 +19,24 @@ interface InternalTransportOptions extends TransportOptions
|
|
|
19
19
|
canProduceByKind: CanProduceByKind;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
class ConsumerCreationTask
|
|
23
|
+
{
|
|
24
|
+
consumerOptions: ConsumerOptions;
|
|
25
|
+
promise: Promise<Consumer>;
|
|
26
|
+
resolve?: (consumer: Consumer) => void;
|
|
27
|
+
reject?: (error: Error) => void;
|
|
28
|
+
|
|
29
|
+
constructor(consumerOptions: ConsumerOptions)
|
|
30
|
+
{
|
|
31
|
+
this.consumerOptions = consumerOptions;
|
|
32
|
+
this.promise = new Promise((resolve, reject) =>
|
|
33
|
+
{
|
|
34
|
+
this.resolve = resolve;
|
|
35
|
+
this.reject = reject;
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
22
40
|
export type TransportOptions =
|
|
23
41
|
{
|
|
24
42
|
id: string;
|
|
@@ -165,6 +183,10 @@ export class Transport extends EnhancedEventEmitter
|
|
|
165
183
|
private _probatorConsumerCreated = false;
|
|
166
184
|
// AwaitQueue instance to make async tasks happen sequentially.
|
|
167
185
|
private readonly _awaitQueue = new AwaitQueue({ ClosedErrorClass: InvalidStateError });
|
|
186
|
+
// Consumer creation tasks awaiting to be processed.
|
|
187
|
+
private _pendingConsumerTasks: ConsumerCreationTask[] = [];
|
|
188
|
+
// Consumer creation in progress flag.
|
|
189
|
+
private _consumerCreationInProgress = false;
|
|
168
190
|
// Observer instance.
|
|
169
191
|
protected readonly _observer = new EnhancedEventEmitter();
|
|
170
192
|
|
|
@@ -583,68 +605,33 @@ export class Transport extends EnhancedEventEmitter
|
|
|
583
605
|
else if (appData && typeof appData !== 'object')
|
|
584
606
|
throw new TypeError('if given, appData must be an object');
|
|
585
607
|
|
|
586
|
-
//
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
{
|
|
590
|
-
// Ensure the device can consume it.
|
|
591
|
-
const canConsume = ortc.canReceive(
|
|
592
|
-
rtpParameters, this._extendedRtpCapabilities);
|
|
593
|
-
|
|
594
|
-
if (!canConsume)
|
|
595
|
-
throw new UnsupportedError('cannot consume this Producer');
|
|
596
|
-
|
|
597
|
-
const { localId, rtpReceiver, track } =
|
|
598
|
-
await this._handler.receive({ trackId: id, kind, rtpParameters });
|
|
599
|
-
|
|
600
|
-
const consumer = new Consumer(
|
|
601
|
-
{
|
|
602
|
-
id,
|
|
603
|
-
localId,
|
|
604
|
-
producerId,
|
|
605
|
-
rtpReceiver,
|
|
606
|
-
track,
|
|
607
|
-
rtpParameters,
|
|
608
|
-
appData
|
|
609
|
-
});
|
|
610
|
-
|
|
611
|
-
this._consumers.set(consumer.id, consumer);
|
|
612
|
-
this._handleConsumer(consumer);
|
|
613
|
-
|
|
614
|
-
// If this is the first video Consumer and the Consumer for RTP probation
|
|
615
|
-
// has not yet been created, create it now.
|
|
616
|
-
if (!this._probatorConsumerCreated && kind === 'video')
|
|
617
|
-
{
|
|
618
|
-
try
|
|
619
|
-
{
|
|
620
|
-
const probatorRtpParameters =
|
|
621
|
-
ortc.generateProbatorRtpParameters(consumer.rtpParameters);
|
|
608
|
+
// Ensure the device can consume it.
|
|
609
|
+
const canConsume = ortc.canReceive(
|
|
610
|
+
rtpParameters, this._extendedRtpCapabilities);
|
|
622
611
|
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
trackId : 'probator',
|
|
626
|
-
kind : 'video',
|
|
627
|
-
rtpParameters : probatorRtpParameters
|
|
628
|
-
});
|
|
612
|
+
if (!canConsume)
|
|
613
|
+
throw new UnsupportedError('cannot consume this Producer');
|
|
629
614
|
|
|
630
|
-
|
|
615
|
+
const consumerCreationTask = new ConsumerCreationTask(
|
|
616
|
+
{
|
|
617
|
+
id,
|
|
618
|
+
producerId,
|
|
619
|
+
kind,
|
|
620
|
+
rtpParameters,
|
|
621
|
+
appData
|
|
622
|
+
}
|
|
623
|
+
);
|
|
631
624
|
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
catch (error)
|
|
635
|
-
{
|
|
636
|
-
logger.error(
|
|
637
|
-
'consume() | failed to create Consumer for RTP probation:%o',
|
|
638
|
-
error);
|
|
639
|
-
}
|
|
640
|
-
}
|
|
625
|
+
// Store the Consumer creation task.
|
|
626
|
+
this._pendingConsumerTasks.push(consumerCreationTask);
|
|
641
627
|
|
|
642
|
-
|
|
643
|
-
|
|
628
|
+
// There is no Consumer creation in progress, create it now.
|
|
629
|
+
if (this._consumerCreationInProgress === false)
|
|
630
|
+
{
|
|
631
|
+
this._createPendingConsumers();
|
|
632
|
+
}
|
|
644
633
|
|
|
645
|
-
|
|
646
|
-
},
|
|
647
|
-
'transport.consume()');
|
|
634
|
+
return consumerCreationTask.promise;
|
|
648
635
|
}
|
|
649
636
|
|
|
650
637
|
/**
|
|
@@ -788,6 +775,123 @@ export class Transport extends EnhancedEventEmitter
|
|
|
788
775
|
'transport.consumeData()');
|
|
789
776
|
}
|
|
790
777
|
|
|
778
|
+
// This method is guaranteed to never throw.
|
|
779
|
+
async _createPendingConsumers(): Promise<void>
|
|
780
|
+
{
|
|
781
|
+
this._awaitQueue.push(
|
|
782
|
+
async () =>
|
|
783
|
+
{
|
|
784
|
+
this._consumerCreationInProgress = true;
|
|
785
|
+
|
|
786
|
+
const pendingConsumerTasks = [ ...this._pendingConsumerTasks ];
|
|
787
|
+
|
|
788
|
+
// Clear pending Consumer tasks.
|
|
789
|
+
this._pendingConsumerTasks = [];
|
|
790
|
+
|
|
791
|
+
// Video Consumer in order to create the probator.
|
|
792
|
+
let videoConsumerForProbator: Consumer | undefined = undefined;
|
|
793
|
+
|
|
794
|
+
// Fill options list.
|
|
795
|
+
const optionsList: HandlerReceiveOptions[] = [];
|
|
796
|
+
|
|
797
|
+
for (const task of pendingConsumerTasks)
|
|
798
|
+
{
|
|
799
|
+
const { id, kind, rtpParameters } = task.consumerOptions;
|
|
800
|
+
|
|
801
|
+
optionsList.push({
|
|
802
|
+
trackId : id!,
|
|
803
|
+
kind : kind as 'audio' | 'video',
|
|
804
|
+
rtpParameters
|
|
805
|
+
});
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
try
|
|
809
|
+
{
|
|
810
|
+
const results = await this._handler.receive(optionsList);
|
|
811
|
+
|
|
812
|
+
for (let idx=0; idx < results.length; idx++)
|
|
813
|
+
{
|
|
814
|
+
const task = pendingConsumerTasks[idx];
|
|
815
|
+
const result = results[idx];
|
|
816
|
+
const { id, producerId, kind, rtpParameters, appData } = task.consumerOptions;
|
|
817
|
+
const { localId, rtpReceiver, track } = result;
|
|
818
|
+
const consumer = new Consumer(
|
|
819
|
+
{
|
|
820
|
+
id : id!,
|
|
821
|
+
localId,
|
|
822
|
+
producerId : producerId!,
|
|
823
|
+
rtpReceiver,
|
|
824
|
+
track,
|
|
825
|
+
rtpParameters,
|
|
826
|
+
appData
|
|
827
|
+
});
|
|
828
|
+
|
|
829
|
+
this._consumers.set(consumer.id, consumer);
|
|
830
|
+
this._handleConsumer(consumer);
|
|
831
|
+
|
|
832
|
+
// If this is the first video Consumer and the Consumer for RTP probation
|
|
833
|
+
// has not yet been created, it's time to create it.
|
|
834
|
+
if (!this._probatorConsumerCreated && !videoConsumerForProbator && kind === 'video')
|
|
835
|
+
{
|
|
836
|
+
videoConsumerForProbator = consumer;
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
// Emit observer event.
|
|
840
|
+
this._observer.safeEmit('newconsumer', consumer);
|
|
841
|
+
|
|
842
|
+
task.resolve!(consumer);
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
catch (error)
|
|
846
|
+
{
|
|
847
|
+
for (const task of pendingConsumerTasks)
|
|
848
|
+
{
|
|
849
|
+
task.reject!(error as Error);
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
// If RTP probation must be handled, do it now.
|
|
854
|
+
if (videoConsumerForProbator)
|
|
855
|
+
{
|
|
856
|
+
try
|
|
857
|
+
{
|
|
858
|
+
const probatorRtpParameters =
|
|
859
|
+
ortc.generateProbatorRtpParameters(videoConsumerForProbator!.rtpParameters);
|
|
860
|
+
|
|
861
|
+
await this._handler.receive(
|
|
862
|
+
[ {
|
|
863
|
+
trackId : 'probator',
|
|
864
|
+
kind : 'video',
|
|
865
|
+
rtpParameters : probatorRtpParameters
|
|
866
|
+
} ]);
|
|
867
|
+
|
|
868
|
+
logger.debug('_createPendingConsumers() | Consumer for RTP probation created');
|
|
869
|
+
|
|
870
|
+
this._probatorConsumerCreated = true;
|
|
871
|
+
}
|
|
872
|
+
catch (error)
|
|
873
|
+
{
|
|
874
|
+
logger.error(
|
|
875
|
+
'_createPendingConsumers() | failed to create Consumer for RTP probation:%o',
|
|
876
|
+
error);
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
this._consumerCreationInProgress = false;
|
|
881
|
+
},
|
|
882
|
+
'transport._createPendingConsumers()')
|
|
883
|
+
.then(() =>
|
|
884
|
+
{
|
|
885
|
+
// There are pending Consumer tasks, enqueue their creation.
|
|
886
|
+
if (this._pendingConsumerTasks.length > 0)
|
|
887
|
+
{
|
|
888
|
+
this._createPendingConsumers();
|
|
889
|
+
}
|
|
890
|
+
})
|
|
891
|
+
// NOTE: We only get here when the await queue is closed.
|
|
892
|
+
.catch(() => {});
|
|
893
|
+
}
|
|
894
|
+
|
|
791
895
|
_handleHandler(): void
|
|
792
896
|
{
|
|
793
897
|
const handler = this._handler;
|
package/src/handlers/Chrome55.ts
CHANGED
|
@@ -580,25 +580,31 @@ export class Chrome55 extends HandlerInterface
|
|
|
580
580
|
}
|
|
581
581
|
|
|
582
582
|
async receive(
|
|
583
|
-
|
|
584
|
-
): Promise<HandlerReceiveResult>
|
|
583
|
+
optionsList: HandlerReceiveOptions[]
|
|
584
|
+
) : Promise<HandlerReceiveResult[]>
|
|
585
585
|
{
|
|
586
586
|
this._assertRecvDirection();
|
|
587
587
|
|
|
588
|
-
|
|
588
|
+
const results: HandlerReceiveResult[] = [];
|
|
589
589
|
|
|
590
|
-
const
|
|
591
|
-
|
|
592
|
-
|
|
590
|
+
for (const options of optionsList)
|
|
591
|
+
{
|
|
592
|
+
const { trackId, kind, rtpParameters } = options;
|
|
593
593
|
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
594
|
+
logger.debug('receive() [trackId:%s, kind:%s]', trackId, kind);
|
|
595
|
+
|
|
596
|
+
const mid = kind;
|
|
597
|
+
const streamId = rtpParameters.rtcp!.cname!;
|
|
598
|
+
|
|
599
|
+
this._remoteSdp!.receive(
|
|
600
|
+
{
|
|
601
|
+
mid,
|
|
602
|
+
kind,
|
|
603
|
+
offerRtpParameters : rtpParameters,
|
|
604
|
+
streamId,
|
|
605
|
+
trackId
|
|
606
|
+
});
|
|
607
|
+
}
|
|
602
608
|
|
|
603
609
|
const offer = { type: 'offer', sdp: this._remoteSdp!.getSdp() };
|
|
604
610
|
|
|
@@ -610,16 +616,22 @@ export class Chrome55 extends HandlerInterface
|
|
|
610
616
|
|
|
611
617
|
let answer = await this._pc.createAnswer();
|
|
612
618
|
const localSdpObject = sdpTransform.parse(answer.sdp);
|
|
613
|
-
const answerMediaObject = localSdpObject.media
|
|
614
|
-
.find((m: any) => String(m.mid) === mid);
|
|
615
619
|
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
620
|
+
for (const options of optionsList)
|
|
621
|
+
{
|
|
622
|
+
const { kind, rtpParameters } = options;
|
|
623
|
+
const mid = kind;
|
|
624
|
+
const answerMediaObject = localSdpObject.media
|
|
625
|
+
.find((m: any) => String(m.mid) === mid);
|
|
626
|
+
|
|
627
|
+
// May need to modify codec parameters in the answer based on codec
|
|
628
|
+
// parameters in the offer.
|
|
629
|
+
sdpCommonUtils.applyCodecParameters(
|
|
630
|
+
{
|
|
631
|
+
offerRtpParameters : rtpParameters,
|
|
632
|
+
answerMediaObject
|
|
633
|
+
});
|
|
634
|
+
}
|
|
623
635
|
|
|
624
636
|
answer = { type: 'answer', sdp: sdpTransform.write(localSdpObject) };
|
|
625
637
|
|
|
@@ -638,17 +650,26 @@ export class Chrome55 extends HandlerInterface
|
|
|
638
650
|
|
|
639
651
|
await this._pc.setLocalDescription(answer);
|
|
640
652
|
|
|
641
|
-
const
|
|
642
|
-
|
|
643
|
-
|
|
653
|
+
for (const options of optionsList)
|
|
654
|
+
{
|
|
655
|
+
const { kind, trackId, rtpParameters } = options;
|
|
656
|
+
const mid = kind;
|
|
657
|
+
const localId = trackId;
|
|
658
|
+
const streamId = rtpParameters.rtcp!.cname!;
|
|
659
|
+
const stream = this._pc.getRemoteStreams()
|
|
660
|
+
.find((s: any) => s.id === streamId);
|
|
661
|
+
const track = stream.getTrackById(localId);
|
|
644
662
|
|
|
645
|
-
|
|
646
|
-
|
|
663
|
+
if (!track)
|
|
664
|
+
throw new Error('remote track not found');
|
|
647
665
|
|
|
648
|
-
|
|
649
|
-
|
|
666
|
+
// Insert into the map.
|
|
667
|
+
this._mapRecvLocalIdInfo.set(localId, { mid, rtpParameters });
|
|
668
|
+
|
|
669
|
+
results.push({ localId, track });
|
|
670
|
+
}
|
|
650
671
|
|
|
651
|
-
return
|
|
672
|
+
return results;
|
|
652
673
|
}
|
|
653
674
|
|
|
654
675
|
async stopReceiving(localId: string): Promise<void>
|