mediasoup-client 3.6.43 → 3.6.47

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.
Files changed (55) hide show
  1. package/lib/DataConsumer.d.ts +2 -2
  2. package/lib/DataConsumer.d.ts.map +1 -1
  3. package/lib/Device.d.ts.map +1 -1
  4. package/lib/Device.js +7 -3
  5. package/lib/Logger.js +6 -6
  6. package/lib/Transport.d.ts +3 -3
  7. package/lib/Transport.js +1 -1
  8. package/lib/handlers/Chrome55.d.ts +1 -0
  9. package/lib/handlers/Chrome55.d.ts.map +1 -1
  10. package/lib/handlers/Chrome55.js +40 -9
  11. package/lib/handlers/Chrome67.d.ts +1 -0
  12. package/lib/handlers/Chrome67.d.ts.map +1 -1
  13. package/lib/handlers/Chrome67.js +41 -10
  14. package/lib/handlers/Chrome70.d.ts +1 -0
  15. package/lib/handlers/Chrome70.d.ts.map +1 -1
  16. package/lib/handlers/Chrome70.js +42 -11
  17. package/lib/handlers/Chrome74.d.ts +1 -0
  18. package/lib/handlers/Chrome74.d.ts.map +1 -1
  19. package/lib/handlers/Chrome74.js +42 -11
  20. package/lib/handlers/Edge11.d.ts.map +1 -1
  21. package/lib/handlers/Edge11.js +3 -2
  22. package/lib/handlers/FakeHandler.js +1 -1
  23. package/lib/handlers/Firefox60.js +10 -4
  24. package/lib/handlers/ReactNative.d.ts +1 -0
  25. package/lib/handlers/ReactNative.d.ts.map +1 -1
  26. package/lib/handlers/ReactNative.js +40 -9
  27. package/lib/handlers/Safari11.d.ts +1 -0
  28. package/lib/handlers/Safari11.d.ts.map +1 -1
  29. package/lib/handlers/Safari11.js +40 -10
  30. package/lib/handlers/Safari12.d.ts +1 -0
  31. package/lib/handlers/Safari12.d.ts.map +1 -1
  32. package/lib/handlers/Safari12.js +40 -10
  33. package/lib/handlers/ortc/edgeUtils.js +1 -1
  34. package/lib/handlers/sdp/MediaSection.js +1 -1
  35. package/lib/handlers/sdp/RemoteSdp.js +1 -1
  36. package/lib/handlers/sdp/commonUtils.js +1 -1
  37. package/lib/index.d.ts +1 -1
  38. package/lib/index.js +3 -3
  39. package/lib/ortc.js +5 -5
  40. package/lib/types.js +1 -1
  41. package/package.json +9 -9
  42. package/src/DataConsumer.ts +2 -2
  43. package/src/Device.ts +7 -2
  44. package/src/Transport.ts +3 -3
  45. package/src/handlers/Chrome55.ts +37 -5
  46. package/src/handlers/Chrome67.ts +37 -5
  47. package/src/handlers/Chrome70.ts +36 -4
  48. package/src/handlers/Chrome74.ts +36 -4
  49. package/src/handlers/Edge11.ts +3 -1
  50. package/src/handlers/Firefox60.ts +1 -1
  51. package/src/handlers/ReactNative.ts +37 -5
  52. package/src/handlers/Safari11.ts +37 -5
  53. package/src/handlers/Safari12.ts +36 -4
  54. package/src/ortc.ts +6 -6
  55. package/tsconfig.json +1 -1
@@ -14,7 +14,7 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
14
14
  var __importStar = (this && this.__importStar) || function (mod) {
15
15
  if (mod && mod.__esModule) return mod;
16
16
  var result = {};
17
- if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
18
  __setModuleDefault(result, mod);
19
19
  return result;
20
20
  };
@@ -116,7 +116,18 @@ class Safari12 extends HandlerInterface_1.HandlerInterface {
116
116
  audio: ortc.getSendingRemoteRtpParameters('audio', extendedRtpCapabilities),
117
117
  video: ortc.getSendingRemoteRtpParameters('video', extendedRtpCapabilities)
118
118
  };
119
- this._pc = new RTCPeerConnection(Object.assign({ iceServers: iceServers || [], iceTransportPolicy: iceTransportPolicy || 'all', bundlePolicy: 'max-bundle', rtcpMuxPolicy: 'require' }, additionalSettings), proprietaryConstraints);
119
+ if (dtlsParameters.role && dtlsParameters.role !== 'auto') {
120
+ this._forcedLocalDtlsRole = dtlsParameters.role === 'server'
121
+ ? 'client'
122
+ : 'server';
123
+ }
124
+ this._pc = new RTCPeerConnection({
125
+ iceServers: iceServers || [],
126
+ iceTransportPolicy: iceTransportPolicy || 'all',
127
+ bundlePolicy: 'max-bundle',
128
+ rtcpMuxPolicy: 'require',
129
+ ...additionalSettings
130
+ }, proprietaryConstraints);
120
131
  // Handle RTCPeerConnection connection status.
121
132
  this._pc.addEventListener('iceconnectionstatechange', () => {
122
133
  switch (this._pc.iceConnectionState) {
@@ -172,6 +183,7 @@ class Safari12 extends HandlerInterface_1.HandlerInterface {
172
183
  return this._pc.getStats();
173
184
  }
174
185
  async send({ track, encodings, codecOptions, codec }) {
186
+ var _a;
175
187
  this._assertSendDirection();
176
188
  logger.debug('send() [kind:%s, track.id:%s]', track.kind, track.id);
177
189
  const sendingRtpParameters = utils.clone(this._sendingRtpParametersByKind[track.kind], {});
@@ -187,8 +199,12 @@ class Safari12 extends HandlerInterface_1.HandlerInterface {
187
199
  let offer = await this._pc.createOffer();
188
200
  let localSdpObject = sdpTransform.parse(offer.sdp);
189
201
  let offerMediaObject;
190
- if (!this._transportReady)
191
- await this._setupTransport({ localDtlsRole: 'server', localSdpObject });
202
+ if (!this._transportReady) {
203
+ await this._setupTransport({
204
+ localDtlsRole: (_a = this._forcedLocalDtlsRole) !== null && _a !== void 0 ? _a : 'client',
205
+ localSdpObject
206
+ });
207
+ }
192
208
  if (encodings && encodings.length > 1) {
193
209
  logger.debug('send() | enabling legacy simulcast');
194
210
  localSdpObject = sdpTransform.parse(offer.sdp);
@@ -300,7 +316,7 @@ class Safari12 extends HandlerInterface_1.HandlerInterface {
300
316
  throw new Error('associated RTCRtpTransceiver not found');
301
317
  const parameters = transceiver.sender.getParameters();
302
318
  parameters.encodings.forEach((encoding, idx) => {
303
- parameters.encodings[idx] = Object.assign(Object.assign({}, encoding), params);
319
+ parameters.encodings[idx] = { ...encoding, ...params };
304
320
  });
305
321
  await transceiver.sender.setParameters(parameters);
306
322
  }
@@ -312,6 +328,7 @@ class Safari12 extends HandlerInterface_1.HandlerInterface {
312
328
  return transceiver.sender.getStats();
313
329
  }
314
330
  async sendDataChannel({ ordered, maxPacketLifeTime, maxRetransmits, label, protocol }) {
331
+ var _a;
315
332
  this._assertSendDirection();
316
333
  const options = {
317
334
  negotiated: true,
@@ -333,8 +350,12 @@ class Safari12 extends HandlerInterface_1.HandlerInterface {
333
350
  const localSdpObject = sdpTransform.parse(offer.sdp);
334
351
  const offerMediaObject = localSdpObject.media
335
352
  .find((m) => m.type === 'application');
336
- if (!this._transportReady)
337
- await this._setupTransport({ localDtlsRole: 'server', localSdpObject });
353
+ if (!this._transportReady) {
354
+ await this._setupTransport({
355
+ localDtlsRole: (_a = this._forcedLocalDtlsRole) !== null && _a !== void 0 ? _a : 'client',
356
+ localSdpObject
357
+ });
358
+ }
338
359
  logger.debug('sendDataChannel() | calling pc.setLocalDescription() [offer:%o]', offer);
339
360
  await this._pc.setLocalDescription(offer);
340
361
  this._remoteSdp.sendSctpAssociation({ offerMediaObject });
@@ -352,6 +373,7 @@ class Safari12 extends HandlerInterface_1.HandlerInterface {
352
373
  return { dataChannel, sctpStreamParameters };
353
374
  }
354
375
  async receive({ trackId, kind, rtpParameters }) {
376
+ var _a;
355
377
  this._assertRecvDirection();
356
378
  logger.debug('receive() [trackId:%s, kind:%s]', trackId, kind);
357
379
  const localId = rtpParameters.mid || String(this._mapMidTransceiver.size);
@@ -376,8 +398,12 @@ class Safari12 extends HandlerInterface_1.HandlerInterface {
376
398
  answerMediaObject
377
399
  });
378
400
  answer = { type: 'answer', sdp: sdpTransform.write(localSdpObject) };
379
- if (!this._transportReady)
380
- await this._setupTransport({ localDtlsRole: 'client', localSdpObject });
401
+ if (!this._transportReady) {
402
+ await this._setupTransport({
403
+ localDtlsRole: (_a = this._forcedLocalDtlsRole) !== null && _a !== void 0 ? _a : 'client',
404
+ localSdpObject
405
+ });
406
+ }
381
407
  logger.debug('receive() | calling pc.setLocalDescription() [answer:%o]', answer);
382
408
  await this._pc.setLocalDescription(answer);
383
409
  const transceiver = this._pc.getTransceivers()
@@ -443,6 +469,7 @@ class Safari12 extends HandlerInterface_1.HandlerInterface {
443
469
  return transceiver.receiver.getStats();
444
470
  }
445
471
  async receiveDataChannel({ sctpStreamParameters, label, protocol }) {
472
+ var _a;
446
473
  this._assertRecvDirection();
447
474
  const { streamId, ordered, maxPacketLifeTime, maxRetransmits } = sctpStreamParameters;
448
475
  const options = {
@@ -465,7 +492,10 @@ class Safari12 extends HandlerInterface_1.HandlerInterface {
465
492
  const answer = await this._pc.createAnswer();
466
493
  if (!this._transportReady) {
467
494
  const localSdpObject = sdpTransform.parse(answer.sdp);
468
- await this._setupTransport({ localDtlsRole: 'client', localSdpObject });
495
+ await this._setupTransport({
496
+ localDtlsRole: (_a = this._forcedLocalDtlsRole) !== null && _a !== void 0 ? _a : 'client',
497
+ localSdpObject
498
+ });
469
499
  }
470
500
  logger.debug('receiveDataChannel() | calling pc.setRemoteDescription() [answer:%o]', answer);
471
501
  await this._pc.setLocalDescription(answer);
@@ -14,7 +14,7 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
14
14
  var __importStar = (this && this.__importStar) || function (mod) {
15
15
  if (mod && mod.__esModule) return mod;
16
16
  var result = {};
17
- if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
18
  __setModuleDefault(result, mod);
19
19
  return result;
20
20
  };
@@ -14,7 +14,7 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
14
14
  var __importStar = (this && this.__importStar) || function (mod) {
15
15
  if (mod && mod.__esModule) return mod;
16
16
  var result = {};
17
- if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
18
  __setModuleDefault(result, mod);
19
19
  return result;
20
20
  };
@@ -14,7 +14,7 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
14
14
  var __importStar = (this && this.__importStar) || function (mod) {
15
15
  if (mod && mod.__esModule) return mod;
16
16
  var result = {};
17
- if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
18
  __setModuleDefault(result, mod);
19
19
  return result;
20
20
  };
@@ -14,7 +14,7 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
14
14
  var __importStar = (this && this.__importStar) || function (mod) {
15
15
  if (mod && mod.__esModule) return mod;
16
16
  var result = {};
17
- if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
18
  __setModuleDefault(result, mod);
19
19
  return result;
20
20
  };
package/lib/index.d.ts CHANGED
@@ -8,7 +8,7 @@ export { types };
8
8
  /**
9
9
  * Expose mediasoup-client version.
10
10
  */
11
- export declare const version = "3.6.43";
11
+ export declare const version = "3.6.47";
12
12
  /**
13
13
  * Expose Device class and detectDevice() helper.
14
14
  */
package/lib/index.js CHANGED
@@ -14,7 +14,7 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
14
14
  var __importStar = (this && this.__importStar) || function (mod) {
15
15
  if (mod && mod.__esModule) return mod;
16
16
  var result = {};
17
- if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
18
  __setModuleDefault(result, mod);
19
19
  return result;
20
20
  };
@@ -22,7 +22,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
22
22
  return (mod && mod.__esModule) ? mod : { "default": mod };
23
23
  };
24
24
  Object.defineProperty(exports, "__esModule", { value: true });
25
- exports.debug = exports.detectDevice = exports.Device = exports.version = exports.types = void 0;
25
+ exports.debug = exports.parseScalabilityMode = exports.detectDevice = exports.Device = exports.version = exports.types = void 0;
26
26
  const debug_1 = __importDefault(require("debug"));
27
27
  exports.debug = debug_1.default;
28
28
  const Device_1 = require("./Device");
@@ -33,7 +33,7 @@ exports.types = types;
33
33
  /**
34
34
  * Expose mediasoup-client version.
35
35
  */
36
- exports.version = '3.6.43';
36
+ exports.version = '3.6.47';
37
37
  /**
38
38
  * Expose parseScalabilityMode() function.
39
39
  */
package/lib/ortc.js CHANGED
@@ -14,7 +14,7 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
14
14
  var __importStar = (this && this.__importStar) || function (mod) {
15
15
  if (mod && mod.__esModule) return mod;
16
16
  var result = {};
17
- if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
18
  __setModuleDefault(result, mod);
19
19
  return result;
20
20
  };
@@ -780,12 +780,12 @@ function matchCodecs(aCodec, bCodec, { strict = false, modify = false } = {}) {
780
780
  switch (aMimeType) {
781
781
  case 'video/h264':
782
782
  {
783
- const aPacketizationMode = aCodec.parameters['packetization-mode'] || 0;
784
- const bPacketizationMode = bCodec.parameters['packetization-mode'] || 0;
785
- if (aPacketizationMode !== bPacketizationMode)
786
- return false;
787
783
  // If strict matching check profile-level-id.
788
784
  if (strict) {
785
+ const aPacketizationMode = aCodec.parameters['packetization-mode'] || 0;
786
+ const bPacketizationMode = bCodec.parameters['packetization-mode'] || 0;
787
+ if (aPacketizationMode !== bPacketizationMode)
788
+ return false;
789
789
  if (!h264.isSameProfile(aCodec.parameters, bCodec.parameters))
790
790
  return false;
791
791
  let selectedProfileLevelId;
package/lib/types.js CHANGED
@@ -7,7 +7,7 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi
7
7
  o[k2] = m[k];
8
8
  }));
9
9
  var __exportStar = (this && this.__exportStar) || function(m, exports) {
10
- for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p);
10
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
11
11
  };
12
12
  Object.defineProperty(exports, "__esModule", { value: true });
13
13
  __exportStar(require("./Device"), exports);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mediasoup-client",
3
- "version": "3.6.43",
3
+ "version": "3.6.47",
4
4
  "description": "mediasoup client side JavaScript library",
5
5
  "contributors": [
6
6
  "Iñaki Baz Castillo <ibc@aliax.net> (https://inakibaz.me)",
@@ -44,20 +44,20 @@
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": "^8.1.1"
47
+ "supports-color": "^9.1.0"
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": "^4.33.0",
53
- "@typescript-eslint/parser": "^4.33.0",
54
- "eslint": "^7.32.0",
55
- "eslint-plugin-jest": "^24.5.2",
56
- "jest": "^27.2.4",
52
+ "@typescript-eslint/eslint-plugin": "^5.4.0",
53
+ "@typescript-eslint/parser": "^5.4.0",
54
+ "eslint": "^8.3.0",
55
+ "eslint-plugin-jest": "^25.3.0",
56
+ "jest": "^27.3.1",
57
57
  "jest-tobetype": "^1.2.3",
58
- "open-cli": "^6.0.1",
58
+ "open-cli": "^7.0.1",
59
59
  "tsc-watch": "^4.5.0",
60
- "typescript": "^3.8",
60
+ "typescript": "^4.5.2",
61
61
  "uuid": "^3.4.0"
62
62
  }
63
63
  }
@@ -128,7 +128,7 @@ export class DataConsumer extends EnhancedEventEmitter
128
128
  /**
129
129
  * DataChannel binaryType.
130
130
  */
131
- get binaryType(): string
131
+ get binaryType(): BinaryType
132
132
  {
133
133
  return this._dataChannel.binaryType;
134
134
  }
@@ -136,7 +136,7 @@ export class DataConsumer extends EnhancedEventEmitter
136
136
  /**
137
137
  * Set DataChannel binaryType.
138
138
  */
139
- set binaryType(binaryType: string)
139
+ set binaryType(binaryType: BinaryType)
140
140
  {
141
141
  this._dataChannel.binaryType = binaryType;
142
142
  }
package/src/Device.ts CHANGED
@@ -80,8 +80,8 @@ export function detectDevice(): BuiltinHandlerName | undefined
80
80
  const browser = Bowser.getParser(ua);
81
81
  const engine = browser.getEngine();
82
82
 
83
- // Chrome and Chromium.
84
- if (browser.satisfies({ chrome: '>=74', chromium: '>=74' }))
83
+ // Chrome, Chromium, and Edge.
84
+ if (browser.satisfies({ chrome: '>=74', chromium: '>=74', 'microsoft edge': '>=88' }))
85
85
  {
86
86
  return 'Chrome74';
87
87
  }
@@ -102,6 +102,11 @@ export function detectDevice(): BuiltinHandlerName | undefined
102
102
  {
103
103
  return 'Firefox60';
104
104
  }
105
+ // Firefox on iOS.
106
+ else if (browser.satisfies({ ios: { OS: '>=14.3', firefox: '>=30.0' } }))
107
+ {
108
+ return 'Safari12';
109
+ }
105
110
  // Safari with Unified-Plan support enabled.
106
111
  else if (
107
112
  browser.satisfies({ safari: '>=12.0' }) &&
package/src/Transport.ts CHANGED
@@ -80,7 +80,7 @@ export type IceCandidate =
80
80
  */
81
81
  port: number;
82
82
  /**
83
- * The type of candidate..
83
+ * The type of candidate.
84
84
  */
85
85
  type: 'host' | 'srflx' | 'prflx' | 'relay';
86
86
  /**
@@ -92,11 +92,11 @@ export type IceCandidate =
92
92
  export type DtlsParameters =
93
93
  {
94
94
  /**
95
- * DTLS role. Default 'auto'.
95
+ * Server DTLS role. Default 'auto'.
96
96
  */
97
97
  role?: DtlsRole;
98
98
  /**
99
- * DTLS fingerprints.
99
+ * Server DTLS fingerprints.
100
100
  */
101
101
  fingerprints: DtlsFingerprint[];
102
102
  }
@@ -38,6 +38,9 @@ export class Chrome55 extends HandlerInterface
38
38
  // Generic sending RTP parameters for audio and video suitable for the SDP
39
39
  // remote answer.
40
40
  private _sendingRemoteRtpParametersByKind?: { [key: string]: RtpParameters };
41
+ // Initial server side DTLS role. If not 'auto', it will force the opposite
42
+ // value in client side.
43
+ private _forcedLocalDtlsRole?: DtlsRole;
41
44
  // RTCPeerConnection instance.
42
45
  private _pc: any;
43
46
  // Local stream for sending.
@@ -181,6 +184,13 @@ export class Chrome55 extends HandlerInterface
181
184
  video : ortc.getSendingRemoteRtpParameters('video', extendedRtpCapabilities)
182
185
  };
183
186
 
187
+ if (dtlsParameters.role && dtlsParameters.role !== 'auto')
188
+ {
189
+ this._forcedLocalDtlsRole = dtlsParameters.role === 'server'
190
+ ? 'client'
191
+ : 'server';
192
+ }
193
+
184
194
  this._pc = new (RTCPeerConnection as any)(
185
195
  {
186
196
  iceServers : iceServers || [],
@@ -315,7 +325,13 @@ export class Chrome55 extends HandlerInterface
315
325
  ortc.reduceCodecs(sendingRemoteRtpParameters.codecs);
316
326
 
317
327
  if (!this._transportReady)
318
- await this._setupTransport({ localDtlsRole: 'server', localSdpObject });
328
+ {
329
+ await this._setupTransport(
330
+ {
331
+ localDtlsRole : this._forcedLocalDtlsRole ?? 'client',
332
+ localSdpObject
333
+ });
334
+ }
319
335
 
320
336
  if (track.kind === 'video' && encodings && encodings.length > 1)
321
337
  {
@@ -438,7 +454,7 @@ export class Chrome55 extends HandlerInterface
438
454
  {
439
455
  logger.warn(
440
456
  'stopSending() | ignoring expected error due no sending tracks: %s',
441
- error.toString());
457
+ (error as Error).toString());
442
458
 
443
459
  return;
444
460
  }
@@ -525,7 +541,13 @@ export class Chrome55 extends HandlerInterface
525
541
  .find((m: any) => m.type === 'application');
526
542
 
527
543
  if (!this._transportReady)
528
- await this._setupTransport({ localDtlsRole: 'server', localSdpObject });
544
+ {
545
+ await this._setupTransport(
546
+ {
547
+ localDtlsRole : this._forcedLocalDtlsRole ?? 'client',
548
+ localSdpObject
549
+ });
550
+ }
529
551
 
530
552
  logger.debug(
531
553
  'sendDataChannel() | calling pc.setLocalDescription() [offer:%o]',
@@ -602,7 +624,13 @@ export class Chrome55 extends HandlerInterface
602
624
  answer = { type: 'answer', sdp: sdpTransform.write(localSdpObject) };
603
625
 
604
626
  if (!this._transportReady)
605
- await this._setupTransport({ localDtlsRole: 'client', localSdpObject });
627
+ {
628
+ await this._setupTransport(
629
+ {
630
+ localDtlsRole : this._forcedLocalDtlsRole ?? 'client',
631
+ localSdpObject
632
+ });
633
+ }
606
634
 
607
635
  logger.debug(
608
636
  'receive() | calling pc.setLocalDescription() [answer:%o]',
@@ -722,7 +750,11 @@ export class Chrome55 extends HandlerInterface
722
750
  {
723
751
  const localSdpObject = sdpTransform.parse(answer.sdp);
724
752
 
725
- await this._setupTransport({ localDtlsRole: 'client', localSdpObject });
753
+ await this._setupTransport(
754
+ {
755
+ localDtlsRole : this._forcedLocalDtlsRole ?? 'client',
756
+ localSdpObject
757
+ });
726
758
  }
727
759
 
728
760
  logger.debug(
@@ -37,6 +37,9 @@ export class Chrome67 extends HandlerInterface
37
37
  // Generic sending RTP parameters for audio and video suitable for the SDP
38
38
  // remote answer.
39
39
  private _sendingRemoteRtpParametersByKind?: { [key: string]: RtpParameters };
40
+ // Initial server side DTLS role. If not 'auto', it will force the opposite
41
+ // value in client side.
42
+ private _forcedLocalDtlsRole?: DtlsRole;
40
43
  // RTCPeerConnection instance.
41
44
  private _pc: any;
42
45
  // Local stream for sending.
@@ -182,6 +185,13 @@ export class Chrome67 extends HandlerInterface
182
185
  video : ortc.getSendingRemoteRtpParameters('video', extendedRtpCapabilities)
183
186
  };
184
187
 
188
+ if (dtlsParameters.role && dtlsParameters.role !== 'auto')
189
+ {
190
+ this._forcedLocalDtlsRole = dtlsParameters.role === 'server'
191
+ ? 'client'
192
+ : 'server';
193
+ }
194
+
185
195
  this._pc = new (RTCPeerConnection as any)(
186
196
  {
187
197
  iceServers : iceServers || [],
@@ -316,7 +326,13 @@ export class Chrome67 extends HandlerInterface
316
326
  ortc.reduceCodecs(sendingRemoteRtpParameters.codecs);
317
327
 
318
328
  if (!this._transportReady)
319
- await this._setupTransport({ localDtlsRole: 'server', localSdpObject });
329
+ {
330
+ await this._setupTransport(
331
+ {
332
+ localDtlsRole : this._forcedLocalDtlsRole ?? 'client',
333
+ localSdpObject
334
+ });
335
+ }
320
336
 
321
337
  if (track.kind === 'video' && encodings && encodings.length > 1)
322
338
  {
@@ -446,7 +462,7 @@ export class Chrome67 extends HandlerInterface
446
462
  {
447
463
  logger.warn(
448
464
  'stopSending() | ignoring expected error due no sending tracks: %s',
449
- error.toString());
465
+ (error as Error).toString());
450
466
 
451
467
  return;
452
468
  }
@@ -602,7 +618,13 @@ export class Chrome67 extends HandlerInterface
602
618
  .find((m: any) => m.type === 'application');
603
619
 
604
620
  if (!this._transportReady)
605
- await this._setupTransport({ localDtlsRole: 'server', localSdpObject });
621
+ {
622
+ await this._setupTransport(
623
+ {
624
+ localDtlsRole : this._forcedLocalDtlsRole ?? 'client',
625
+ localSdpObject
626
+ });
627
+ }
606
628
 
607
629
  logger.debug(
608
630
  'sendDataChannel() | calling pc.setLocalDescription() [offer:%o]',
@@ -678,7 +700,13 @@ export class Chrome67 extends HandlerInterface
678
700
  answer = { type: 'answer', sdp: sdpTransform.write(localSdpObject) };
679
701
 
680
702
  if (!this._transportReady)
681
- await this._setupTransport({ localDtlsRole: 'client', localSdpObject });
703
+ {
704
+ await this._setupTransport(
705
+ {
706
+ localDtlsRole : this._forcedLocalDtlsRole ?? 'client',
707
+ localSdpObject
708
+ });
709
+ }
682
710
 
683
711
  logger.debug(
684
712
  'receive() | calling pc.setLocalDescription() [answer:%o]',
@@ -807,7 +835,11 @@ export class Chrome67 extends HandlerInterface
807
835
  {
808
836
  const localSdpObject = sdpTransform.parse(answer.sdp);
809
837
 
810
- await this._setupTransport({ localDtlsRole: 'client', localSdpObject });
838
+ await this._setupTransport(
839
+ {
840
+ localDtlsRole : this._forcedLocalDtlsRole ?? 'client',
841
+ localSdpObject
842
+ });
811
843
  }
812
844
 
813
845
  logger.debug(
@@ -38,6 +38,9 @@ export class Chrome70 extends HandlerInterface
38
38
  // Generic sending RTP parameters for audio and video suitable for the SDP
39
39
  // remote answer.
40
40
  private _sendingRemoteRtpParametersByKind?: { [key: string]: RtpParameters };
41
+ // Initial server side DTLS role. If not 'auto', it will force the opposite
42
+ // value in client side.
43
+ private _forcedLocalDtlsRole?: DtlsRole;
41
44
  // RTCPeerConnection instance.
42
45
  private _pc: any;
43
46
  // Map of RTCTransceivers indexed by MID.
@@ -168,6 +171,13 @@ export class Chrome70 extends HandlerInterface
168
171
  video : ortc.getSendingRemoteRtpParameters('video', extendedRtpCapabilities)
169
172
  };
170
173
 
174
+ if (dtlsParameters.role && dtlsParameters.role !== 'auto')
175
+ {
176
+ this._forcedLocalDtlsRole = dtlsParameters.role === 'server'
177
+ ? 'client'
178
+ : 'server';
179
+ }
180
+
171
181
  this._pc = new (RTCPeerConnection as any)(
172
182
  {
173
183
  iceServers : iceServers || [],
@@ -298,7 +308,13 @@ export class Chrome70 extends HandlerInterface
298
308
  let offerMediaObject;
299
309
 
300
310
  if (!this._transportReady)
301
- await this._setupTransport({ localDtlsRole: 'server', localSdpObject });
311
+ {
312
+ await this._setupTransport(
313
+ {
314
+ localDtlsRole : this._forcedLocalDtlsRole ?? 'client',
315
+ localSdpObject
316
+ });
317
+ }
302
318
 
303
319
  if (encodings && encodings.length > 1)
304
320
  {
@@ -608,7 +624,13 @@ export class Chrome70 extends HandlerInterface
608
624
  .find((m: any) => m.type === 'application');
609
625
 
610
626
  if (!this._transportReady)
611
- await this._setupTransport({ localDtlsRole: 'server', localSdpObject });
627
+ {
628
+ await this._setupTransport(
629
+ {
630
+ localDtlsRole : this._forcedLocalDtlsRole ?? 'client',
631
+ localSdpObject
632
+ });
633
+ }
612
634
 
613
635
  logger.debug(
614
636
  'sendDataChannel() | calling pc.setLocalDescription() [offer:%o]',
@@ -683,7 +705,13 @@ export class Chrome70 extends HandlerInterface
683
705
  answer = { type: 'answer', sdp: sdpTransform.write(localSdpObject) };
684
706
 
685
707
  if (!this._transportReady)
686
- await this._setupTransport({ localDtlsRole: 'client', localSdpObject });
708
+ {
709
+ await this._setupTransport(
710
+ {
711
+ localDtlsRole : this._forcedLocalDtlsRole ?? 'client',
712
+ localSdpObject
713
+ });
714
+ }
687
715
 
688
716
  logger.debug(
689
717
  'receive() | calling pc.setLocalDescription() [answer:%o]',
@@ -813,7 +841,11 @@ export class Chrome70 extends HandlerInterface
813
841
  {
814
842
  const localSdpObject = sdpTransform.parse(answer.sdp);
815
843
 
816
- await this._setupTransport({ localDtlsRole: 'client', localSdpObject });
844
+ await this._setupTransport(
845
+ {
846
+ localDtlsRole : this._forcedLocalDtlsRole ?? 'client',
847
+ localSdpObject
848
+ });
817
849
  }
818
850
 
819
851
  logger.debug(