livekit-client 2.5.6 → 2.5.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. package/dist/livekit-client.e2ee.worker.js +1 -1
  2. package/dist/livekit-client.e2ee.worker.js.map +1 -1
  3. package/dist/livekit-client.e2ee.worker.mjs +624 -603
  4. package/dist/livekit-client.e2ee.worker.mjs.map +1 -1
  5. package/dist/livekit-client.esm.mjs +2123 -1948
  6. package/dist/livekit-client.esm.mjs.map +1 -1
  7. package/dist/livekit-client.umd.js +1 -1
  8. package/dist/livekit-client.umd.js.map +1 -1
  9. package/dist/src/e2ee/worker/FrameCryptor.d.ts +2 -2
  10. package/dist/src/e2ee/worker/FrameCryptor.d.ts.map +1 -1
  11. package/dist/src/index.d.ts +2 -2
  12. package/dist/src/index.d.ts.map +1 -1
  13. package/dist/src/room/Room.d.ts +2 -1
  14. package/dist/src/room/Room.d.ts.map +1 -1
  15. package/dist/src/room/events.d.ts +2 -2
  16. package/dist/src/room/participant/Participant.d.ts +1 -1
  17. package/dist/src/room/participant/Participant.d.ts.map +1 -1
  18. package/dist/src/room/track/Track.d.ts +1 -1
  19. package/dist/src/room/track/Track.d.ts.map +1 -1
  20. package/dist/src/room/utils.d.ts +1 -1
  21. package/dist/src/room/utils.d.ts.map +1 -1
  22. package/dist/src/test/mocks.d.ts +1 -1
  23. package/dist/src/test/mocks.d.ts.map +1 -1
  24. package/dist/ts4.2/src/e2ee/worker/FrameCryptor.d.ts +2 -2
  25. package/dist/ts4.2/src/index.d.ts +2 -2
  26. package/dist/ts4.2/src/room/Room.d.ts +2 -1
  27. package/dist/ts4.2/src/room/events.d.ts +2 -2
  28. package/dist/ts4.2/src/room/participant/Participant.d.ts +1 -1
  29. package/dist/ts4.2/src/room/track/Track.d.ts +1 -1
  30. package/dist/ts4.2/src/room/utils.d.ts +1 -1
  31. package/dist/ts4.2/src/test/mocks.d.ts +1 -1
  32. package/package.json +10 -11
  33. package/src/e2ee/worker/FrameCryptor.test.ts +249 -2
  34. package/src/e2ee/worker/FrameCryptor.ts +3 -3
  35. package/src/e2ee/worker/ParticipantKeyHandler.test.ts +122 -0
  36. package/src/e2ee/worker/ParticipantKeyHandler.ts +1 -1
  37. package/src/e2ee/worker/e2ee.worker.ts +1 -1
  38. package/src/index.ts +2 -0
  39. package/src/room/Room.ts +16 -10
  40. package/src/room/events.ts +2 -2
  41. package/src/room/participant/Participant.ts +3 -2
  42. package/src/room/track/Track.ts +1 -1
  43. package/src/room/track/utils.ts +1 -1
  44. package/src/room/utils.ts +1 -1
  45. package/src/test/mocks.ts +1 -1
@@ -3672,6 +3672,11 @@ const TimeSeriesMetric = /*@__PURE__*/proto3.makeMessageType("livekit.TimeSeries
3672
3672
  kind: "message",
3673
3673
  T: MetricSample,
3674
3674
  repeated: true
3675
+ }, {
3676
+ no: 5,
3677
+ name: "rid",
3678
+ kind: "scalar",
3679
+ T: 13 /* ScalarType.UINT32 */
3675
3680
  }]);
3676
3681
 
3677
3682
  /**
@@ -3739,6 +3744,11 @@ const EventMetric = /*@__PURE__*/proto3.makeMessageType("livekit.EventMetric", (
3739
3744
  name: "metadata",
3740
3745
  kind: "scalar",
3741
3746
  T: 9 /* ScalarType.STRING */
3747
+ }, {
3748
+ no: 9,
3749
+ name: "rid",
3750
+ kind: "scalar",
3751
+ T: 13 /* ScalarType.UINT32 */
3742
3752
  }]);
3743
3753
 
3744
3754
  // Copyright 2023 LiveKit, Inc.
@@ -4419,6 +4429,24 @@ const DataPacket = /*@__PURE__*/proto3.makeMessageType("livekit.DataPacket", ()
4419
4429
  kind: "message",
4420
4430
  T: ChatMessage,
4421
4431
  oneof: "value"
4432
+ }, {
4433
+ no: 10,
4434
+ name: "rpc_request",
4435
+ kind: "message",
4436
+ T: RpcRequest,
4437
+ oneof: "value"
4438
+ }, {
4439
+ no: 11,
4440
+ name: "rpc_ack",
4441
+ kind: "message",
4442
+ T: RpcAck,
4443
+ oneof: "value"
4444
+ }, {
4445
+ no: 12,
4446
+ name: "rpc_response",
4447
+ kind: "message",
4448
+ T: RpcResponse,
4449
+ oneof: "value"
4422
4450
  }]);
4423
4451
 
4424
4452
  /**
@@ -4626,6 +4654,88 @@ const ChatMessage = /*@__PURE__*/proto3.makeMessageType("livekit.ChatMessage", (
4626
4654
  T: 8 /* ScalarType.BOOL */
4627
4655
  }]);
4628
4656
 
4657
+ /**
4658
+ * @generated from message livekit.RpcRequest
4659
+ */
4660
+ const RpcRequest = /*@__PURE__*/proto3.makeMessageType("livekit.RpcRequest", () => [{
4661
+ no: 1,
4662
+ name: "id",
4663
+ kind: "scalar",
4664
+ T: 9 /* ScalarType.STRING */
4665
+ }, {
4666
+ no: 2,
4667
+ name: "method",
4668
+ kind: "scalar",
4669
+ T: 9 /* ScalarType.STRING */
4670
+ }, {
4671
+ no: 3,
4672
+ name: "payload",
4673
+ kind: "scalar",
4674
+ T: 9 /* ScalarType.STRING */
4675
+ }, {
4676
+ no: 4,
4677
+ name: "response_timeout_ms",
4678
+ kind: "scalar",
4679
+ T: 13 /* ScalarType.UINT32 */
4680
+ }, {
4681
+ no: 5,
4682
+ name: "version",
4683
+ kind: "scalar",
4684
+ T: 13 /* ScalarType.UINT32 */
4685
+ }]);
4686
+
4687
+ /**
4688
+ * @generated from message livekit.RpcAck
4689
+ */
4690
+ const RpcAck = /*@__PURE__*/proto3.makeMessageType("livekit.RpcAck", () => [{
4691
+ no: 1,
4692
+ name: "request_id",
4693
+ kind: "scalar",
4694
+ T: 9 /* ScalarType.STRING */
4695
+ }]);
4696
+
4697
+ /**
4698
+ * @generated from message livekit.RpcResponse
4699
+ */
4700
+ const RpcResponse = /*@__PURE__*/proto3.makeMessageType("livekit.RpcResponse", () => [{
4701
+ no: 1,
4702
+ name: "request_id",
4703
+ kind: "scalar",
4704
+ T: 9 /* ScalarType.STRING */
4705
+ }, {
4706
+ no: 2,
4707
+ name: "payload",
4708
+ kind: "scalar",
4709
+ T: 9 /* ScalarType.STRING */,
4710
+ oneof: "value"
4711
+ }, {
4712
+ no: 3,
4713
+ name: "error",
4714
+ kind: "message",
4715
+ T: RpcError,
4716
+ oneof: "value"
4717
+ }]);
4718
+
4719
+ /**
4720
+ * @generated from message livekit.RpcError
4721
+ */
4722
+ const RpcError = /*@__PURE__*/proto3.makeMessageType("livekit.RpcError", () => [{
4723
+ no: 1,
4724
+ name: "code",
4725
+ kind: "scalar",
4726
+ T: 13 /* ScalarType.UINT32 */
4727
+ }, {
4728
+ no: 2,
4729
+ name: "message",
4730
+ kind: "scalar",
4731
+ T: 9 /* ScalarType.STRING */
4732
+ }, {
4733
+ no: 3,
4734
+ name: "data",
4735
+ kind: "scalar",
4736
+ T: 9 /* ScalarType.STRING */
4737
+ }]);
4738
+
4629
4739
  /**
4630
4740
  * @generated from message livekit.ParticipantTracks
4631
4741
  */
@@ -4750,6 +4860,11 @@ const ClientInfo = /*@__PURE__*/proto3.makeMessageType("livekit.ClientInfo", ()
4750
4860
  name: "network",
4751
4861
  kind: "scalar",
4752
4862
  T: 9 /* ScalarType.STRING */
4863
+ }, {
4864
+ no: 11,
4865
+ name: "other_sdks",
4866
+ kind: "scalar",
4867
+ T: 9 /* ScalarType.STRING */
4753
4868
  }]);
4754
4869
 
4755
4870
  /**
@@ -6094,13 +6209,11 @@ const TrackSubscribed = /*@__PURE__*/proto3.makeMessageType("livekit.TrackSubscr
6094
6209
  T: 9 /* ScalarType.STRING */
6095
6210
  }]);
6096
6211
 
6097
- var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
6098
-
6099
6212
  function getDefaultExportFromCjs (x) {
6100
6213
  return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
6101
6214
  }
6102
6215
 
6103
- var loglevel = {exports: {}};
6216
+ var loglevel$1 = {exports: {}};
6104
6217
 
6105
6218
  /*
6106
6219
  * loglevel - https://github.com/pimterry/loglevel
@@ -6108,315 +6221,323 @@ var loglevel = {exports: {}};
6108
6221
  * Copyright (c) 2013 Tim Perry
6109
6222
  * Licensed under the MIT license.
6110
6223
  */
6111
- (function (module) {
6112
- (function (root, definition) {
6113
-
6114
- if (module.exports) {
6115
- module.exports = definition();
6116
- } else {
6117
- root.log = definition();
6118
- }
6119
- })(commonjsGlobal, function () {
6120
-
6121
- // Slightly dubious tricks to cut down minimized file size
6122
- var noop = function () {};
6123
- var undefinedType = "undefined";
6124
- var isIE = typeof window !== undefinedType && typeof window.navigator !== undefinedType && /Trident\/|MSIE /.test(window.navigator.userAgent);
6125
- var logMethods = ["trace", "debug", "info", "warn", "error"];
6126
- var _loggersByName = {};
6127
- var defaultLogger = null;
6128
-
6129
- // Cross-browser bind equivalent that works at least back to IE6
6130
- function bindMethod(obj, methodName) {
6131
- var method = obj[methodName];
6132
- if (typeof method.bind === 'function') {
6133
- return method.bind(obj);
6224
+ var loglevel = loglevel$1.exports;
6225
+ var hasRequiredLoglevel;
6226
+ function requireLoglevel() {
6227
+ if (hasRequiredLoglevel) return loglevel$1.exports;
6228
+ hasRequiredLoglevel = 1;
6229
+ (function (module) {
6230
+ (function (root, definition) {
6231
+
6232
+ if (module.exports) {
6233
+ module.exports = definition();
6134
6234
  } else {
6135
- try {
6136
- return Function.prototype.bind.call(method, obj);
6137
- } catch (e) {
6138
- // Missing bind shim or IE8 + Modernizr, fallback to wrapping
6139
- return function () {
6140
- return Function.prototype.apply.apply(method, [obj, arguments]);
6141
- };
6235
+ root.log = definition();
6236
+ }
6237
+ })(loglevel, function () {
6238
+
6239
+ // Slightly dubious tricks to cut down minimized file size
6240
+ var noop = function () {};
6241
+ var undefinedType = "undefined";
6242
+ var isIE = typeof window !== undefinedType && typeof window.navigator !== undefinedType && /Trident\/|MSIE /.test(window.navigator.userAgent);
6243
+ var logMethods = ["trace", "debug", "info", "warn", "error"];
6244
+ var _loggersByName = {};
6245
+ var defaultLogger = null;
6246
+
6247
+ // Cross-browser bind equivalent that works at least back to IE6
6248
+ function bindMethod(obj, methodName) {
6249
+ var method = obj[methodName];
6250
+ if (typeof method.bind === 'function') {
6251
+ return method.bind(obj);
6252
+ } else {
6253
+ try {
6254
+ return Function.prototype.bind.call(method, obj);
6255
+ } catch (e) {
6256
+ // Missing bind shim or IE8 + Modernizr, fallback to wrapping
6257
+ return function () {
6258
+ return Function.prototype.apply.apply(method, [obj, arguments]);
6259
+ };
6260
+ }
6142
6261
  }
6143
6262
  }
6144
- }
6145
6263
 
6146
- // Trace() doesn't print the message in IE, so for that case we need to wrap it
6147
- function traceForIE() {
6148
- if (console.log) {
6149
- if (console.log.apply) {
6150
- console.log.apply(console, arguments);
6151
- } else {
6152
- // In old IE, native console methods themselves don't have apply().
6153
- Function.prototype.apply.apply(console.log, [console, arguments]);
6264
+ // Trace() doesn't print the message in IE, so for that case we need to wrap it
6265
+ function traceForIE() {
6266
+ if (console.log) {
6267
+ if (console.log.apply) {
6268
+ console.log.apply(console, arguments);
6269
+ } else {
6270
+ // In old IE, native console methods themselves don't have apply().
6271
+ Function.prototype.apply.apply(console.log, [console, arguments]);
6272
+ }
6154
6273
  }
6274
+ if (console.trace) console.trace();
6155
6275
  }
6156
- if (console.trace) console.trace();
6157
- }
6158
6276
 
6159
- // Build the best logging method possible for this env
6160
- // Wherever possible we want to bind, not wrap, to preserve stack traces
6161
- function realMethod(methodName) {
6162
- if (methodName === 'debug') {
6163
- methodName = 'log';
6164
- }
6165
- if (typeof console === undefinedType) {
6166
- return false; // No method possible, for now - fixed later by enableLoggingWhenConsoleArrives
6167
- } else if (methodName === 'trace' && isIE) {
6168
- return traceForIE;
6169
- } else if (console[methodName] !== undefined) {
6170
- return bindMethod(console, methodName);
6171
- } else if (console.log !== undefined) {
6172
- return bindMethod(console, 'log');
6173
- } else {
6174
- return noop;
6277
+ // Build the best logging method possible for this env
6278
+ // Wherever possible we want to bind, not wrap, to preserve stack traces
6279
+ function realMethod(methodName) {
6280
+ if (methodName === 'debug') {
6281
+ methodName = 'log';
6282
+ }
6283
+ if (typeof console === undefinedType) {
6284
+ return false; // No method possible, for now - fixed later by enableLoggingWhenConsoleArrives
6285
+ } else if (methodName === 'trace' && isIE) {
6286
+ return traceForIE;
6287
+ } else if (console[methodName] !== undefined) {
6288
+ return bindMethod(console, methodName);
6289
+ } else if (console.log !== undefined) {
6290
+ return bindMethod(console, 'log');
6291
+ } else {
6292
+ return noop;
6293
+ }
6175
6294
  }
6176
- }
6177
6295
 
6178
- // These private functions always need `this` to be set properly
6296
+ // These private functions always need `this` to be set properly
6179
6297
 
6180
- function replaceLoggingMethods() {
6181
- /*jshint validthis:true */
6182
- var level = this.getLevel();
6298
+ function replaceLoggingMethods() {
6299
+ /*jshint validthis:true */
6300
+ var level = this.getLevel();
6183
6301
 
6184
- // Replace the actual methods.
6185
- for (var i = 0; i < logMethods.length; i++) {
6186
- var methodName = logMethods[i];
6187
- this[methodName] = i < level ? noop : this.methodFactory(methodName, level, this.name);
6188
- }
6189
-
6190
- // Define log.log as an alias for log.debug
6191
- this.log = this.debug;
6302
+ // Replace the actual methods.
6303
+ for (var i = 0; i < logMethods.length; i++) {
6304
+ var methodName = logMethods[i];
6305
+ this[methodName] = i < level ? noop : this.methodFactory(methodName, level, this.name);
6306
+ }
6192
6307
 
6193
- // Return any important warnings.
6194
- if (typeof console === undefinedType && level < this.levels.SILENT) {
6195
- return "No console available for logging";
6196
- }
6197
- }
6308
+ // Define log.log as an alias for log.debug
6309
+ this.log = this.debug;
6198
6310
 
6199
- // In old IE versions, the console isn't present until you first open it.
6200
- // We build realMethod() replacements here that regenerate logging methods
6201
- function enableLoggingWhenConsoleArrives(methodName) {
6202
- return function () {
6203
- if (typeof console !== undefinedType) {
6204
- replaceLoggingMethods.call(this);
6205
- this[methodName].apply(this, arguments);
6311
+ // Return any important warnings.
6312
+ if (typeof console === undefinedType && level < this.levels.SILENT) {
6313
+ return "No console available for logging";
6206
6314
  }
6207
- };
6208
- }
6315
+ }
6209
6316
 
6210
- // By default, we use closely bound real methods wherever possible, and
6211
- // otherwise we wait for a console to appear, and then try again.
6212
- function defaultMethodFactory(methodName, _level, _loggerName) {
6213
- /*jshint validthis:true */
6214
- return realMethod(methodName) || enableLoggingWhenConsoleArrives.apply(this, arguments);
6215
- }
6216
- function Logger(name, factory) {
6217
- // Private instance variables.
6218
- var self = this;
6219
- /**
6220
- * The level inherited from a parent logger (or a global default). We
6221
- * cache this here rather than delegating to the parent so that it stays
6222
- * in sync with the actual logging methods that we have installed (the
6223
- * parent could change levels but we might not have rebuilt the loggers
6224
- * in this child yet).
6225
- * @type {number}
6226
- */
6227
- var inheritedLevel;
6228
- /**
6229
- * The default level for this logger, if any. If set, this overrides
6230
- * `inheritedLevel`.
6231
- * @type {number|null}
6232
- */
6233
- var defaultLevel;
6234
- /**
6235
- * A user-specific level for this logger. If set, this overrides
6236
- * `defaultLevel`.
6237
- * @type {number|null}
6238
- */
6239
- var userLevel;
6240
- var storageKey = "loglevel";
6241
- if (typeof name === "string") {
6242
- storageKey += ":" + name;
6243
- } else if (typeof name === "symbol") {
6244
- storageKey = undefined;
6245
- }
6246
- function persistLevelIfPossible(levelNum) {
6247
- var levelName = (logMethods[levelNum] || 'silent').toUpperCase();
6248
- if (typeof window === undefinedType || !storageKey) return;
6249
-
6250
- // Use localStorage if available
6251
- try {
6252
- window.localStorage[storageKey] = levelName;
6253
- return;
6254
- } catch (ignore) {}
6317
+ // In old IE versions, the console isn't present until you first open it.
6318
+ // We build realMethod() replacements here that regenerate logging methods
6319
+ function enableLoggingWhenConsoleArrives(methodName) {
6320
+ return function () {
6321
+ if (typeof console !== undefinedType) {
6322
+ replaceLoggingMethods.call(this);
6323
+ this[methodName].apply(this, arguments);
6324
+ }
6325
+ };
6326
+ }
6255
6327
 
6256
- // Use session cookie as fallback
6257
- try {
6258
- window.document.cookie = encodeURIComponent(storageKey) + "=" + levelName + ";";
6259
- } catch (ignore) {}
6328
+ // By default, we use closely bound real methods wherever possible, and
6329
+ // otherwise we wait for a console to appear, and then try again.
6330
+ function defaultMethodFactory(methodName, _level, _loggerName) {
6331
+ /*jshint validthis:true */
6332
+ return realMethod(methodName) || enableLoggingWhenConsoleArrives.apply(this, arguments);
6260
6333
  }
6261
- function getPersistedLevel() {
6262
- var storedLevel;
6263
- if (typeof window === undefinedType || !storageKey) return;
6264
- try {
6265
- storedLevel = window.localStorage[storageKey];
6266
- } catch (ignore) {}
6334
+ function Logger(name, factory) {
6335
+ // Private instance variables.
6336
+ var self = this;
6337
+ /**
6338
+ * The level inherited from a parent logger (or a global default). We
6339
+ * cache this here rather than delegating to the parent so that it stays
6340
+ * in sync with the actual logging methods that we have installed (the
6341
+ * parent could change levels but we might not have rebuilt the loggers
6342
+ * in this child yet).
6343
+ * @type {number}
6344
+ */
6345
+ var inheritedLevel;
6346
+ /**
6347
+ * The default level for this logger, if any. If set, this overrides
6348
+ * `inheritedLevel`.
6349
+ * @type {number|null}
6350
+ */
6351
+ var defaultLevel;
6352
+ /**
6353
+ * A user-specific level for this logger. If set, this overrides
6354
+ * `defaultLevel`.
6355
+ * @type {number|null}
6356
+ */
6357
+ var userLevel;
6358
+ var storageKey = "loglevel";
6359
+ if (typeof name === "string") {
6360
+ storageKey += ":" + name;
6361
+ } else if (typeof name === "symbol") {
6362
+ storageKey = undefined;
6363
+ }
6364
+ function persistLevelIfPossible(levelNum) {
6365
+ var levelName = (logMethods[levelNum] || 'silent').toUpperCase();
6366
+ if (typeof window === undefinedType || !storageKey) return;
6367
+
6368
+ // Use localStorage if available
6369
+ try {
6370
+ window.localStorage[storageKey] = levelName;
6371
+ return;
6372
+ } catch (ignore) {}
6267
6373
 
6268
- // Fallback to cookies if local storage gives us nothing
6269
- if (typeof storedLevel === undefinedType) {
6374
+ // Use session cookie as fallback
6270
6375
  try {
6271
- var cookie = window.document.cookie;
6272
- var cookieName = encodeURIComponent(storageKey);
6273
- var location = cookie.indexOf(cookieName + "=");
6274
- if (location !== -1) {
6275
- storedLevel = /^([^;]+)/.exec(cookie.slice(location + cookieName.length + 1))[1];
6276
- }
6376
+ window.document.cookie = encodeURIComponent(storageKey) + "=" + levelName + ";";
6277
6377
  } catch (ignore) {}
6278
6378
  }
6379
+ function getPersistedLevel() {
6380
+ var storedLevel;
6381
+ if (typeof window === undefinedType || !storageKey) return;
6382
+ try {
6383
+ storedLevel = window.localStorage[storageKey];
6384
+ } catch (ignore) {}
6385
+
6386
+ // Fallback to cookies if local storage gives us nothing
6387
+ if (typeof storedLevel === undefinedType) {
6388
+ try {
6389
+ var cookie = window.document.cookie;
6390
+ var cookieName = encodeURIComponent(storageKey);
6391
+ var location = cookie.indexOf(cookieName + "=");
6392
+ if (location !== -1) {
6393
+ storedLevel = /^([^;]+)/.exec(cookie.slice(location + cookieName.length + 1))[1];
6394
+ }
6395
+ } catch (ignore) {}
6396
+ }
6279
6397
 
6280
- // If the stored level is not valid, treat it as if nothing was stored.
6281
- if (self.levels[storedLevel] === undefined) {
6282
- storedLevel = undefined;
6398
+ // If the stored level is not valid, treat it as if nothing was stored.
6399
+ if (self.levels[storedLevel] === undefined) {
6400
+ storedLevel = undefined;
6401
+ }
6402
+ return storedLevel;
6283
6403
  }
6284
- return storedLevel;
6285
- }
6286
- function clearPersistedLevel() {
6287
- if (typeof window === undefinedType || !storageKey) return;
6404
+ function clearPersistedLevel() {
6405
+ if (typeof window === undefinedType || !storageKey) return;
6288
6406
 
6289
- // Use localStorage if available
6290
- try {
6291
- window.localStorage.removeItem(storageKey);
6292
- } catch (ignore) {}
6407
+ // Use localStorage if available
6408
+ try {
6409
+ window.localStorage.removeItem(storageKey);
6410
+ } catch (ignore) {}
6293
6411
 
6294
- // Use session cookie as fallback
6295
- try {
6296
- window.document.cookie = encodeURIComponent(storageKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 UTC";
6297
- } catch (ignore) {}
6298
- }
6299
- function normalizeLevel(input) {
6300
- var level = input;
6301
- if (typeof level === "string" && self.levels[level.toUpperCase()] !== undefined) {
6302
- level = self.levels[level.toUpperCase()];
6412
+ // Use session cookie as fallback
6413
+ try {
6414
+ window.document.cookie = encodeURIComponent(storageKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 UTC";
6415
+ } catch (ignore) {}
6303
6416
  }
6304
- if (typeof level === "number" && level >= 0 && level <= self.levels.SILENT) {
6305
- return level;
6306
- } else {
6307
- throw new TypeError("log.setLevel() called with invalid level: " + input);
6417
+ function normalizeLevel(input) {
6418
+ var level = input;
6419
+ if (typeof level === "string" && self.levels[level.toUpperCase()] !== undefined) {
6420
+ level = self.levels[level.toUpperCase()];
6421
+ }
6422
+ if (typeof level === "number" && level >= 0 && level <= self.levels.SILENT) {
6423
+ return level;
6424
+ } else {
6425
+ throw new TypeError("log.setLevel() called with invalid level: " + input);
6426
+ }
6308
6427
  }
6428
+
6429
+ /*
6430
+ *
6431
+ * Public logger API - see https://github.com/pimterry/loglevel for details
6432
+ *
6433
+ */
6434
+
6435
+ self.name = name;
6436
+ self.levels = {
6437
+ "TRACE": 0,
6438
+ "DEBUG": 1,
6439
+ "INFO": 2,
6440
+ "WARN": 3,
6441
+ "ERROR": 4,
6442
+ "SILENT": 5
6443
+ };
6444
+ self.methodFactory = factory || defaultMethodFactory;
6445
+ self.getLevel = function () {
6446
+ if (userLevel != null) {
6447
+ return userLevel;
6448
+ } else if (defaultLevel != null) {
6449
+ return defaultLevel;
6450
+ } else {
6451
+ return inheritedLevel;
6452
+ }
6453
+ };
6454
+ self.setLevel = function (level, persist) {
6455
+ userLevel = normalizeLevel(level);
6456
+ if (persist !== false) {
6457
+ // defaults to true
6458
+ persistLevelIfPossible(userLevel);
6459
+ }
6460
+
6461
+ // NOTE: in v2, this should call rebuild(), which updates children.
6462
+ return replaceLoggingMethods.call(self);
6463
+ };
6464
+ self.setDefaultLevel = function (level) {
6465
+ defaultLevel = normalizeLevel(level);
6466
+ if (!getPersistedLevel()) {
6467
+ self.setLevel(level, false);
6468
+ }
6469
+ };
6470
+ self.resetLevel = function () {
6471
+ userLevel = null;
6472
+ clearPersistedLevel();
6473
+ replaceLoggingMethods.call(self);
6474
+ };
6475
+ self.enableAll = function (persist) {
6476
+ self.setLevel(self.levels.TRACE, persist);
6477
+ };
6478
+ self.disableAll = function (persist) {
6479
+ self.setLevel(self.levels.SILENT, persist);
6480
+ };
6481
+ self.rebuild = function () {
6482
+ if (defaultLogger !== self) {
6483
+ inheritedLevel = normalizeLevel(defaultLogger.getLevel());
6484
+ }
6485
+ replaceLoggingMethods.call(self);
6486
+ if (defaultLogger === self) {
6487
+ for (var childName in _loggersByName) {
6488
+ _loggersByName[childName].rebuild();
6489
+ }
6490
+ }
6491
+ };
6492
+
6493
+ // Initialize all the internal levels.
6494
+ inheritedLevel = normalizeLevel(defaultLogger ? defaultLogger.getLevel() : "WARN");
6495
+ var initialLevel = getPersistedLevel();
6496
+ if (initialLevel != null) {
6497
+ userLevel = normalizeLevel(initialLevel);
6498
+ }
6499
+ replaceLoggingMethods.call(self);
6309
6500
  }
6310
6501
 
6311
6502
  /*
6312
6503
  *
6313
- * Public logger API - see https://github.com/pimterry/loglevel for details
6504
+ * Top-level API
6314
6505
  *
6315
6506
  */
6316
6507
 
6317
- self.name = name;
6318
- self.levels = {
6319
- "TRACE": 0,
6320
- "DEBUG": 1,
6321
- "INFO": 2,
6322
- "WARN": 3,
6323
- "ERROR": 4,
6324
- "SILENT": 5
6325
- };
6326
- self.methodFactory = factory || defaultMethodFactory;
6327
- self.getLevel = function () {
6328
- if (userLevel != null) {
6329
- return userLevel;
6330
- } else if (defaultLevel != null) {
6331
- return defaultLevel;
6332
- } else {
6333
- return inheritedLevel;
6508
+ defaultLogger = new Logger();
6509
+ defaultLogger.getLogger = function getLogger(name) {
6510
+ if (typeof name !== "symbol" && typeof name !== "string" || name === "") {
6511
+ throw new TypeError("You must supply a name when creating a logger.");
6334
6512
  }
6335
- };
6336
- self.setLevel = function (level, persist) {
6337
- userLevel = normalizeLevel(level);
6338
- if (persist !== false) {
6339
- // defaults to true
6340
- persistLevelIfPossible(userLevel);
6513
+ var logger = _loggersByName[name];
6514
+ if (!logger) {
6515
+ logger = _loggersByName[name] = new Logger(name, defaultLogger.methodFactory);
6341
6516
  }
6342
-
6343
- // NOTE: in v2, this should call rebuild(), which updates children.
6344
- return replaceLoggingMethods.call(self);
6517
+ return logger;
6345
6518
  };
6346
- self.setDefaultLevel = function (level) {
6347
- defaultLevel = normalizeLevel(level);
6348
- if (!getPersistedLevel()) {
6349
- self.setLevel(level, false);
6519
+
6520
+ // Grab the current global log variable in case of overwrite
6521
+ var _log = typeof window !== undefinedType ? window.log : undefined;
6522
+ defaultLogger.noConflict = function () {
6523
+ if (typeof window !== undefinedType && window.log === defaultLogger) {
6524
+ window.log = _log;
6350
6525
  }
6526
+ return defaultLogger;
6351
6527
  };
6352
- self.resetLevel = function () {
6353
- userLevel = null;
6354
- clearPersistedLevel();
6355
- replaceLoggingMethods.call(self);
6356
- };
6357
- self.enableAll = function (persist) {
6358
- self.setLevel(self.levels.TRACE, persist);
6528
+ defaultLogger.getLoggers = function getLoggers() {
6529
+ return _loggersByName;
6359
6530
  };
6360
- self.disableAll = function (persist) {
6361
- self.setLevel(self.levels.SILENT, persist);
6362
- };
6363
- self.rebuild = function () {
6364
- if (defaultLogger !== self) {
6365
- inheritedLevel = normalizeLevel(defaultLogger.getLevel());
6366
- }
6367
- replaceLoggingMethods.call(self);
6368
- if (defaultLogger === self) {
6369
- for (var childName in _loggersByName) {
6370
- _loggersByName[childName].rebuild();
6371
- }
6372
- }
6373
- };
6374
-
6375
- // Initialize all the internal levels.
6376
- inheritedLevel = normalizeLevel(defaultLogger ? defaultLogger.getLevel() : "WARN");
6377
- var initialLevel = getPersistedLevel();
6378
- if (initialLevel != null) {
6379
- userLevel = normalizeLevel(initialLevel);
6380
- }
6381
- replaceLoggingMethods.call(self);
6382
- }
6383
-
6384
- /*
6385
- *
6386
- * Top-level API
6387
- *
6388
- */
6389
-
6390
- defaultLogger = new Logger();
6391
- defaultLogger.getLogger = function getLogger(name) {
6392
- if (typeof name !== "symbol" && typeof name !== "string" || name === "") {
6393
- throw new TypeError("You must supply a name when creating a logger.");
6394
- }
6395
- var logger = _loggersByName[name];
6396
- if (!logger) {
6397
- logger = _loggersByName[name] = new Logger(name, defaultLogger.methodFactory);
6398
- }
6399
- return logger;
6400
- };
6401
6531
 
6402
- // Grab the current global log variable in case of overwrite
6403
- var _log = typeof window !== undefinedType ? window.log : undefined;
6404
- defaultLogger.noConflict = function () {
6405
- if (typeof window !== undefinedType && window.log === defaultLogger) {
6406
- window.log = _log;
6407
- }
6532
+ // ES6 default export, for compatibility
6533
+ defaultLogger['default'] = defaultLogger;
6408
6534
  return defaultLogger;
6409
- };
6410
- defaultLogger.getLoggers = function getLoggers() {
6411
- return _loggersByName;
6412
- };
6535
+ });
6536
+ })(loglevel$1);
6537
+ return loglevel$1.exports;
6538
+ }
6413
6539
 
6414
- // ES6 default export, for compatibility
6415
- defaultLogger['default'] = defaultLogger;
6416
- return defaultLogger;
6417
- });
6418
- })(loglevel);
6419
- var loglevelExports = loglevel.exports;
6540
+ var loglevelExports = requireLoglevel();
6420
6541
 
6421
6542
  var LogLevel;
6422
6543
  (function (LogLevel) {
@@ -6552,383 +6673,390 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
6552
6673
 
6553
6674
  var events = {exports: {}};
6554
6675
 
6555
- var R = typeof Reflect === 'object' ? Reflect : null;
6556
- var ReflectApply = R && typeof R.apply === 'function' ? R.apply : function ReflectApply(target, receiver, args) {
6557
- return Function.prototype.apply.call(target, receiver, args);
6558
- };
6559
- var ReflectOwnKeys;
6560
- if (R && typeof R.ownKeys === 'function') {
6561
- ReflectOwnKeys = R.ownKeys;
6562
- } else if (Object.getOwnPropertySymbols) {
6563
- ReflectOwnKeys = function ReflectOwnKeys(target) {
6564
- return Object.getOwnPropertyNames(target).concat(Object.getOwnPropertySymbols(target));
6676
+ var hasRequiredEvents;
6677
+ function requireEvents() {
6678
+ if (hasRequiredEvents) return events.exports;
6679
+ hasRequiredEvents = 1;
6680
+ var R = typeof Reflect === 'object' ? Reflect : null;
6681
+ var ReflectApply = R && typeof R.apply === 'function' ? R.apply : function ReflectApply(target, receiver, args) {
6682
+ return Function.prototype.apply.call(target, receiver, args);
6565
6683
  };
6566
- } else {
6567
- ReflectOwnKeys = function ReflectOwnKeys(target) {
6568
- return Object.getOwnPropertyNames(target);
6569
- };
6570
- }
6571
- function ProcessEmitWarning(warning) {
6572
- if (console && console.warn) console.warn(warning);
6573
- }
6574
- var NumberIsNaN = Number.isNaN || function NumberIsNaN(value) {
6575
- return value !== value;
6576
- };
6577
- function EventEmitter() {
6578
- EventEmitter.init.call(this);
6579
- }
6580
- events.exports = EventEmitter;
6581
- events.exports.once = once;
6582
-
6583
- // Backwards-compat with node 0.10.x
6584
- EventEmitter.EventEmitter = EventEmitter;
6585
- EventEmitter.prototype._events = undefined;
6586
- EventEmitter.prototype._eventsCount = 0;
6587
- EventEmitter.prototype._maxListeners = undefined;
6588
-
6589
- // By default EventEmitters will print a warning if more than 10 listeners are
6590
- // added to it. This is a useful default which helps finding memory leaks.
6591
- var defaultMaxListeners = 10;
6592
- function checkListener(listener) {
6593
- if (typeof listener !== 'function') {
6594
- throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener);
6595
- }
6596
- }
6597
- Object.defineProperty(EventEmitter, 'defaultMaxListeners', {
6598
- enumerable: true,
6599
- get: function () {
6600
- return defaultMaxListeners;
6601
- },
6602
- set: function (arg) {
6603
- if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) {
6604
- throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + arg + '.');
6605
- }
6606
- defaultMaxListeners = arg;
6684
+ var ReflectOwnKeys;
6685
+ if (R && typeof R.ownKeys === 'function') {
6686
+ ReflectOwnKeys = R.ownKeys;
6687
+ } else if (Object.getOwnPropertySymbols) {
6688
+ ReflectOwnKeys = function ReflectOwnKeys(target) {
6689
+ return Object.getOwnPropertyNames(target).concat(Object.getOwnPropertySymbols(target));
6690
+ };
6691
+ } else {
6692
+ ReflectOwnKeys = function ReflectOwnKeys(target) {
6693
+ return Object.getOwnPropertyNames(target);
6694
+ };
6607
6695
  }
6608
- });
6609
- EventEmitter.init = function () {
6610
- if (this._events === undefined || this._events === Object.getPrototypeOf(this)._events) {
6611
- this._events = Object.create(null);
6612
- this._eventsCount = 0;
6696
+ function ProcessEmitWarning(warning) {
6697
+ if (console && console.warn) console.warn(warning);
6613
6698
  }
6614
- this._maxListeners = this._maxListeners || undefined;
6615
- };
6616
-
6617
- // Obviously not all Emitters should be limited to 10. This function allows
6618
- // that to be increased. Set to zero for unlimited.
6619
- EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {
6620
- if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) {
6621
- throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received ' + n + '.');
6699
+ var NumberIsNaN = Number.isNaN || function NumberIsNaN(value) {
6700
+ return value !== value;
6701
+ };
6702
+ function EventEmitter() {
6703
+ EventEmitter.init.call(this);
6622
6704
  }
6623
- this._maxListeners = n;
6624
- return this;
6625
- };
6626
- function _getMaxListeners(that) {
6627
- if (that._maxListeners === undefined) return EventEmitter.defaultMaxListeners;
6628
- return that._maxListeners;
6629
- }
6630
- EventEmitter.prototype.getMaxListeners = function getMaxListeners() {
6631
- return _getMaxListeners(this);
6632
- };
6633
- EventEmitter.prototype.emit = function emit(type) {
6634
- var args = [];
6635
- for (var i = 1; i < arguments.length; i++) args.push(arguments[i]);
6636
- var doError = type === 'error';
6637
- var events = this._events;
6638
- if (events !== undefined) doError = doError && events.error === undefined;else if (!doError) return false;
6639
-
6640
- // If there is no 'error' event listener then throw.
6641
- if (doError) {
6642
- var er;
6643
- if (args.length > 0) er = args[0];
6644
- if (er instanceof Error) {
6645
- // Note: The comments on the `throw` lines are intentional, they show
6646
- // up in Node's output if this results in an unhandled exception.
6647
- throw er; // Unhandled 'error' event
6648
- }
6649
- // At least give some kind of context to the user
6650
- var err = new Error('Unhandled error.' + (er ? ' (' + er.message + ')' : ''));
6651
- err.context = er;
6652
- throw err; // Unhandled 'error' event
6653
- }
6654
- var handler = events[type];
6655
- if (handler === undefined) return false;
6656
- if (typeof handler === 'function') {
6657
- ReflectApply(handler, this, args);
6658
- } else {
6659
- var len = handler.length;
6660
- var listeners = arrayClone(handler, len);
6661
- for (var i = 0; i < len; ++i) ReflectApply(listeners[i], this, args);
6705
+ events.exports = EventEmitter;
6706
+ events.exports.once = once;
6707
+
6708
+ // Backwards-compat with node 0.10.x
6709
+ EventEmitter.EventEmitter = EventEmitter;
6710
+ EventEmitter.prototype._events = undefined;
6711
+ EventEmitter.prototype._eventsCount = 0;
6712
+ EventEmitter.prototype._maxListeners = undefined;
6713
+
6714
+ // By default EventEmitters will print a warning if more than 10 listeners are
6715
+ // added to it. This is a useful default which helps finding memory leaks.
6716
+ var defaultMaxListeners = 10;
6717
+ function checkListener(listener) {
6718
+ if (typeof listener !== 'function') {
6719
+ throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener);
6720
+ }
6662
6721
  }
6663
- return true;
6664
- };
6665
- function _addListener(target, type, listener, prepend) {
6666
- var m;
6667
- var events;
6668
- var existing;
6669
- checkListener(listener);
6670
- events = target._events;
6671
- if (events === undefined) {
6672
- events = target._events = Object.create(null);
6673
- target._eventsCount = 0;
6674
- } else {
6675
- // To avoid recursion in the case that type === "newListener"! Before
6676
- // adding it to the listeners, first emit "newListener".
6677
- if (events.newListener !== undefined) {
6678
- target.emit('newListener', type, listener.listener ? listener.listener : listener);
6722
+ Object.defineProperty(EventEmitter, 'defaultMaxListeners', {
6723
+ enumerable: true,
6724
+ get: function () {
6725
+ return defaultMaxListeners;
6726
+ },
6727
+ set: function (arg) {
6728
+ if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) {
6729
+ throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + arg + '.');
6730
+ }
6731
+ defaultMaxListeners = arg;
6732
+ }
6733
+ });
6734
+ EventEmitter.init = function () {
6735
+ if (this._events === undefined || this._events === Object.getPrototypeOf(this)._events) {
6736
+ this._events = Object.create(null);
6737
+ this._eventsCount = 0;
6738
+ }
6739
+ this._maxListeners = this._maxListeners || undefined;
6740
+ };
6679
6741
 
6680
- // Re-assign `events` because a newListener handler could have caused the
6681
- // this._events to be assigned to a new object
6682
- events = target._events;
6742
+ // Obviously not all Emitters should be limited to 10. This function allows
6743
+ // that to be increased. Set to zero for unlimited.
6744
+ EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {
6745
+ if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) {
6746
+ throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received ' + n + '.');
6683
6747
  }
6684
- existing = events[type];
6748
+ this._maxListeners = n;
6749
+ return this;
6750
+ };
6751
+ function _getMaxListeners(that) {
6752
+ if (that._maxListeners === undefined) return EventEmitter.defaultMaxListeners;
6753
+ return that._maxListeners;
6685
6754
  }
6686
- if (existing === undefined) {
6687
- // Optimize the case of one listener. Don't need the extra array object.
6688
- existing = events[type] = listener;
6689
- ++target._eventsCount;
6690
- } else {
6691
- if (typeof existing === 'function') {
6692
- // Adding the second element, need to change to array.
6693
- existing = events[type] = prepend ? [listener, existing] : [existing, listener];
6694
- // If we've already got an array, just append.
6695
- } else if (prepend) {
6696
- existing.unshift(listener);
6755
+ EventEmitter.prototype.getMaxListeners = function getMaxListeners() {
6756
+ return _getMaxListeners(this);
6757
+ };
6758
+ EventEmitter.prototype.emit = function emit(type) {
6759
+ var args = [];
6760
+ for (var i = 1; i < arguments.length; i++) args.push(arguments[i]);
6761
+ var doError = type === 'error';
6762
+ var events = this._events;
6763
+ if (events !== undefined) doError = doError && events.error === undefined;else if (!doError) return false;
6764
+
6765
+ // If there is no 'error' event listener then throw.
6766
+ if (doError) {
6767
+ var er;
6768
+ if (args.length > 0) er = args[0];
6769
+ if (er instanceof Error) {
6770
+ // Note: The comments on the `throw` lines are intentional, they show
6771
+ // up in Node's output if this results in an unhandled exception.
6772
+ throw er; // Unhandled 'error' event
6773
+ }
6774
+ // At least give some kind of context to the user
6775
+ var err = new Error('Unhandled error.' + (er ? ' (' + er.message + ')' : ''));
6776
+ err.context = er;
6777
+ throw err; // Unhandled 'error' event
6778
+ }
6779
+ var handler = events[type];
6780
+ if (handler === undefined) return false;
6781
+ if (typeof handler === 'function') {
6782
+ ReflectApply(handler, this, args);
6697
6783
  } else {
6698
- existing.push(listener);
6784
+ var len = handler.length;
6785
+ var listeners = arrayClone(handler, len);
6786
+ for (var i = 0; i < len; ++i) ReflectApply(listeners[i], this, args);
6787
+ }
6788
+ return true;
6789
+ };
6790
+ function _addListener(target, type, listener, prepend) {
6791
+ var m;
6792
+ var events;
6793
+ var existing;
6794
+ checkListener(listener);
6795
+ events = target._events;
6796
+ if (events === undefined) {
6797
+ events = target._events = Object.create(null);
6798
+ target._eventsCount = 0;
6799
+ } else {
6800
+ // To avoid recursion in the case that type === "newListener"! Before
6801
+ // adding it to the listeners, first emit "newListener".
6802
+ if (events.newListener !== undefined) {
6803
+ target.emit('newListener', type, listener.listener ? listener.listener : listener);
6804
+
6805
+ // Re-assign `events` because a newListener handler could have caused the
6806
+ // this._events to be assigned to a new object
6807
+ events = target._events;
6808
+ }
6809
+ existing = events[type];
6699
6810
  }
6811
+ if (existing === undefined) {
6812
+ // Optimize the case of one listener. Don't need the extra array object.
6813
+ existing = events[type] = listener;
6814
+ ++target._eventsCount;
6815
+ } else {
6816
+ if (typeof existing === 'function') {
6817
+ // Adding the second element, need to change to array.
6818
+ existing = events[type] = prepend ? [listener, existing] : [existing, listener];
6819
+ // If we've already got an array, just append.
6820
+ } else if (prepend) {
6821
+ existing.unshift(listener);
6822
+ } else {
6823
+ existing.push(listener);
6824
+ }
6700
6825
 
6701
- // Check for listener leak
6702
- m = _getMaxListeners(target);
6703
- if (m > 0 && existing.length > m && !existing.warned) {
6704
- existing.warned = true;
6705
- // No error code for this since it is a Warning
6706
- // eslint-disable-next-line no-restricted-syntax
6707
- var w = new Error('Possible EventEmitter memory leak detected. ' + existing.length + ' ' + String(type) + ' listeners ' + 'added. Use emitter.setMaxListeners() to ' + 'increase limit');
6708
- w.name = 'MaxListenersExceededWarning';
6709
- w.emitter = target;
6710
- w.type = type;
6711
- w.count = existing.length;
6712
- ProcessEmitWarning(w);
6826
+ // Check for listener leak
6827
+ m = _getMaxListeners(target);
6828
+ if (m > 0 && existing.length > m && !existing.warned) {
6829
+ existing.warned = true;
6830
+ // No error code for this since it is a Warning
6831
+ // eslint-disable-next-line no-restricted-syntax
6832
+ var w = new Error('Possible EventEmitter memory leak detected. ' + existing.length + ' ' + String(type) + ' listeners ' + 'added. Use emitter.setMaxListeners() to ' + 'increase limit');
6833
+ w.name = 'MaxListenersExceededWarning';
6834
+ w.emitter = target;
6835
+ w.type = type;
6836
+ w.count = existing.length;
6837
+ ProcessEmitWarning(w);
6838
+ }
6713
6839
  }
6840
+ return target;
6714
6841
  }
6715
- return target;
6716
- }
6717
- EventEmitter.prototype.addListener = function addListener(type, listener) {
6718
- return _addListener(this, type, listener, false);
6719
- };
6720
- EventEmitter.prototype.on = EventEmitter.prototype.addListener;
6721
- EventEmitter.prototype.prependListener = function prependListener(type, listener) {
6722
- return _addListener(this, type, listener, true);
6723
- };
6724
- function onceWrapper() {
6725
- if (!this.fired) {
6726
- this.target.removeListener(this.type, this.wrapFn);
6727
- this.fired = true;
6728
- if (arguments.length === 0) return this.listener.call(this.target);
6729
- return this.listener.apply(this.target, arguments);
6730
- }
6731
- }
6732
- function _onceWrap(target, type, listener) {
6733
- var state = {
6734
- fired: false,
6735
- wrapFn: undefined,
6736
- target: target,
6737
- type: type,
6738
- listener: listener
6842
+ EventEmitter.prototype.addListener = function addListener(type, listener) {
6843
+ return _addListener(this, type, listener, false);
6844
+ };
6845
+ EventEmitter.prototype.on = EventEmitter.prototype.addListener;
6846
+ EventEmitter.prototype.prependListener = function prependListener(type, listener) {
6847
+ return _addListener(this, type, listener, true);
6848
+ };
6849
+ function onceWrapper() {
6850
+ if (!this.fired) {
6851
+ this.target.removeListener(this.type, this.wrapFn);
6852
+ this.fired = true;
6853
+ if (arguments.length === 0) return this.listener.call(this.target);
6854
+ return this.listener.apply(this.target, arguments);
6855
+ }
6856
+ }
6857
+ function _onceWrap(target, type, listener) {
6858
+ var state = {
6859
+ fired: false,
6860
+ wrapFn: undefined,
6861
+ target: target,
6862
+ type: type,
6863
+ listener: listener
6864
+ };
6865
+ var wrapped = onceWrapper.bind(state);
6866
+ wrapped.listener = listener;
6867
+ state.wrapFn = wrapped;
6868
+ return wrapped;
6869
+ }
6870
+ EventEmitter.prototype.once = function once(type, listener) {
6871
+ checkListener(listener);
6872
+ this.on(type, _onceWrap(this, type, listener));
6873
+ return this;
6874
+ };
6875
+ EventEmitter.prototype.prependOnceListener = function prependOnceListener(type, listener) {
6876
+ checkListener(listener);
6877
+ this.prependListener(type, _onceWrap(this, type, listener));
6878
+ return this;
6739
6879
  };
6740
- var wrapped = onceWrapper.bind(state);
6741
- wrapped.listener = listener;
6742
- state.wrapFn = wrapped;
6743
- return wrapped;
6744
- }
6745
- EventEmitter.prototype.once = function once(type, listener) {
6746
- checkListener(listener);
6747
- this.on(type, _onceWrap(this, type, listener));
6748
- return this;
6749
- };
6750
- EventEmitter.prototype.prependOnceListener = function prependOnceListener(type, listener) {
6751
- checkListener(listener);
6752
- this.prependListener(type, _onceWrap(this, type, listener));
6753
- return this;
6754
- };
6755
6880
 
6756
- // Emits a 'removeListener' event if and only if the listener was removed.
6757
- EventEmitter.prototype.removeListener = function removeListener(type, listener) {
6758
- var list, events, position, i, originalListener;
6759
- checkListener(listener);
6760
- events = this._events;
6761
- if (events === undefined) return this;
6762
- list = events[type];
6763
- if (list === undefined) return this;
6764
- if (list === listener || list.listener === listener) {
6765
- if (--this._eventsCount === 0) this._events = Object.create(null);else {
6766
- delete events[type];
6767
- if (events.removeListener) this.emit('removeListener', type, list.listener || listener);
6768
- }
6769
- } else if (typeof list !== 'function') {
6770
- position = -1;
6771
- for (i = list.length - 1; i >= 0; i--) {
6772
- if (list[i] === listener || list[i].listener === listener) {
6773
- originalListener = list[i].listener;
6774
- position = i;
6775
- break;
6881
+ // Emits a 'removeListener' event if and only if the listener was removed.
6882
+ EventEmitter.prototype.removeListener = function removeListener(type, listener) {
6883
+ var list, events, position, i, originalListener;
6884
+ checkListener(listener);
6885
+ events = this._events;
6886
+ if (events === undefined) return this;
6887
+ list = events[type];
6888
+ if (list === undefined) return this;
6889
+ if (list === listener || list.listener === listener) {
6890
+ if (--this._eventsCount === 0) this._events = Object.create(null);else {
6891
+ delete events[type];
6892
+ if (events.removeListener) this.emit('removeListener', type, list.listener || listener);
6893
+ }
6894
+ } else if (typeof list !== 'function') {
6895
+ position = -1;
6896
+ for (i = list.length - 1; i >= 0; i--) {
6897
+ if (list[i] === listener || list[i].listener === listener) {
6898
+ originalListener = list[i].listener;
6899
+ position = i;
6900
+ break;
6901
+ }
6902
+ }
6903
+ if (position < 0) return this;
6904
+ if (position === 0) list.shift();else {
6905
+ spliceOne(list, position);
6776
6906
  }
6907
+ if (list.length === 1) events[type] = list[0];
6908
+ if (events.removeListener !== undefined) this.emit('removeListener', type, originalListener || listener);
6777
6909
  }
6778
- if (position < 0) return this;
6779
- if (position === 0) list.shift();else {
6780
- spliceOne(list, position);
6910
+ return this;
6911
+ };
6912
+ EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
6913
+ EventEmitter.prototype.removeAllListeners = function removeAllListeners(type) {
6914
+ var listeners, events, i;
6915
+ events = this._events;
6916
+ if (events === undefined) return this;
6917
+
6918
+ // not listening for removeListener, no need to emit
6919
+ if (events.removeListener === undefined) {
6920
+ if (arguments.length === 0) {
6921
+ this._events = Object.create(null);
6922
+ this._eventsCount = 0;
6923
+ } else if (events[type] !== undefined) {
6924
+ if (--this._eventsCount === 0) this._events = Object.create(null);else delete events[type];
6925
+ }
6926
+ return this;
6781
6927
  }
6782
- if (list.length === 1) events[type] = list[0];
6783
- if (events.removeListener !== undefined) this.emit('removeListener', type, originalListener || listener);
6784
- }
6785
- return this;
6786
- };
6787
- EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
6788
- EventEmitter.prototype.removeAllListeners = function removeAllListeners(type) {
6789
- var listeners, events, i;
6790
- events = this._events;
6791
- if (events === undefined) return this;
6792
-
6793
- // not listening for removeListener, no need to emit
6794
- if (events.removeListener === undefined) {
6928
+
6929
+ // emit removeListener for all listeners on all events
6795
6930
  if (arguments.length === 0) {
6931
+ var keys = Object.keys(events);
6932
+ var key;
6933
+ for (i = 0; i < keys.length; ++i) {
6934
+ key = keys[i];
6935
+ if (key === 'removeListener') continue;
6936
+ this.removeAllListeners(key);
6937
+ }
6938
+ this.removeAllListeners('removeListener');
6796
6939
  this._events = Object.create(null);
6797
6940
  this._eventsCount = 0;
6798
- } else if (events[type] !== undefined) {
6799
- if (--this._eventsCount === 0) this._events = Object.create(null);else delete events[type];
6941
+ return this;
6800
6942
  }
6801
- return this;
6802
- }
6803
-
6804
- // emit removeListener for all listeners on all events
6805
- if (arguments.length === 0) {
6806
- var keys = Object.keys(events);
6807
- var key;
6808
- for (i = 0; i < keys.length; ++i) {
6809
- key = keys[i];
6810
- if (key === 'removeListener') continue;
6811
- this.removeAllListeners(key);
6943
+ listeners = events[type];
6944
+ if (typeof listeners === 'function') {
6945
+ this.removeListener(type, listeners);
6946
+ } else if (listeners !== undefined) {
6947
+ // LIFO order
6948
+ for (i = listeners.length - 1; i >= 0; i--) {
6949
+ this.removeListener(type, listeners[i]);
6950
+ }
6812
6951
  }
6813
- this.removeAllListeners('removeListener');
6814
- this._events = Object.create(null);
6815
- this._eventsCount = 0;
6816
6952
  return this;
6953
+ };
6954
+ function _listeners(target, type, unwrap) {
6955
+ var events = target._events;
6956
+ if (events === undefined) return [];
6957
+ var evlistener = events[type];
6958
+ if (evlistener === undefined) return [];
6959
+ if (typeof evlistener === 'function') return unwrap ? [evlistener.listener || evlistener] : [evlistener];
6960
+ return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);
6817
6961
  }
6818
- listeners = events[type];
6819
- if (typeof listeners === 'function') {
6820
- this.removeListener(type, listeners);
6821
- } else if (listeners !== undefined) {
6822
- // LIFO order
6823
- for (i = listeners.length - 1; i >= 0; i--) {
6824
- this.removeListener(type, listeners[i]);
6962
+ EventEmitter.prototype.listeners = function listeners(type) {
6963
+ return _listeners(this, type, true);
6964
+ };
6965
+ EventEmitter.prototype.rawListeners = function rawListeners(type) {
6966
+ return _listeners(this, type, false);
6967
+ };
6968
+ EventEmitter.listenerCount = function (emitter, type) {
6969
+ if (typeof emitter.listenerCount === 'function') {
6970
+ return emitter.listenerCount(type);
6971
+ } else {
6972
+ return listenerCount.call(emitter, type);
6825
6973
  }
6826
- }
6827
- return this;
6828
- };
6829
- function _listeners(target, type, unwrap) {
6830
- var events = target._events;
6831
- if (events === undefined) return [];
6832
- var evlistener = events[type];
6833
- if (evlistener === undefined) return [];
6834
- if (typeof evlistener === 'function') return unwrap ? [evlistener.listener || evlistener] : [evlistener];
6835
- return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);
6836
- }
6837
- EventEmitter.prototype.listeners = function listeners(type) {
6838
- return _listeners(this, type, true);
6839
- };
6840
- EventEmitter.prototype.rawListeners = function rawListeners(type) {
6841
- return _listeners(this, type, false);
6842
- };
6843
- EventEmitter.listenerCount = function (emitter, type) {
6844
- if (typeof emitter.listenerCount === 'function') {
6845
- return emitter.listenerCount(type);
6846
- } else {
6847
- return listenerCount.call(emitter, type);
6848
- }
6849
- };
6850
- EventEmitter.prototype.listenerCount = listenerCount;
6851
- function listenerCount(type) {
6852
- var events = this._events;
6853
- if (events !== undefined) {
6854
- var evlistener = events[type];
6855
- if (typeof evlistener === 'function') {
6856
- return 1;
6857
- } else if (evlistener !== undefined) {
6858
- return evlistener.length;
6974
+ };
6975
+ EventEmitter.prototype.listenerCount = listenerCount;
6976
+ function listenerCount(type) {
6977
+ var events = this._events;
6978
+ if (events !== undefined) {
6979
+ var evlistener = events[type];
6980
+ if (typeof evlistener === 'function') {
6981
+ return 1;
6982
+ } else if (evlistener !== undefined) {
6983
+ return evlistener.length;
6984
+ }
6859
6985
  }
6986
+ return 0;
6860
6987
  }
6861
- return 0;
6862
- }
6863
- EventEmitter.prototype.eventNames = function eventNames() {
6864
- return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : [];
6865
- };
6866
- function arrayClone(arr, n) {
6867
- var copy = new Array(n);
6868
- for (var i = 0; i < n; ++i) copy[i] = arr[i];
6869
- return copy;
6870
- }
6871
- function spliceOne(list, index) {
6872
- for (; index + 1 < list.length; index++) list[index] = list[index + 1];
6873
- list.pop();
6874
- }
6875
- function unwrapListeners(arr) {
6876
- var ret = new Array(arr.length);
6877
- for (var i = 0; i < ret.length; ++i) {
6878
- ret[i] = arr[i].listener || arr[i];
6988
+ EventEmitter.prototype.eventNames = function eventNames() {
6989
+ return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : [];
6990
+ };
6991
+ function arrayClone(arr, n) {
6992
+ var copy = new Array(n);
6993
+ for (var i = 0; i < n; ++i) copy[i] = arr[i];
6994
+ return copy;
6879
6995
  }
6880
- return ret;
6881
- }
6882
- function once(emitter, name) {
6883
- return new Promise(function (resolve, reject) {
6884
- function errorListener(err) {
6885
- emitter.removeListener(name, resolver);
6886
- reject(err);
6996
+ function spliceOne(list, index) {
6997
+ for (; index + 1 < list.length; index++) list[index] = list[index + 1];
6998
+ list.pop();
6999
+ }
7000
+ function unwrapListeners(arr) {
7001
+ var ret = new Array(arr.length);
7002
+ for (var i = 0; i < ret.length; ++i) {
7003
+ ret[i] = arr[i].listener || arr[i];
6887
7004
  }
6888
- function resolver() {
6889
- if (typeof emitter.removeListener === 'function') {
6890
- emitter.removeListener('error', errorListener);
7005
+ return ret;
7006
+ }
7007
+ function once(emitter, name) {
7008
+ return new Promise(function (resolve, reject) {
7009
+ function errorListener(err) {
7010
+ emitter.removeListener(name, resolver);
7011
+ reject(err);
6891
7012
  }
6892
- resolve([].slice.call(arguments));
6893
- }
6894
- eventTargetAgnosticAddListener(emitter, name, resolver, {
6895
- once: true
6896
- });
6897
- if (name !== 'error') {
6898
- addErrorHandlerIfEventEmitter(emitter, errorListener, {
7013
+ function resolver() {
7014
+ if (typeof emitter.removeListener === 'function') {
7015
+ emitter.removeListener('error', errorListener);
7016
+ }
7017
+ resolve([].slice.call(arguments));
7018
+ }
7019
+ eventTargetAgnosticAddListener(emitter, name, resolver, {
6899
7020
  once: true
6900
7021
  });
7022
+ if (name !== 'error') {
7023
+ addErrorHandlerIfEventEmitter(emitter, errorListener, {
7024
+ once: true
7025
+ });
7026
+ }
7027
+ });
7028
+ }
7029
+ function addErrorHandlerIfEventEmitter(emitter, handler, flags) {
7030
+ if (typeof emitter.on === 'function') {
7031
+ eventTargetAgnosticAddListener(emitter, 'error', handler, flags);
6901
7032
  }
6902
- });
6903
- }
6904
- function addErrorHandlerIfEventEmitter(emitter, handler, flags) {
6905
- if (typeof emitter.on === 'function') {
6906
- eventTargetAgnosticAddListener(emitter, 'error', handler, flags);
6907
7033
  }
6908
- }
6909
- function eventTargetAgnosticAddListener(emitter, name, listener, flags) {
6910
- if (typeof emitter.on === 'function') {
6911
- if (flags.once) {
6912
- emitter.once(name, listener);
6913
- } else {
6914
- emitter.on(name, listener);
6915
- }
6916
- } else if (typeof emitter.addEventListener === 'function') {
6917
- // EventTarget does not have `error` event semantics like Node
6918
- // EventEmitters, we do not listen for `error` events here.
6919
- emitter.addEventListener(name, function wrapListener(arg) {
6920
- // IE does not have builtin `{ once: true }` support so we
6921
- // have to do it manually.
7034
+ function eventTargetAgnosticAddListener(emitter, name, listener, flags) {
7035
+ if (typeof emitter.on === 'function') {
6922
7036
  if (flags.once) {
6923
- emitter.removeEventListener(name, wrapListener);
6924
- }
6925
- listener(arg);
6926
- });
6927
- } else {
6928
- throw new TypeError('The "emitter" argument must be of type EventEmitter. Received type ' + typeof emitter);
7037
+ emitter.once(name, listener);
7038
+ } else {
7039
+ emitter.on(name, listener);
7040
+ }
7041
+ } else if (typeof emitter.addEventListener === 'function') {
7042
+ // EventTarget does not have `error` event semantics like Node
7043
+ // EventEmitters, we do not listen for `error` events here.
7044
+ emitter.addEventListener(name, function wrapListener(arg) {
7045
+ // IE does not have builtin `{ once: true }` support so we
7046
+ // have to do it manually.
7047
+ if (flags.once) {
7048
+ emitter.removeEventListener(name, wrapListener);
7049
+ }
7050
+ listener(arg);
7051
+ });
7052
+ } else {
7053
+ throw new TypeError('The "emitter" argument must be of type EventEmitter. Received type ' + typeof emitter);
7054
+ }
6929
7055
  }
7056
+ return events.exports;
6930
7057
  }
6931
- var eventsExports = events.exports;
7058
+
7059
+ var eventsExports = requireEvents();
6932
7060
 
6933
7061
  /*
6934
7062
  * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
@@ -8639,746 +8767,753 @@ var safariShim = /*#__PURE__*/Object.freeze({
8639
8767
  var sdp$1 = {exports: {}};
8640
8768
 
8641
8769
  /* eslint-env node */
8642
- (function (module) {
8643
-
8644
- // SDP helpers.
8645
- const SDPUtils = {};
8646
-
8647
- // Generate an alphanumeric identifier for cname or mids.
8648
- // TODO: use UUIDs instead? https://gist.github.com/jed/982883
8649
- SDPUtils.generateIdentifier = function () {
8650
- return Math.random().toString(36).substring(2, 12);
8651
- };
8652
-
8653
- // The RTCP CNAME used by all peerconnections from the same JS.
8654
- SDPUtils.localCName = SDPUtils.generateIdentifier();
8770
+ var hasRequiredSdp;
8771
+ function requireSdp() {
8772
+ if (hasRequiredSdp) return sdp$1.exports;
8773
+ hasRequiredSdp = 1;
8774
+ (function (module) {
8775
+
8776
+ // SDP helpers.
8777
+ const SDPUtils = {};
8778
+
8779
+ // Generate an alphanumeric identifier for cname or mids.
8780
+ // TODO: use UUIDs instead? https://gist.github.com/jed/982883
8781
+ SDPUtils.generateIdentifier = function () {
8782
+ return Math.random().toString(36).substring(2, 12);
8783
+ };
8655
8784
 
8656
- // Splits SDP into lines, dealing with both CRLF and LF.
8657
- SDPUtils.splitLines = function (blob) {
8658
- return blob.trim().split('\n').map(line => line.trim());
8659
- };
8660
- // Splits SDP into sessionpart and mediasections. Ensures CRLF.
8661
- SDPUtils.splitSections = function (blob) {
8662
- const parts = blob.split('\nm=');
8663
- return parts.map((part, index) => (index > 0 ? 'm=' + part : part).trim() + '\r\n');
8664
- };
8785
+ // The RTCP CNAME used by all peerconnections from the same JS.
8786
+ SDPUtils.localCName = SDPUtils.generateIdentifier();
8665
8787
 
8666
- // Returns the session description.
8667
- SDPUtils.getDescription = function (blob) {
8668
- const sections = SDPUtils.splitSections(blob);
8669
- return sections && sections[0];
8670
- };
8788
+ // Splits SDP into lines, dealing with both CRLF and LF.
8789
+ SDPUtils.splitLines = function (blob) {
8790
+ return blob.trim().split('\n').map(line => line.trim());
8791
+ };
8792
+ // Splits SDP into sessionpart and mediasections. Ensures CRLF.
8793
+ SDPUtils.splitSections = function (blob) {
8794
+ const parts = blob.split('\nm=');
8795
+ return parts.map((part, index) => (index > 0 ? 'm=' + part : part).trim() + '\r\n');
8796
+ };
8671
8797
 
8672
- // Returns the individual media sections.
8673
- SDPUtils.getMediaSections = function (blob) {
8674
- const sections = SDPUtils.splitSections(blob);
8675
- sections.shift();
8676
- return sections;
8677
- };
8798
+ // Returns the session description.
8799
+ SDPUtils.getDescription = function (blob) {
8800
+ const sections = SDPUtils.splitSections(blob);
8801
+ return sections && sections[0];
8802
+ };
8678
8803
 
8679
- // Returns lines that start with a certain prefix.
8680
- SDPUtils.matchPrefix = function (blob, prefix) {
8681
- return SDPUtils.splitLines(blob).filter(line => line.indexOf(prefix) === 0);
8682
- };
8804
+ // Returns the individual media sections.
8805
+ SDPUtils.getMediaSections = function (blob) {
8806
+ const sections = SDPUtils.splitSections(blob);
8807
+ sections.shift();
8808
+ return sections;
8809
+ };
8683
8810
 
8684
- // Parses an ICE candidate line. Sample input:
8685
- // candidate:702786350 2 udp 41819902 8.8.8.8 60769 typ relay raddr 8.8.8.8
8686
- // rport 55996"
8687
- // Input can be prefixed with a=.
8688
- SDPUtils.parseCandidate = function (line) {
8689
- let parts;
8690
- // Parse both variants.
8691
- if (line.indexOf('a=candidate:') === 0) {
8692
- parts = line.substring(12).split(' ');
8693
- } else {
8694
- parts = line.substring(10).split(' ');
8695
- }
8696
- const candidate = {
8697
- foundation: parts[0],
8698
- component: {
8699
- 1: 'rtp',
8700
- 2: 'rtcp'
8701
- }[parts[1]] || parts[1],
8702
- protocol: parts[2].toLowerCase(),
8703
- priority: parseInt(parts[3], 10),
8704
- ip: parts[4],
8705
- address: parts[4],
8706
- // address is an alias for ip.
8707
- port: parseInt(parts[5], 10),
8708
- // skip parts[6] == 'typ'
8709
- type: parts[7]
8811
+ // Returns lines that start with a certain prefix.
8812
+ SDPUtils.matchPrefix = function (blob, prefix) {
8813
+ return SDPUtils.splitLines(blob).filter(line => line.indexOf(prefix) === 0);
8710
8814
  };
8711
- for (let i = 8; i < parts.length; i += 2) {
8712
- switch (parts[i]) {
8713
- case 'raddr':
8714
- candidate.relatedAddress = parts[i + 1];
8715
- break;
8716
- case 'rport':
8717
- candidate.relatedPort = parseInt(parts[i + 1], 10);
8718
- break;
8719
- case 'tcptype':
8720
- candidate.tcpType = parts[i + 1];
8721
- break;
8722
- case 'ufrag':
8723
- candidate.ufrag = parts[i + 1]; // for backward compatibility.
8724
- candidate.usernameFragment = parts[i + 1];
8725
- break;
8726
- default:
8727
- // extension handling, in particular ufrag. Don't overwrite.
8728
- if (candidate[parts[i]] === undefined) {
8729
- candidate[parts[i]] = parts[i + 1];
8730
- }
8731
- break;
8732
- }
8733
- }
8734
- return candidate;
8735
- };
8736
8815
 
8737
- // Translates a candidate object into SDP candidate attribute.
8738
- // This does not include the a= prefix!
8739
- SDPUtils.writeCandidate = function (candidate) {
8740
- const sdp = [];
8741
- sdp.push(candidate.foundation);
8742
- const component = candidate.component;
8743
- if (component === 'rtp') {
8744
- sdp.push(1);
8745
- } else if (component === 'rtcp') {
8746
- sdp.push(2);
8747
- } else {
8748
- sdp.push(component);
8749
- }
8750
- sdp.push(candidate.protocol.toUpperCase());
8751
- sdp.push(candidate.priority);
8752
- sdp.push(candidate.address || candidate.ip);
8753
- sdp.push(candidate.port);
8754
- const type = candidate.type;
8755
- sdp.push('typ');
8756
- sdp.push(type);
8757
- if (type !== 'host' && candidate.relatedAddress && candidate.relatedPort) {
8758
- sdp.push('raddr');
8759
- sdp.push(candidate.relatedAddress);
8760
- sdp.push('rport');
8761
- sdp.push(candidate.relatedPort);
8762
- }
8763
- if (candidate.tcpType && candidate.protocol.toLowerCase() === 'tcp') {
8764
- sdp.push('tcptype');
8765
- sdp.push(candidate.tcpType);
8766
- }
8767
- if (candidate.usernameFragment || candidate.ufrag) {
8768
- sdp.push('ufrag');
8769
- sdp.push(candidate.usernameFragment || candidate.ufrag);
8770
- }
8771
- return 'candidate:' + sdp.join(' ');
8772
- };
8816
+ // Parses an ICE candidate line. Sample input:
8817
+ // candidate:702786350 2 udp 41819902 8.8.8.8 60769 typ relay raddr 8.8.8.8
8818
+ // rport 55996"
8819
+ // Input can be prefixed with a=.
8820
+ SDPUtils.parseCandidate = function (line) {
8821
+ let parts;
8822
+ // Parse both variants.
8823
+ if (line.indexOf('a=candidate:') === 0) {
8824
+ parts = line.substring(12).split(' ');
8825
+ } else {
8826
+ parts = line.substring(10).split(' ');
8827
+ }
8828
+ const candidate = {
8829
+ foundation: parts[0],
8830
+ component: {
8831
+ 1: 'rtp',
8832
+ 2: 'rtcp'
8833
+ }[parts[1]] || parts[1],
8834
+ protocol: parts[2].toLowerCase(),
8835
+ priority: parseInt(parts[3], 10),
8836
+ ip: parts[4],
8837
+ address: parts[4],
8838
+ // address is an alias for ip.
8839
+ port: parseInt(parts[5], 10),
8840
+ // skip parts[6] == 'typ'
8841
+ type: parts[7]
8842
+ };
8843
+ for (let i = 8; i < parts.length; i += 2) {
8844
+ switch (parts[i]) {
8845
+ case 'raddr':
8846
+ candidate.relatedAddress = parts[i + 1];
8847
+ break;
8848
+ case 'rport':
8849
+ candidate.relatedPort = parseInt(parts[i + 1], 10);
8850
+ break;
8851
+ case 'tcptype':
8852
+ candidate.tcpType = parts[i + 1];
8853
+ break;
8854
+ case 'ufrag':
8855
+ candidate.ufrag = parts[i + 1]; // for backward compatibility.
8856
+ candidate.usernameFragment = parts[i + 1];
8857
+ break;
8858
+ default:
8859
+ // extension handling, in particular ufrag. Don't overwrite.
8860
+ if (candidate[parts[i]] === undefined) {
8861
+ candidate[parts[i]] = parts[i + 1];
8862
+ }
8863
+ break;
8864
+ }
8865
+ }
8866
+ return candidate;
8867
+ };
8773
8868
 
8774
- // Parses an ice-options line, returns an array of option tags.
8775
- // Sample input:
8776
- // a=ice-options:foo bar
8777
- SDPUtils.parseIceOptions = function (line) {
8778
- return line.substring(14).split(' ');
8779
- };
8869
+ // Translates a candidate object into SDP candidate attribute.
8870
+ // This does not include the a= prefix!
8871
+ SDPUtils.writeCandidate = function (candidate) {
8872
+ const sdp = [];
8873
+ sdp.push(candidate.foundation);
8874
+ const component = candidate.component;
8875
+ if (component === 'rtp') {
8876
+ sdp.push(1);
8877
+ } else if (component === 'rtcp') {
8878
+ sdp.push(2);
8879
+ } else {
8880
+ sdp.push(component);
8881
+ }
8882
+ sdp.push(candidate.protocol.toUpperCase());
8883
+ sdp.push(candidate.priority);
8884
+ sdp.push(candidate.address || candidate.ip);
8885
+ sdp.push(candidate.port);
8886
+ const type = candidate.type;
8887
+ sdp.push('typ');
8888
+ sdp.push(type);
8889
+ if (type !== 'host' && candidate.relatedAddress && candidate.relatedPort) {
8890
+ sdp.push('raddr');
8891
+ sdp.push(candidate.relatedAddress);
8892
+ sdp.push('rport');
8893
+ sdp.push(candidate.relatedPort);
8894
+ }
8895
+ if (candidate.tcpType && candidate.protocol.toLowerCase() === 'tcp') {
8896
+ sdp.push('tcptype');
8897
+ sdp.push(candidate.tcpType);
8898
+ }
8899
+ if (candidate.usernameFragment || candidate.ufrag) {
8900
+ sdp.push('ufrag');
8901
+ sdp.push(candidate.usernameFragment || candidate.ufrag);
8902
+ }
8903
+ return 'candidate:' + sdp.join(' ');
8904
+ };
8780
8905
 
8781
- // Parses a rtpmap line, returns RTCRtpCoddecParameters. Sample input:
8782
- // a=rtpmap:111 opus/48000/2
8783
- SDPUtils.parseRtpMap = function (line) {
8784
- let parts = line.substring(9).split(' ');
8785
- const parsed = {
8786
- payloadType: parseInt(parts.shift(), 10) // was: id
8906
+ // Parses an ice-options line, returns an array of option tags.
8907
+ // Sample input:
8908
+ // a=ice-options:foo bar
8909
+ SDPUtils.parseIceOptions = function (line) {
8910
+ return line.substring(14).split(' ');
8787
8911
  };
8788
- parts = parts[0].split('/');
8789
- parsed.name = parts[0];
8790
- parsed.clockRate = parseInt(parts[1], 10); // was: clockrate
8791
- parsed.channels = parts.length === 3 ? parseInt(parts[2], 10) : 1;
8792
- // legacy alias, got renamed back to channels in ORTC.
8793
- parsed.numChannels = parsed.channels;
8794
- return parsed;
8795
- };
8796
8912
 
8797
- // Generates a rtpmap line from RTCRtpCodecCapability or
8798
- // RTCRtpCodecParameters.
8799
- SDPUtils.writeRtpMap = function (codec) {
8800
- let pt = codec.payloadType;
8801
- if (codec.preferredPayloadType !== undefined) {
8802
- pt = codec.preferredPayloadType;
8803
- }
8804
- const channels = codec.channels || codec.numChannels || 1;
8805
- return 'a=rtpmap:' + pt + ' ' + codec.name + '/' + codec.clockRate + (channels !== 1 ? '/' + channels : '') + '\r\n';
8806
- };
8913
+ // Parses a rtpmap line, returns RTCRtpCoddecParameters. Sample input:
8914
+ // a=rtpmap:111 opus/48000/2
8915
+ SDPUtils.parseRtpMap = function (line) {
8916
+ let parts = line.substring(9).split(' ');
8917
+ const parsed = {
8918
+ payloadType: parseInt(parts.shift(), 10) // was: id
8919
+ };
8920
+ parts = parts[0].split('/');
8921
+ parsed.name = parts[0];
8922
+ parsed.clockRate = parseInt(parts[1], 10); // was: clockrate
8923
+ parsed.channels = parts.length === 3 ? parseInt(parts[2], 10) : 1;
8924
+ // legacy alias, got renamed back to channels in ORTC.
8925
+ parsed.numChannels = parsed.channels;
8926
+ return parsed;
8927
+ };
8807
8928
 
8808
- // Parses a extmap line (headerextension from RFC 5285). Sample input:
8809
- // a=extmap:2 urn:ietf:params:rtp-hdrext:toffset
8810
- // a=extmap:2/sendonly urn:ietf:params:rtp-hdrext:toffset
8811
- SDPUtils.parseExtmap = function (line) {
8812
- const parts = line.substring(9).split(' ');
8813
- return {
8814
- id: parseInt(parts[0], 10),
8815
- direction: parts[0].indexOf('/') > 0 ? parts[0].split('/')[1] : 'sendrecv',
8816
- uri: parts[1],
8817
- attributes: parts.slice(2).join(' ')
8929
+ // Generates a rtpmap line from RTCRtpCodecCapability or
8930
+ // RTCRtpCodecParameters.
8931
+ SDPUtils.writeRtpMap = function (codec) {
8932
+ let pt = codec.payloadType;
8933
+ if (codec.preferredPayloadType !== undefined) {
8934
+ pt = codec.preferredPayloadType;
8935
+ }
8936
+ const channels = codec.channels || codec.numChannels || 1;
8937
+ return 'a=rtpmap:' + pt + ' ' + codec.name + '/' + codec.clockRate + (channels !== 1 ? '/' + channels : '') + '\r\n';
8818
8938
  };
8819
- };
8820
8939
 
8821
- // Generates an extmap line from RTCRtpHeaderExtensionParameters or
8822
- // RTCRtpHeaderExtension.
8823
- SDPUtils.writeExtmap = function (headerExtension) {
8824
- return 'a=extmap:' + (headerExtension.id || headerExtension.preferredId) + (headerExtension.direction && headerExtension.direction !== 'sendrecv' ? '/' + headerExtension.direction : '') + ' ' + headerExtension.uri + (headerExtension.attributes ? ' ' + headerExtension.attributes : '') + '\r\n';
8825
- };
8940
+ // Parses a extmap line (headerextension from RFC 5285). Sample input:
8941
+ // a=extmap:2 urn:ietf:params:rtp-hdrext:toffset
8942
+ // a=extmap:2/sendonly urn:ietf:params:rtp-hdrext:toffset
8943
+ SDPUtils.parseExtmap = function (line) {
8944
+ const parts = line.substring(9).split(' ');
8945
+ return {
8946
+ id: parseInt(parts[0], 10),
8947
+ direction: parts[0].indexOf('/') > 0 ? parts[0].split('/')[1] : 'sendrecv',
8948
+ uri: parts[1],
8949
+ attributes: parts.slice(2).join(' ')
8950
+ };
8951
+ };
8826
8952
 
8827
- // Parses a fmtp line, returns dictionary. Sample input:
8828
- // a=fmtp:96 vbr=on;cng=on
8829
- // Also deals with vbr=on; cng=on
8830
- SDPUtils.parseFmtp = function (line) {
8831
- const parsed = {};
8832
- let kv;
8833
- const parts = line.substring(line.indexOf(' ') + 1).split(';');
8834
- for (let j = 0; j < parts.length; j++) {
8835
- kv = parts[j].trim().split('=');
8836
- parsed[kv[0].trim()] = kv[1];
8837
- }
8838
- return parsed;
8839
- };
8953
+ // Generates an extmap line from RTCRtpHeaderExtensionParameters or
8954
+ // RTCRtpHeaderExtension.
8955
+ SDPUtils.writeExtmap = function (headerExtension) {
8956
+ return 'a=extmap:' + (headerExtension.id || headerExtension.preferredId) + (headerExtension.direction && headerExtension.direction !== 'sendrecv' ? '/' + headerExtension.direction : '') + ' ' + headerExtension.uri + (headerExtension.attributes ? ' ' + headerExtension.attributes : '') + '\r\n';
8957
+ };
8840
8958
 
8841
- // Generates a fmtp line from RTCRtpCodecCapability or RTCRtpCodecParameters.
8842
- SDPUtils.writeFmtp = function (codec) {
8843
- let line = '';
8844
- let pt = codec.payloadType;
8845
- if (codec.preferredPayloadType !== undefined) {
8846
- pt = codec.preferredPayloadType;
8847
- }
8848
- if (codec.parameters && Object.keys(codec.parameters).length) {
8849
- const params = [];
8850
- Object.keys(codec.parameters).forEach(param => {
8851
- if (codec.parameters[param] !== undefined) {
8852
- params.push(param + '=' + codec.parameters[param]);
8853
- } else {
8854
- params.push(param);
8855
- }
8856
- });
8857
- line += 'a=fmtp:' + pt + ' ' + params.join(';') + '\r\n';
8858
- }
8859
- return line;
8860
- };
8959
+ // Parses a fmtp line, returns dictionary. Sample input:
8960
+ // a=fmtp:96 vbr=on;cng=on
8961
+ // Also deals with vbr=on; cng=on
8962
+ SDPUtils.parseFmtp = function (line) {
8963
+ const parsed = {};
8964
+ let kv;
8965
+ const parts = line.substring(line.indexOf(' ') + 1).split(';');
8966
+ for (let j = 0; j < parts.length; j++) {
8967
+ kv = parts[j].trim().split('=');
8968
+ parsed[kv[0].trim()] = kv[1];
8969
+ }
8970
+ return parsed;
8971
+ };
8861
8972
 
8862
- // Parses a rtcp-fb line, returns RTCPRtcpFeedback object. Sample input:
8863
- // a=rtcp-fb:98 nack rpsi
8864
- SDPUtils.parseRtcpFb = function (line) {
8865
- const parts = line.substring(line.indexOf(' ') + 1).split(' ');
8866
- return {
8867
- type: parts.shift(),
8868
- parameter: parts.join(' ')
8973
+ // Generates a fmtp line from RTCRtpCodecCapability or RTCRtpCodecParameters.
8974
+ SDPUtils.writeFmtp = function (codec) {
8975
+ let line = '';
8976
+ let pt = codec.payloadType;
8977
+ if (codec.preferredPayloadType !== undefined) {
8978
+ pt = codec.preferredPayloadType;
8979
+ }
8980
+ if (codec.parameters && Object.keys(codec.parameters).length) {
8981
+ const params = [];
8982
+ Object.keys(codec.parameters).forEach(param => {
8983
+ if (codec.parameters[param] !== undefined) {
8984
+ params.push(param + '=' + codec.parameters[param]);
8985
+ } else {
8986
+ params.push(param);
8987
+ }
8988
+ });
8989
+ line += 'a=fmtp:' + pt + ' ' + params.join(';') + '\r\n';
8990
+ }
8991
+ return line;
8869
8992
  };
8870
- };
8871
8993
 
8872
- // Generate a=rtcp-fb lines from RTCRtpCodecCapability or RTCRtpCodecParameters.
8873
- SDPUtils.writeRtcpFb = function (codec) {
8874
- let lines = '';
8875
- let pt = codec.payloadType;
8876
- if (codec.preferredPayloadType !== undefined) {
8877
- pt = codec.preferredPayloadType;
8878
- }
8879
- if (codec.rtcpFeedback && codec.rtcpFeedback.length) {
8880
- // FIXME: special handling for trr-int?
8881
- codec.rtcpFeedback.forEach(fb => {
8882
- lines += 'a=rtcp-fb:' + pt + ' ' + fb.type + (fb.parameter && fb.parameter.length ? ' ' + fb.parameter : '') + '\r\n';
8883
- });
8884
- }
8885
- return lines;
8886
- };
8994
+ // Parses a rtcp-fb line, returns RTCPRtcpFeedback object. Sample input:
8995
+ // a=rtcp-fb:98 nack rpsi
8996
+ SDPUtils.parseRtcpFb = function (line) {
8997
+ const parts = line.substring(line.indexOf(' ') + 1).split(' ');
8998
+ return {
8999
+ type: parts.shift(),
9000
+ parameter: parts.join(' ')
9001
+ };
9002
+ };
8887
9003
 
8888
- // Parses a RFC 5576 ssrc media attribute. Sample input:
8889
- // a=ssrc:3735928559 cname:something
8890
- SDPUtils.parseSsrcMedia = function (line) {
8891
- const sp = line.indexOf(' ');
8892
- const parts = {
8893
- ssrc: parseInt(line.substring(7, sp), 10)
9004
+ // Generate a=rtcp-fb lines from RTCRtpCodecCapability or RTCRtpCodecParameters.
9005
+ SDPUtils.writeRtcpFb = function (codec) {
9006
+ let lines = '';
9007
+ let pt = codec.payloadType;
9008
+ if (codec.preferredPayloadType !== undefined) {
9009
+ pt = codec.preferredPayloadType;
9010
+ }
9011
+ if (codec.rtcpFeedback && codec.rtcpFeedback.length) {
9012
+ // FIXME: special handling for trr-int?
9013
+ codec.rtcpFeedback.forEach(fb => {
9014
+ lines += 'a=rtcp-fb:' + pt + ' ' + fb.type + (fb.parameter && fb.parameter.length ? ' ' + fb.parameter : '') + '\r\n';
9015
+ });
9016
+ }
9017
+ return lines;
8894
9018
  };
8895
- const colon = line.indexOf(':', sp);
8896
- if (colon > -1) {
8897
- parts.attribute = line.substring(sp + 1, colon);
8898
- parts.value = line.substring(colon + 1);
8899
- } else {
8900
- parts.attribute = line.substring(sp + 1);
8901
- }
8902
- return parts;
8903
- };
8904
9019
 
8905
- // Parse a ssrc-group line (see RFC 5576). Sample input:
8906
- // a=ssrc-group:semantics 12 34
8907
- SDPUtils.parseSsrcGroup = function (line) {
8908
- const parts = line.substring(13).split(' ');
8909
- return {
8910
- semantics: parts.shift(),
8911
- ssrcs: parts.map(ssrc => parseInt(ssrc, 10))
9020
+ // Parses a RFC 5576 ssrc media attribute. Sample input:
9021
+ // a=ssrc:3735928559 cname:something
9022
+ SDPUtils.parseSsrcMedia = function (line) {
9023
+ const sp = line.indexOf(' ');
9024
+ const parts = {
9025
+ ssrc: parseInt(line.substring(7, sp), 10)
9026
+ };
9027
+ const colon = line.indexOf(':', sp);
9028
+ if (colon > -1) {
9029
+ parts.attribute = line.substring(sp + 1, colon);
9030
+ parts.value = line.substring(colon + 1);
9031
+ } else {
9032
+ parts.attribute = line.substring(sp + 1);
9033
+ }
9034
+ return parts;
8912
9035
  };
8913
- };
8914
9036
 
8915
- // Extracts the MID (RFC 5888) from a media section.
8916
- // Returns the MID or undefined if no mid line was found.
8917
- SDPUtils.getMid = function (mediaSection) {
8918
- const mid = SDPUtils.matchPrefix(mediaSection, 'a=mid:')[0];
8919
- if (mid) {
8920
- return mid.substring(6);
8921
- }
8922
- };
9037
+ // Parse a ssrc-group line (see RFC 5576). Sample input:
9038
+ // a=ssrc-group:semantics 12 34
9039
+ SDPUtils.parseSsrcGroup = function (line) {
9040
+ const parts = line.substring(13).split(' ');
9041
+ return {
9042
+ semantics: parts.shift(),
9043
+ ssrcs: parts.map(ssrc => parseInt(ssrc, 10))
9044
+ };
9045
+ };
8923
9046
 
8924
- // Parses a fingerprint line for DTLS-SRTP.
8925
- SDPUtils.parseFingerprint = function (line) {
8926
- const parts = line.substring(14).split(' ');
8927
- return {
8928
- algorithm: parts[0].toLowerCase(),
8929
- // algorithm is case-sensitive in Edge.
8930
- value: parts[1].toUpperCase() // the definition is upper-case in RFC 4572.
9047
+ // Extracts the MID (RFC 5888) from a media section.
9048
+ // Returns the MID or undefined if no mid line was found.
9049
+ SDPUtils.getMid = function (mediaSection) {
9050
+ const mid = SDPUtils.matchPrefix(mediaSection, 'a=mid:')[0];
9051
+ if (mid) {
9052
+ return mid.substring(6);
9053
+ }
8931
9054
  };
8932
- };
8933
9055
 
8934
- // Extracts DTLS parameters from SDP media section or sessionpart.
8935
- // FIXME: for consistency with other functions this should only
8936
- // get the fingerprint line as input. See also getIceParameters.
8937
- SDPUtils.getDtlsParameters = function (mediaSection, sessionpart) {
8938
- const lines = SDPUtils.matchPrefix(mediaSection + sessionpart, 'a=fingerprint:');
8939
- // Note: a=setup line is ignored since we use the 'auto' role in Edge.
8940
- return {
8941
- role: 'auto',
8942
- fingerprints: lines.map(SDPUtils.parseFingerprint)
9056
+ // Parses a fingerprint line for DTLS-SRTP.
9057
+ SDPUtils.parseFingerprint = function (line) {
9058
+ const parts = line.substring(14).split(' ');
9059
+ return {
9060
+ algorithm: parts[0].toLowerCase(),
9061
+ // algorithm is case-sensitive in Edge.
9062
+ value: parts[1].toUpperCase() // the definition is upper-case in RFC 4572.
9063
+ };
8943
9064
  };
8944
- };
8945
9065
 
8946
- // Serializes DTLS parameters to SDP.
8947
- SDPUtils.writeDtlsParameters = function (params, setupType) {
8948
- let sdp = 'a=setup:' + setupType + '\r\n';
8949
- params.fingerprints.forEach(fp => {
8950
- sdp += 'a=fingerprint:' + fp.algorithm + ' ' + fp.value + '\r\n';
8951
- });
8952
- return sdp;
8953
- };
9066
+ // Extracts DTLS parameters from SDP media section or sessionpart.
9067
+ // FIXME: for consistency with other functions this should only
9068
+ // get the fingerprint line as input. See also getIceParameters.
9069
+ SDPUtils.getDtlsParameters = function (mediaSection, sessionpart) {
9070
+ const lines = SDPUtils.matchPrefix(mediaSection + sessionpart, 'a=fingerprint:');
9071
+ // Note: a=setup line is ignored since we use the 'auto' role in Edge.
9072
+ return {
9073
+ role: 'auto',
9074
+ fingerprints: lines.map(SDPUtils.parseFingerprint)
9075
+ };
9076
+ };
8954
9077
 
8955
- // Parses a=crypto lines into
8956
- // https://rawgit.com/aboba/edgertc/master/msortc-rs4.html#dictionary-rtcsrtpsdesparameters-members
8957
- SDPUtils.parseCryptoLine = function (line) {
8958
- const parts = line.substring(9).split(' ');
8959
- return {
8960
- tag: parseInt(parts[0], 10),
8961
- cryptoSuite: parts[1],
8962
- keyParams: parts[2],
8963
- sessionParams: parts.slice(3)
9078
+ // Serializes DTLS parameters to SDP.
9079
+ SDPUtils.writeDtlsParameters = function (params, setupType) {
9080
+ let sdp = 'a=setup:' + setupType + '\r\n';
9081
+ params.fingerprints.forEach(fp => {
9082
+ sdp += 'a=fingerprint:' + fp.algorithm + ' ' + fp.value + '\r\n';
9083
+ });
9084
+ return sdp;
8964
9085
  };
8965
- };
8966
- SDPUtils.writeCryptoLine = function (parameters) {
8967
- return 'a=crypto:' + parameters.tag + ' ' + parameters.cryptoSuite + ' ' + (typeof parameters.keyParams === 'object' ? SDPUtils.writeCryptoKeyParams(parameters.keyParams) : parameters.keyParams) + (parameters.sessionParams ? ' ' + parameters.sessionParams.join(' ') : '') + '\r\n';
8968
- };
8969
9086
 
8970
- // Parses the crypto key parameters into
8971
- // https://rawgit.com/aboba/edgertc/master/msortc-rs4.html#rtcsrtpkeyparam*
8972
- SDPUtils.parseCryptoKeyParams = function (keyParams) {
8973
- if (keyParams.indexOf('inline:') !== 0) {
8974
- return null;
8975
- }
8976
- const parts = keyParams.substring(7).split('|');
8977
- return {
8978
- keyMethod: 'inline',
8979
- keySalt: parts[0],
8980
- lifeTime: parts[1],
8981
- mkiValue: parts[2] ? parts[2].split(':')[0] : undefined,
8982
- mkiLength: parts[2] ? parts[2].split(':')[1] : undefined
9087
+ // Parses a=crypto lines into
9088
+ // https://rawgit.com/aboba/edgertc/master/msortc-rs4.html#dictionary-rtcsrtpsdesparameters-members
9089
+ SDPUtils.parseCryptoLine = function (line) {
9090
+ const parts = line.substring(9).split(' ');
9091
+ return {
9092
+ tag: parseInt(parts[0], 10),
9093
+ cryptoSuite: parts[1],
9094
+ keyParams: parts[2],
9095
+ sessionParams: parts.slice(3)
9096
+ };
9097
+ };
9098
+ SDPUtils.writeCryptoLine = function (parameters) {
9099
+ return 'a=crypto:' + parameters.tag + ' ' + parameters.cryptoSuite + ' ' + (typeof parameters.keyParams === 'object' ? SDPUtils.writeCryptoKeyParams(parameters.keyParams) : parameters.keyParams) + (parameters.sessionParams ? ' ' + parameters.sessionParams.join(' ') : '') + '\r\n';
8983
9100
  };
8984
- };
8985
- SDPUtils.writeCryptoKeyParams = function (keyParams) {
8986
- return keyParams.keyMethod + ':' + keyParams.keySalt + (keyParams.lifeTime ? '|' + keyParams.lifeTime : '') + (keyParams.mkiValue && keyParams.mkiLength ? '|' + keyParams.mkiValue + ':' + keyParams.mkiLength : '');
8987
- };
8988
9101
 
8989
- // Extracts all SDES parameters.
8990
- SDPUtils.getCryptoParameters = function (mediaSection, sessionpart) {
8991
- const lines = SDPUtils.matchPrefix(mediaSection + sessionpart, 'a=crypto:');
8992
- return lines.map(SDPUtils.parseCryptoLine);
8993
- };
9102
+ // Parses the crypto key parameters into
9103
+ // https://rawgit.com/aboba/edgertc/master/msortc-rs4.html#rtcsrtpkeyparam*
9104
+ SDPUtils.parseCryptoKeyParams = function (keyParams) {
9105
+ if (keyParams.indexOf('inline:') !== 0) {
9106
+ return null;
9107
+ }
9108
+ const parts = keyParams.substring(7).split('|');
9109
+ return {
9110
+ keyMethod: 'inline',
9111
+ keySalt: parts[0],
9112
+ lifeTime: parts[1],
9113
+ mkiValue: parts[2] ? parts[2].split(':')[0] : undefined,
9114
+ mkiLength: parts[2] ? parts[2].split(':')[1] : undefined
9115
+ };
9116
+ };
9117
+ SDPUtils.writeCryptoKeyParams = function (keyParams) {
9118
+ return keyParams.keyMethod + ':' + keyParams.keySalt + (keyParams.lifeTime ? '|' + keyParams.lifeTime : '') + (keyParams.mkiValue && keyParams.mkiLength ? '|' + keyParams.mkiValue + ':' + keyParams.mkiLength : '');
9119
+ };
8994
9120
 
8995
- // Parses ICE information from SDP media section or sessionpart.
8996
- // FIXME: for consistency with other functions this should only
8997
- // get the ice-ufrag and ice-pwd lines as input.
8998
- SDPUtils.getIceParameters = function (mediaSection, sessionpart) {
8999
- const ufrag = SDPUtils.matchPrefix(mediaSection + sessionpart, 'a=ice-ufrag:')[0];
9000
- const pwd = SDPUtils.matchPrefix(mediaSection + sessionpart, 'a=ice-pwd:')[0];
9001
- if (!(ufrag && pwd)) {
9002
- return null;
9003
- }
9004
- return {
9005
- usernameFragment: ufrag.substring(12),
9006
- password: pwd.substring(10)
9121
+ // Extracts all SDES parameters.
9122
+ SDPUtils.getCryptoParameters = function (mediaSection, sessionpart) {
9123
+ const lines = SDPUtils.matchPrefix(mediaSection + sessionpart, 'a=crypto:');
9124
+ return lines.map(SDPUtils.parseCryptoLine);
9007
9125
  };
9008
- };
9009
9126
 
9010
- // Serializes ICE parameters to SDP.
9011
- SDPUtils.writeIceParameters = function (params) {
9012
- let sdp = 'a=ice-ufrag:' + params.usernameFragment + '\r\n' + 'a=ice-pwd:' + params.password + '\r\n';
9013
- if (params.iceLite) {
9014
- sdp += 'a=ice-lite\r\n';
9015
- }
9016
- return sdp;
9017
- };
9127
+ // Parses ICE information from SDP media section or sessionpart.
9128
+ // FIXME: for consistency with other functions this should only
9129
+ // get the ice-ufrag and ice-pwd lines as input.
9130
+ SDPUtils.getIceParameters = function (mediaSection, sessionpart) {
9131
+ const ufrag = SDPUtils.matchPrefix(mediaSection + sessionpart, 'a=ice-ufrag:')[0];
9132
+ const pwd = SDPUtils.matchPrefix(mediaSection + sessionpart, 'a=ice-pwd:')[0];
9133
+ if (!(ufrag && pwd)) {
9134
+ return null;
9135
+ }
9136
+ return {
9137
+ usernameFragment: ufrag.substring(12),
9138
+ password: pwd.substring(10)
9139
+ };
9140
+ };
9018
9141
 
9019
- // Parses the SDP media section and returns RTCRtpParameters.
9020
- SDPUtils.parseRtpParameters = function (mediaSection) {
9021
- const description = {
9022
- codecs: [],
9023
- headerExtensions: [],
9024
- fecMechanisms: [],
9025
- rtcp: []
9142
+ // Serializes ICE parameters to SDP.
9143
+ SDPUtils.writeIceParameters = function (params) {
9144
+ let sdp = 'a=ice-ufrag:' + params.usernameFragment + '\r\n' + 'a=ice-pwd:' + params.password + '\r\n';
9145
+ if (params.iceLite) {
9146
+ sdp += 'a=ice-lite\r\n';
9147
+ }
9148
+ return sdp;
9026
9149
  };
9027
- const lines = SDPUtils.splitLines(mediaSection);
9028
- const mline = lines[0].split(' ');
9029
- description.profile = mline[2];
9030
- for (let i = 3; i < mline.length; i++) {
9031
- // find all codecs from mline[3..]
9032
- const pt = mline[i];
9033
- const rtpmapline = SDPUtils.matchPrefix(mediaSection, 'a=rtpmap:' + pt + ' ')[0];
9034
- if (rtpmapline) {
9035
- const codec = SDPUtils.parseRtpMap(rtpmapline);
9036
- const fmtps = SDPUtils.matchPrefix(mediaSection, 'a=fmtp:' + pt + ' ');
9037
- // Only the first a=fmtp:<pt> is considered.
9038
- codec.parameters = fmtps.length ? SDPUtils.parseFmtp(fmtps[0]) : {};
9039
- codec.rtcpFeedback = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-fb:' + pt + ' ').map(SDPUtils.parseRtcpFb);
9040
- description.codecs.push(codec);
9041
- // parse FEC mechanisms from rtpmap lines.
9042
- switch (codec.name.toUpperCase()) {
9043
- case 'RED':
9044
- case 'ULPFEC':
9045
- description.fecMechanisms.push(codec.name.toUpperCase());
9046
- break;
9150
+
9151
+ // Parses the SDP media section and returns RTCRtpParameters.
9152
+ SDPUtils.parseRtpParameters = function (mediaSection) {
9153
+ const description = {
9154
+ codecs: [],
9155
+ headerExtensions: [],
9156
+ fecMechanisms: [],
9157
+ rtcp: []
9158
+ };
9159
+ const lines = SDPUtils.splitLines(mediaSection);
9160
+ const mline = lines[0].split(' ');
9161
+ description.profile = mline[2];
9162
+ for (let i = 3; i < mline.length; i++) {
9163
+ // find all codecs from mline[3..]
9164
+ const pt = mline[i];
9165
+ const rtpmapline = SDPUtils.matchPrefix(mediaSection, 'a=rtpmap:' + pt + ' ')[0];
9166
+ if (rtpmapline) {
9167
+ const codec = SDPUtils.parseRtpMap(rtpmapline);
9168
+ const fmtps = SDPUtils.matchPrefix(mediaSection, 'a=fmtp:' + pt + ' ');
9169
+ // Only the first a=fmtp:<pt> is considered.
9170
+ codec.parameters = fmtps.length ? SDPUtils.parseFmtp(fmtps[0]) : {};
9171
+ codec.rtcpFeedback = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-fb:' + pt + ' ').map(SDPUtils.parseRtcpFb);
9172
+ description.codecs.push(codec);
9173
+ // parse FEC mechanisms from rtpmap lines.
9174
+ switch (codec.name.toUpperCase()) {
9175
+ case 'RED':
9176
+ case 'ULPFEC':
9177
+ description.fecMechanisms.push(codec.name.toUpperCase());
9178
+ break;
9179
+ }
9047
9180
  }
9048
9181
  }
9049
- }
9050
- SDPUtils.matchPrefix(mediaSection, 'a=extmap:').forEach(line => {
9051
- description.headerExtensions.push(SDPUtils.parseExtmap(line));
9052
- });
9053
- const wildcardRtcpFb = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-fb:* ').map(SDPUtils.parseRtcpFb);
9054
- description.codecs.forEach(codec => {
9055
- wildcardRtcpFb.forEach(fb => {
9056
- const duplicate = codec.rtcpFeedback.find(existingFeedback => {
9057
- return existingFeedback.type === fb.type && existingFeedback.parameter === fb.parameter;
9182
+ SDPUtils.matchPrefix(mediaSection, 'a=extmap:').forEach(line => {
9183
+ description.headerExtensions.push(SDPUtils.parseExtmap(line));
9184
+ });
9185
+ const wildcardRtcpFb = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-fb:* ').map(SDPUtils.parseRtcpFb);
9186
+ description.codecs.forEach(codec => {
9187
+ wildcardRtcpFb.forEach(fb => {
9188
+ const duplicate = codec.rtcpFeedback.find(existingFeedback => {
9189
+ return existingFeedback.type === fb.type && existingFeedback.parameter === fb.parameter;
9190
+ });
9191
+ if (!duplicate) {
9192
+ codec.rtcpFeedback.push(fb);
9193
+ }
9058
9194
  });
9059
- if (!duplicate) {
9060
- codec.rtcpFeedback.push(fb);
9061
- }
9062
9195
  });
9063
- });
9064
- // FIXME: parse rtcp.
9065
- return description;
9066
- };
9067
-
9068
- // Generates parts of the SDP media section describing the capabilities /
9069
- // parameters.
9070
- SDPUtils.writeRtpDescription = function (kind, caps) {
9071
- let sdp = '';
9196
+ // FIXME: parse rtcp.
9197
+ return description;
9198
+ };
9072
9199
 
9073
- // Build the mline.
9074
- sdp += 'm=' + kind + ' ';
9075
- sdp += caps.codecs.length > 0 ? '9' : '0'; // reject if no codecs.
9076
- sdp += ' ' + (caps.profile || 'UDP/TLS/RTP/SAVPF') + ' ';
9077
- sdp += caps.codecs.map(codec => {
9078
- if (codec.preferredPayloadType !== undefined) {
9079
- return codec.preferredPayloadType;
9200
+ // Generates parts of the SDP media section describing the capabilities /
9201
+ // parameters.
9202
+ SDPUtils.writeRtpDescription = function (kind, caps) {
9203
+ let sdp = '';
9204
+
9205
+ // Build the mline.
9206
+ sdp += 'm=' + kind + ' ';
9207
+ sdp += caps.codecs.length > 0 ? '9' : '0'; // reject if no codecs.
9208
+ sdp += ' ' + (caps.profile || 'UDP/TLS/RTP/SAVPF') + ' ';
9209
+ sdp += caps.codecs.map(codec => {
9210
+ if (codec.preferredPayloadType !== undefined) {
9211
+ return codec.preferredPayloadType;
9212
+ }
9213
+ return codec.payloadType;
9214
+ }).join(' ') + '\r\n';
9215
+ sdp += 'c=IN IP4 0.0.0.0\r\n';
9216
+ sdp += 'a=rtcp:9 IN IP4 0.0.0.0\r\n';
9217
+
9218
+ // Add a=rtpmap lines for each codec. Also fmtp and rtcp-fb.
9219
+ caps.codecs.forEach(codec => {
9220
+ sdp += SDPUtils.writeRtpMap(codec);
9221
+ sdp += SDPUtils.writeFmtp(codec);
9222
+ sdp += SDPUtils.writeRtcpFb(codec);
9223
+ });
9224
+ let maxptime = 0;
9225
+ caps.codecs.forEach(codec => {
9226
+ if (codec.maxptime > maxptime) {
9227
+ maxptime = codec.maxptime;
9228
+ }
9229
+ });
9230
+ if (maxptime > 0) {
9231
+ sdp += 'a=maxptime:' + maxptime + '\r\n';
9080
9232
  }
9081
- return codec.payloadType;
9082
- }).join(' ') + '\r\n';
9083
- sdp += 'c=IN IP4 0.0.0.0\r\n';
9084
- sdp += 'a=rtcp:9 IN IP4 0.0.0.0\r\n';
9085
-
9086
- // Add a=rtpmap lines for each codec. Also fmtp and rtcp-fb.
9087
- caps.codecs.forEach(codec => {
9088
- sdp += SDPUtils.writeRtpMap(codec);
9089
- sdp += SDPUtils.writeFmtp(codec);
9090
- sdp += SDPUtils.writeRtcpFb(codec);
9091
- });
9092
- let maxptime = 0;
9093
- caps.codecs.forEach(codec => {
9094
- if (codec.maxptime > maxptime) {
9095
- maxptime = codec.maxptime;
9233
+ if (caps.headerExtensions) {
9234
+ caps.headerExtensions.forEach(extension => {
9235
+ sdp += SDPUtils.writeExtmap(extension);
9236
+ });
9096
9237
  }
9097
- });
9098
- if (maxptime > 0) {
9099
- sdp += 'a=maxptime:' + maxptime + '\r\n';
9100
- }
9101
- if (caps.headerExtensions) {
9102
- caps.headerExtensions.forEach(extension => {
9103
- sdp += SDPUtils.writeExtmap(extension);
9104
- });
9105
- }
9106
- // FIXME: write fecMechanisms.
9107
- return sdp;
9108
- };
9238
+ // FIXME: write fecMechanisms.
9239
+ return sdp;
9240
+ };
9109
9241
 
9110
- // Parses the SDP media section and returns an array of
9111
- // RTCRtpEncodingParameters.
9112
- SDPUtils.parseRtpEncodingParameters = function (mediaSection) {
9113
- const encodingParameters = [];
9114
- const description = SDPUtils.parseRtpParameters(mediaSection);
9115
- const hasRed = description.fecMechanisms.indexOf('RED') !== -1;
9116
- const hasUlpfec = description.fecMechanisms.indexOf('ULPFEC') !== -1;
9117
-
9118
- // filter a=ssrc:... cname:, ignore PlanB-msid
9119
- const ssrcs = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:').map(line => SDPUtils.parseSsrcMedia(line)).filter(parts => parts.attribute === 'cname');
9120
- const primarySsrc = ssrcs.length > 0 && ssrcs[0].ssrc;
9121
- let secondarySsrc;
9122
- const flows = SDPUtils.matchPrefix(mediaSection, 'a=ssrc-group:FID').map(line => {
9123
- const parts = line.substring(17).split(' ');
9124
- return parts.map(part => parseInt(part, 10));
9125
- });
9126
- if (flows.length > 0 && flows[0].length > 1 && flows[0][0] === primarySsrc) {
9127
- secondarySsrc = flows[0][1];
9128
- }
9129
- description.codecs.forEach(codec => {
9130
- if (codec.name.toUpperCase() === 'RTX' && codec.parameters.apt) {
9131
- let encParam = {
9132
- ssrc: primarySsrc,
9133
- codecPayloadType: parseInt(codec.parameters.apt, 10)
9134
- };
9135
- if (primarySsrc && secondarySsrc) {
9136
- encParam.rtx = {
9137
- ssrc: secondarySsrc
9138
- };
9139
- }
9140
- encodingParameters.push(encParam);
9141
- if (hasRed) {
9142
- encParam = JSON.parse(JSON.stringify(encParam));
9143
- encParam.fec = {
9242
+ // Parses the SDP media section and returns an array of
9243
+ // RTCRtpEncodingParameters.
9244
+ SDPUtils.parseRtpEncodingParameters = function (mediaSection) {
9245
+ const encodingParameters = [];
9246
+ const description = SDPUtils.parseRtpParameters(mediaSection);
9247
+ const hasRed = description.fecMechanisms.indexOf('RED') !== -1;
9248
+ const hasUlpfec = description.fecMechanisms.indexOf('ULPFEC') !== -1;
9249
+
9250
+ // filter a=ssrc:... cname:, ignore PlanB-msid
9251
+ const ssrcs = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:').map(line => SDPUtils.parseSsrcMedia(line)).filter(parts => parts.attribute === 'cname');
9252
+ const primarySsrc = ssrcs.length > 0 && ssrcs[0].ssrc;
9253
+ let secondarySsrc;
9254
+ const flows = SDPUtils.matchPrefix(mediaSection, 'a=ssrc-group:FID').map(line => {
9255
+ const parts = line.substring(17).split(' ');
9256
+ return parts.map(part => parseInt(part, 10));
9257
+ });
9258
+ if (flows.length > 0 && flows[0].length > 1 && flows[0][0] === primarySsrc) {
9259
+ secondarySsrc = flows[0][1];
9260
+ }
9261
+ description.codecs.forEach(codec => {
9262
+ if (codec.name.toUpperCase() === 'RTX' && codec.parameters.apt) {
9263
+ let encParam = {
9144
9264
  ssrc: primarySsrc,
9145
- mechanism: hasUlpfec ? 'red+ulpfec' : 'red'
9265
+ codecPayloadType: parseInt(codec.parameters.apt, 10)
9146
9266
  };
9267
+ if (primarySsrc && secondarySsrc) {
9268
+ encParam.rtx = {
9269
+ ssrc: secondarySsrc
9270
+ };
9271
+ }
9147
9272
  encodingParameters.push(encParam);
9273
+ if (hasRed) {
9274
+ encParam = JSON.parse(JSON.stringify(encParam));
9275
+ encParam.fec = {
9276
+ ssrc: primarySsrc,
9277
+ mechanism: hasUlpfec ? 'red+ulpfec' : 'red'
9278
+ };
9279
+ encodingParameters.push(encParam);
9280
+ }
9148
9281
  }
9149
- }
9150
- });
9151
- if (encodingParameters.length === 0 && primarySsrc) {
9152
- encodingParameters.push({
9153
- ssrc: primarySsrc
9154
9282
  });
9155
- }
9283
+ if (encodingParameters.length === 0 && primarySsrc) {
9284
+ encodingParameters.push({
9285
+ ssrc: primarySsrc
9286
+ });
9287
+ }
9156
9288
 
9157
- // we support both b=AS and b=TIAS but interpret AS as TIAS.
9158
- let bandwidth = SDPUtils.matchPrefix(mediaSection, 'b=');
9159
- if (bandwidth.length) {
9160
- if (bandwidth[0].indexOf('b=TIAS:') === 0) {
9161
- bandwidth = parseInt(bandwidth[0].substring(7), 10);
9162
- } else if (bandwidth[0].indexOf('b=AS:') === 0) {
9163
- // use formula from JSEP to convert b=AS to TIAS value.
9164
- bandwidth = parseInt(bandwidth[0].substring(5), 10) * 1000 * 0.95 - 50 * 40 * 8;
9165
- } else {
9166
- bandwidth = undefined;
9289
+ // we support both b=AS and b=TIAS but interpret AS as TIAS.
9290
+ let bandwidth = SDPUtils.matchPrefix(mediaSection, 'b=');
9291
+ if (bandwidth.length) {
9292
+ if (bandwidth[0].indexOf('b=TIAS:') === 0) {
9293
+ bandwidth = parseInt(bandwidth[0].substring(7), 10);
9294
+ } else if (bandwidth[0].indexOf('b=AS:') === 0) {
9295
+ // use formula from JSEP to convert b=AS to TIAS value.
9296
+ bandwidth = parseInt(bandwidth[0].substring(5), 10) * 1000 * 0.95 - 50 * 40 * 8;
9297
+ } else {
9298
+ bandwidth = undefined;
9299
+ }
9300
+ encodingParameters.forEach(params => {
9301
+ params.maxBitrate = bandwidth;
9302
+ });
9167
9303
  }
9168
- encodingParameters.forEach(params => {
9169
- params.maxBitrate = bandwidth;
9170
- });
9171
- }
9172
- return encodingParameters;
9173
- };
9304
+ return encodingParameters;
9305
+ };
9174
9306
 
9175
- // parses http://draft.ortc.org/#rtcrtcpparameters*
9176
- SDPUtils.parseRtcpParameters = function (mediaSection) {
9177
- const rtcpParameters = {};
9178
-
9179
- // Gets the first SSRC. Note that with RTX there might be multiple
9180
- // SSRCs.
9181
- const remoteSsrc = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:').map(line => SDPUtils.parseSsrcMedia(line)).filter(obj => obj.attribute === 'cname')[0];
9182
- if (remoteSsrc) {
9183
- rtcpParameters.cname = remoteSsrc.value;
9184
- rtcpParameters.ssrc = remoteSsrc.ssrc;
9185
- }
9186
-
9187
- // Edge uses the compound attribute instead of reducedSize
9188
- // compound is !reducedSize
9189
- const rsize = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-rsize');
9190
- rtcpParameters.reducedSize = rsize.length > 0;
9191
- rtcpParameters.compound = rsize.length === 0;
9192
-
9193
- // parses the rtcp-mux attrіbute.
9194
- // Note that Edge does not support unmuxed RTCP.
9195
- const mux = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-mux');
9196
- rtcpParameters.mux = mux.length > 0;
9197
- return rtcpParameters;
9198
- };
9199
- SDPUtils.writeRtcpParameters = function (rtcpParameters) {
9200
- let sdp = '';
9201
- if (rtcpParameters.reducedSize) {
9202
- sdp += 'a=rtcp-rsize\r\n';
9203
- }
9204
- if (rtcpParameters.mux) {
9205
- sdp += 'a=rtcp-mux\r\n';
9206
- }
9207
- if (rtcpParameters.ssrc !== undefined && rtcpParameters.cname) {
9208
- sdp += 'a=ssrc:' + rtcpParameters.ssrc + ' cname:' + rtcpParameters.cname + '\r\n';
9209
- }
9210
- return sdp;
9211
- };
9307
+ // parses http://draft.ortc.org/#rtcrtcpparameters*
9308
+ SDPUtils.parseRtcpParameters = function (mediaSection) {
9309
+ const rtcpParameters = {};
9310
+
9311
+ // Gets the first SSRC. Note that with RTX there might be multiple
9312
+ // SSRCs.
9313
+ const remoteSsrc = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:').map(line => SDPUtils.parseSsrcMedia(line)).filter(obj => obj.attribute === 'cname')[0];
9314
+ if (remoteSsrc) {
9315
+ rtcpParameters.cname = remoteSsrc.value;
9316
+ rtcpParameters.ssrc = remoteSsrc.ssrc;
9317
+ }
9318
+
9319
+ // Edge uses the compound attribute instead of reducedSize
9320
+ // compound is !reducedSize
9321
+ const rsize = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-rsize');
9322
+ rtcpParameters.reducedSize = rsize.length > 0;
9323
+ rtcpParameters.compound = rsize.length === 0;
9324
+
9325
+ // parses the rtcp-mux attrіbute.
9326
+ // Note that Edge does not support unmuxed RTCP.
9327
+ const mux = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-mux');
9328
+ rtcpParameters.mux = mux.length > 0;
9329
+ return rtcpParameters;
9330
+ };
9331
+ SDPUtils.writeRtcpParameters = function (rtcpParameters) {
9332
+ let sdp = '';
9333
+ if (rtcpParameters.reducedSize) {
9334
+ sdp += 'a=rtcp-rsize\r\n';
9335
+ }
9336
+ if (rtcpParameters.mux) {
9337
+ sdp += 'a=rtcp-mux\r\n';
9338
+ }
9339
+ if (rtcpParameters.ssrc !== undefined && rtcpParameters.cname) {
9340
+ sdp += 'a=ssrc:' + rtcpParameters.ssrc + ' cname:' + rtcpParameters.cname + '\r\n';
9341
+ }
9342
+ return sdp;
9343
+ };
9212
9344
 
9213
- // parses either a=msid: or a=ssrc:... msid lines and returns
9214
- // the id of the MediaStream and MediaStreamTrack.
9215
- SDPUtils.parseMsid = function (mediaSection) {
9216
- let parts;
9217
- const spec = SDPUtils.matchPrefix(mediaSection, 'a=msid:');
9218
- if (spec.length === 1) {
9219
- parts = spec[0].substring(7).split(' ');
9220
- return {
9221
- stream: parts[0],
9222
- track: parts[1]
9223
- };
9224
- }
9225
- const planB = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:').map(line => SDPUtils.parseSsrcMedia(line)).filter(msidParts => msidParts.attribute === 'msid');
9226
- if (planB.length > 0) {
9227
- parts = planB[0].value.split(' ');
9228
- return {
9229
- stream: parts[0],
9230
- track: parts[1]
9231
- };
9232
- }
9233
- };
9345
+ // parses either a=msid: or a=ssrc:... msid lines and returns
9346
+ // the id of the MediaStream and MediaStreamTrack.
9347
+ SDPUtils.parseMsid = function (mediaSection) {
9348
+ let parts;
9349
+ const spec = SDPUtils.matchPrefix(mediaSection, 'a=msid:');
9350
+ if (spec.length === 1) {
9351
+ parts = spec[0].substring(7).split(' ');
9352
+ return {
9353
+ stream: parts[0],
9354
+ track: parts[1]
9355
+ };
9356
+ }
9357
+ const planB = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:').map(line => SDPUtils.parseSsrcMedia(line)).filter(msidParts => msidParts.attribute === 'msid');
9358
+ if (planB.length > 0) {
9359
+ parts = planB[0].value.split(' ');
9360
+ return {
9361
+ stream: parts[0],
9362
+ track: parts[1]
9363
+ };
9364
+ }
9365
+ };
9234
9366
 
9235
- // SCTP
9236
- // parses draft-ietf-mmusic-sctp-sdp-26 first and falls back
9237
- // to draft-ietf-mmusic-sctp-sdp-05
9238
- SDPUtils.parseSctpDescription = function (mediaSection) {
9239
- const mline = SDPUtils.parseMLine(mediaSection);
9240
- const maxSizeLine = SDPUtils.matchPrefix(mediaSection, 'a=max-message-size:');
9241
- let maxMessageSize;
9242
- if (maxSizeLine.length > 0) {
9243
- maxMessageSize = parseInt(maxSizeLine[0].substring(19), 10);
9244
- }
9245
- if (isNaN(maxMessageSize)) {
9246
- maxMessageSize = 65536;
9247
- }
9248
- const sctpPort = SDPUtils.matchPrefix(mediaSection, 'a=sctp-port:');
9249
- if (sctpPort.length > 0) {
9250
- return {
9251
- port: parseInt(sctpPort[0].substring(12), 10),
9252
- protocol: mline.fmt,
9253
- maxMessageSize
9254
- };
9255
- }
9256
- const sctpMapLines = SDPUtils.matchPrefix(mediaSection, 'a=sctpmap:');
9257
- if (sctpMapLines.length > 0) {
9258
- const parts = sctpMapLines[0].substring(10).split(' ');
9259
- return {
9260
- port: parseInt(parts[0], 10),
9261
- protocol: parts[1],
9262
- maxMessageSize
9263
- };
9264
- }
9265
- };
9367
+ // SCTP
9368
+ // parses draft-ietf-mmusic-sctp-sdp-26 first and falls back
9369
+ // to draft-ietf-mmusic-sctp-sdp-05
9370
+ SDPUtils.parseSctpDescription = function (mediaSection) {
9371
+ const mline = SDPUtils.parseMLine(mediaSection);
9372
+ const maxSizeLine = SDPUtils.matchPrefix(mediaSection, 'a=max-message-size:');
9373
+ let maxMessageSize;
9374
+ if (maxSizeLine.length > 0) {
9375
+ maxMessageSize = parseInt(maxSizeLine[0].substring(19), 10);
9376
+ }
9377
+ if (isNaN(maxMessageSize)) {
9378
+ maxMessageSize = 65536;
9379
+ }
9380
+ const sctpPort = SDPUtils.matchPrefix(mediaSection, 'a=sctp-port:');
9381
+ if (sctpPort.length > 0) {
9382
+ return {
9383
+ port: parseInt(sctpPort[0].substring(12), 10),
9384
+ protocol: mline.fmt,
9385
+ maxMessageSize
9386
+ };
9387
+ }
9388
+ const sctpMapLines = SDPUtils.matchPrefix(mediaSection, 'a=sctpmap:');
9389
+ if (sctpMapLines.length > 0) {
9390
+ const parts = sctpMapLines[0].substring(10).split(' ');
9391
+ return {
9392
+ port: parseInt(parts[0], 10),
9393
+ protocol: parts[1],
9394
+ maxMessageSize
9395
+ };
9396
+ }
9397
+ };
9266
9398
 
9267
- // SCTP
9268
- // outputs the draft-ietf-mmusic-sctp-sdp-26 version that all browsers
9269
- // support by now receiving in this format, unless we originally parsed
9270
- // as the draft-ietf-mmusic-sctp-sdp-05 format (indicated by the m-line
9271
- // protocol of DTLS/SCTP -- without UDP/ or TCP/)
9272
- SDPUtils.writeSctpDescription = function (media, sctp) {
9273
- let output = [];
9274
- if (media.protocol !== 'DTLS/SCTP') {
9275
- output = ['m=' + media.kind + ' 9 ' + media.protocol + ' ' + sctp.protocol + '\r\n', 'c=IN IP4 0.0.0.0\r\n', 'a=sctp-port:' + sctp.port + '\r\n'];
9276
- } else {
9277
- output = ['m=' + media.kind + ' 9 ' + media.protocol + ' ' + sctp.port + '\r\n', 'c=IN IP4 0.0.0.0\r\n', 'a=sctpmap:' + sctp.port + ' ' + sctp.protocol + ' 65535\r\n'];
9278
- }
9279
- if (sctp.maxMessageSize !== undefined) {
9280
- output.push('a=max-message-size:' + sctp.maxMessageSize + '\r\n');
9281
- }
9282
- return output.join('');
9283
- };
9399
+ // SCTP
9400
+ // outputs the draft-ietf-mmusic-sctp-sdp-26 version that all browsers
9401
+ // support by now receiving in this format, unless we originally parsed
9402
+ // as the draft-ietf-mmusic-sctp-sdp-05 format (indicated by the m-line
9403
+ // protocol of DTLS/SCTP -- without UDP/ or TCP/)
9404
+ SDPUtils.writeSctpDescription = function (media, sctp) {
9405
+ let output = [];
9406
+ if (media.protocol !== 'DTLS/SCTP') {
9407
+ output = ['m=' + media.kind + ' 9 ' + media.protocol + ' ' + sctp.protocol + '\r\n', 'c=IN IP4 0.0.0.0\r\n', 'a=sctp-port:' + sctp.port + '\r\n'];
9408
+ } else {
9409
+ output = ['m=' + media.kind + ' 9 ' + media.protocol + ' ' + sctp.port + '\r\n', 'c=IN IP4 0.0.0.0\r\n', 'a=sctpmap:' + sctp.port + ' ' + sctp.protocol + ' 65535\r\n'];
9410
+ }
9411
+ if (sctp.maxMessageSize !== undefined) {
9412
+ output.push('a=max-message-size:' + sctp.maxMessageSize + '\r\n');
9413
+ }
9414
+ return output.join('');
9415
+ };
9284
9416
 
9285
- // Generate a session ID for SDP.
9286
- // https://tools.ietf.org/html/draft-ietf-rtcweb-jsep-20#section-5.2.1
9287
- // recommends using a cryptographically random +ve 64-bit value
9288
- // but right now this should be acceptable and within the right range
9289
- SDPUtils.generateSessionId = function () {
9290
- return Math.random().toString().substr(2, 22);
9291
- };
9417
+ // Generate a session ID for SDP.
9418
+ // https://tools.ietf.org/html/draft-ietf-rtcweb-jsep-20#section-5.2.1
9419
+ // recommends using a cryptographically random +ve 64-bit value
9420
+ // but right now this should be acceptable and within the right range
9421
+ SDPUtils.generateSessionId = function () {
9422
+ return Math.random().toString().substr(2, 22);
9423
+ };
9292
9424
 
9293
- // Write boiler plate for start of SDP
9294
- // sessId argument is optional - if not supplied it will
9295
- // be generated randomly
9296
- // sessVersion is optional and defaults to 2
9297
- // sessUser is optional and defaults to 'thisisadapterortc'
9298
- SDPUtils.writeSessionBoilerplate = function (sessId, sessVer, sessUser) {
9299
- let sessionId;
9300
- const version = sessVer !== undefined ? sessVer : 2;
9301
- if (sessId) {
9302
- sessionId = sessId;
9303
- } else {
9304
- sessionId = SDPUtils.generateSessionId();
9305
- }
9306
- const user = sessUser || 'thisisadapterortc';
9307
- // FIXME: sess-id should be an NTP timestamp.
9308
- return 'v=0\r\n' + 'o=' + user + ' ' + sessionId + ' ' + version + ' IN IP4 127.0.0.1\r\n' + 's=-\r\n' + 't=0 0\r\n';
9309
- };
9425
+ // Write boiler plate for start of SDP
9426
+ // sessId argument is optional - if not supplied it will
9427
+ // be generated randomly
9428
+ // sessVersion is optional and defaults to 2
9429
+ // sessUser is optional and defaults to 'thisisadapterortc'
9430
+ SDPUtils.writeSessionBoilerplate = function (sessId, sessVer, sessUser) {
9431
+ let sessionId;
9432
+ const version = sessVer !== undefined ? sessVer : 2;
9433
+ if (sessId) {
9434
+ sessionId = sessId;
9435
+ } else {
9436
+ sessionId = SDPUtils.generateSessionId();
9437
+ }
9438
+ const user = sessUser || 'thisisadapterortc';
9439
+ // FIXME: sess-id should be an NTP timestamp.
9440
+ return 'v=0\r\n' + 'o=' + user + ' ' + sessionId + ' ' + version + ' IN IP4 127.0.0.1\r\n' + 's=-\r\n' + 't=0 0\r\n';
9441
+ };
9310
9442
 
9311
- // Gets the direction from the mediaSection or the sessionpart.
9312
- SDPUtils.getDirection = function (mediaSection, sessionpart) {
9313
- // Look for sendrecv, sendonly, recvonly, inactive, default to sendrecv.
9314
- const lines = SDPUtils.splitLines(mediaSection);
9315
- for (let i = 0; i < lines.length; i++) {
9316
- switch (lines[i]) {
9317
- case 'a=sendrecv':
9318
- case 'a=sendonly':
9319
- case 'a=recvonly':
9320
- case 'a=inactive':
9321
- return lines[i].substring(2);
9322
- // FIXME: What should happen here?
9443
+ // Gets the direction from the mediaSection or the sessionpart.
9444
+ SDPUtils.getDirection = function (mediaSection, sessionpart) {
9445
+ // Look for sendrecv, sendonly, recvonly, inactive, default to sendrecv.
9446
+ const lines = SDPUtils.splitLines(mediaSection);
9447
+ for (let i = 0; i < lines.length; i++) {
9448
+ switch (lines[i]) {
9449
+ case 'a=sendrecv':
9450
+ case 'a=sendonly':
9451
+ case 'a=recvonly':
9452
+ case 'a=inactive':
9453
+ return lines[i].substring(2);
9454
+ // FIXME: What should happen here?
9455
+ }
9323
9456
  }
9324
- }
9325
- if (sessionpart) {
9326
- return SDPUtils.getDirection(sessionpart);
9327
- }
9328
- return 'sendrecv';
9329
- };
9330
- SDPUtils.getKind = function (mediaSection) {
9331
- const lines = SDPUtils.splitLines(mediaSection);
9332
- const mline = lines[0].split(' ');
9333
- return mline[0].substring(2);
9334
- };
9335
- SDPUtils.isRejected = function (mediaSection) {
9336
- return mediaSection.split(' ', 2)[1] === '0';
9337
- };
9338
- SDPUtils.parseMLine = function (mediaSection) {
9339
- const lines = SDPUtils.splitLines(mediaSection);
9340
- const parts = lines[0].substring(2).split(' ');
9341
- return {
9342
- kind: parts[0],
9343
- port: parseInt(parts[1], 10),
9344
- protocol: parts[2],
9345
- fmt: parts.slice(3).join(' ')
9457
+ if (sessionpart) {
9458
+ return SDPUtils.getDirection(sessionpart);
9459
+ }
9460
+ return 'sendrecv';
9346
9461
  };
9347
- };
9348
- SDPUtils.parseOLine = function (mediaSection) {
9349
- const line = SDPUtils.matchPrefix(mediaSection, 'o=')[0];
9350
- const parts = line.substring(2).split(' ');
9351
- return {
9352
- username: parts[0],
9353
- sessionId: parts[1],
9354
- sessionVersion: parseInt(parts[2], 10),
9355
- netType: parts[3],
9356
- addressType: parts[4],
9357
- address: parts[5]
9462
+ SDPUtils.getKind = function (mediaSection) {
9463
+ const lines = SDPUtils.splitLines(mediaSection);
9464
+ const mline = lines[0].split(' ');
9465
+ return mline[0].substring(2);
9466
+ };
9467
+ SDPUtils.isRejected = function (mediaSection) {
9468
+ return mediaSection.split(' ', 2)[1] === '0';
9469
+ };
9470
+ SDPUtils.parseMLine = function (mediaSection) {
9471
+ const lines = SDPUtils.splitLines(mediaSection);
9472
+ const parts = lines[0].substring(2).split(' ');
9473
+ return {
9474
+ kind: parts[0],
9475
+ port: parseInt(parts[1], 10),
9476
+ protocol: parts[2],
9477
+ fmt: parts.slice(3).join(' ')
9478
+ };
9479
+ };
9480
+ SDPUtils.parseOLine = function (mediaSection) {
9481
+ const line = SDPUtils.matchPrefix(mediaSection, 'o=')[0];
9482
+ const parts = line.substring(2).split(' ');
9483
+ return {
9484
+ username: parts[0],
9485
+ sessionId: parts[1],
9486
+ sessionVersion: parseInt(parts[2], 10),
9487
+ netType: parts[3],
9488
+ addressType: parts[4],
9489
+ address: parts[5]
9490
+ };
9358
9491
  };
9359
- };
9360
9492
 
9361
- // a very naive interpretation of a valid SDP.
9362
- SDPUtils.isValidSDP = function (blob) {
9363
- if (typeof blob !== 'string' || blob.length === 0) {
9364
- return false;
9365
- }
9366
- const lines = SDPUtils.splitLines(blob);
9367
- for (let i = 0; i < lines.length; i++) {
9368
- if (lines[i].length < 2 || lines[i].charAt(1) !== '=') {
9493
+ // a very naive interpretation of a valid SDP.
9494
+ SDPUtils.isValidSDP = function (blob) {
9495
+ if (typeof blob !== 'string' || blob.length === 0) {
9369
9496
  return false;
9370
9497
  }
9371
- // TODO: check the modifier a bit more.
9498
+ const lines = SDPUtils.splitLines(blob);
9499
+ for (let i = 0; i < lines.length; i++) {
9500
+ if (lines[i].length < 2 || lines[i].charAt(1) !== '=') {
9501
+ return false;
9502
+ }
9503
+ // TODO: check the modifier a bit more.
9504
+ }
9505
+ return true;
9506
+ };
9507
+
9508
+ // Expose public methods.
9509
+ {
9510
+ module.exports = SDPUtils;
9372
9511
  }
9373
- return true;
9374
- };
9512
+ })(sdp$1);
9513
+ return sdp$1.exports;
9514
+ }
9375
9515
 
9376
- // Expose public methods.
9377
- {
9378
- module.exports = SDPUtils;
9379
- }
9380
- })(sdp$1);
9381
- var sdpExports = sdp$1.exports;
9516
+ var sdpExports = requireSdp();
9382
9517
  var SDPUtils = /*@__PURE__*/getDefaultExportFromCjs(sdpExports);
9383
9518
 
9384
9519
  var sdp = /*#__PURE__*/_mergeNamespaces({
@@ -10223,6 +10358,14 @@ class LivekitError extends Error {
10223
10358
  this.code = code;
10224
10359
  }
10225
10360
  }
10361
+ var ConnectionErrorReason;
10362
+ (function (ConnectionErrorReason) {
10363
+ ConnectionErrorReason[ConnectionErrorReason["NotAllowed"] = 0] = "NotAllowed";
10364
+ ConnectionErrorReason[ConnectionErrorReason["ServerUnreachable"] = 1] = "ServerUnreachable";
10365
+ ConnectionErrorReason[ConnectionErrorReason["InternalError"] = 2] = "InternalError";
10366
+ ConnectionErrorReason[ConnectionErrorReason["Cancelled"] = 3] = "Cancelled";
10367
+ ConnectionErrorReason[ConnectionErrorReason["LeaveRequest"] = 4] = "LeaveRequest";
10368
+ })(ConnectionErrorReason || (ConnectionErrorReason = {}));
10226
10369
  class ConnectionError extends LivekitError {
10227
10370
  constructor(message, reason, status) {
10228
10371
  super(1, message);
@@ -10572,7 +10715,7 @@ var RoomEvent;
10572
10715
  */
10573
10716
  RoomEvent["MediaDevicesError"] = "mediaDevicesError";
10574
10717
  /**
10575
- * A participant's permission has changed. Currently only fired on LocalParticipant.
10718
+ * A participant's permission has changed.
10576
10719
  * args: (prevPermissions: [[ParticipantPermission]], participant: [[Participant]])
10577
10720
  */
10578
10721
  RoomEvent["ParticipantPermissionsChanged"] = "participantPermissionsChanged";
@@ -10753,7 +10896,7 @@ var ParticipantEvent;
10753
10896
  /** @internal */
10754
10897
  ParticipantEvent["AudioStreamAcquired"] = "audioStreamAcquired";
10755
10898
  /**
10756
- * A participant's permission has changed. Currently only fired on LocalParticipant.
10899
+ * A participant's permission has changed.
10757
10900
  * args: (prevPermissions: [[ParticipantPermission]])
10758
10901
  */
10759
10902
  ParticipantEvent["ParticipantPermissionsChanged"] = "participantPermissionsChanged";
@@ -10995,7 +11138,7 @@ function getOSVersion(ua) {
10995
11138
  return ua.includes('mac os') ? getMatch(/\(.+?(\d+_\d+(:?_\d+)?)/, ua, 1).replace(/_/g, '.') : undefined;
10996
11139
  }
10997
11140
 
10998
- var version$1 = "2.5.6";
11141
+ var version$1 = "2.5.7";
10999
11142
 
11000
11143
  const version = version$1;
11001
11144
  const protocolVersion = 15;
@@ -13253,12 +13396,12 @@ class SignalClient {
13253
13396
  const resp = yield fetch("http".concat(url.substring(2), "/validate").concat(params));
13254
13397
  if (resp.status.toFixed(0).startsWith('4')) {
13255
13398
  const msg = yield resp.text();
13256
- reject(new ConnectionError(msg, 0 /* ConnectionErrorReason.NotAllowed */, resp.status));
13399
+ reject(new ConnectionError(msg, ConnectionErrorReason.NotAllowed, resp.status));
13257
13400
  } else {
13258
- reject(new ConnectionError('Internal error', 2 /* ConnectionErrorReason.InternalError */, resp.status));
13401
+ reject(new ConnectionError('Internal error', ConnectionErrorReason.InternalError, resp.status));
13259
13402
  }
13260
13403
  } catch (e) {
13261
- reject(new ConnectionError('server was not reachable', 1 /* ConnectionErrorReason.ServerUnreachable */));
13404
+ reject(new ConnectionError('server was not reachable', ConnectionErrorReason.ServerUnreachable));
13262
13405
  }
13263
13406
  return;
13264
13407
  }
@@ -13309,7 +13452,7 @@ class SignalClient {
13309
13452
  shouldProcessMessage = true;
13310
13453
  }
13311
13454
  } else if (this.isEstablishingConnection && resp.message.case === 'leave') {
13312
- reject(new ConnectionError('Received leave request while trying to (re)connect', 4 /* ConnectionErrorReason.LeaveRequest */));
13455
+ reject(new ConnectionError('Received leave request while trying to (re)connect', ConnectionErrorReason.LeaveRequest));
13313
13456
  } else if (!opts.reconnect) {
13314
13457
  // non-reconnect case, should receive join response first
13315
13458
  reject(new ConnectionError("did not receive join response, got ".concat((_c = resp.message) === null || _c === void 0 ? void 0 : _c.case, " instead")));
@@ -13795,671 +13938,699 @@ function createConnectionParams(token, info, opts) {
13795
13938
  return "?".concat(params.toString());
13796
13939
  }
13797
13940
 
13798
- var parser$1 = {};
13799
-
13800
- var grammar$2 = {exports: {}};
13801
-
13802
- var grammar$1 = grammar$2.exports = {
13803
- v: [{
13804
- name: 'version',
13805
- reg: /^(\d*)$/
13806
- }],
13807
- o: [{
13808
- // o=- 20518 0 IN IP4 203.0.113.1
13809
- // NB: sessionId will be a String in most cases because it is huge
13810
- name: 'origin',
13811
- reg: /^(\S*) (\d*) (\d*) (\S*) IP(\d) (\S*)/,
13812
- names: ['username', 'sessionId', 'sessionVersion', 'netType', 'ipVer', 'address'],
13813
- format: '%s %s %d %s IP%d %s'
13814
- }],
13815
- // default parsing of these only (though some of these feel outdated)
13816
- s: [{
13817
- name: 'name'
13818
- }],
13819
- i: [{
13820
- name: 'description'
13821
- }],
13822
- u: [{
13823
- name: 'uri'
13824
- }],
13825
- e: [{
13826
- name: 'email'
13827
- }],
13828
- p: [{
13829
- name: 'phone'
13830
- }],
13831
- z: [{
13832
- name: 'timezones'
13833
- }],
13834
- // TODO: this one can actually be parsed properly...
13835
- r: [{
13836
- name: 'repeats'
13837
- }],
13838
- // TODO: this one can also be parsed properly
13839
- // k: [{}], // outdated thing ignored
13840
- t: [{
13841
- // t=0 0
13842
- name: 'timing',
13843
- reg: /^(\d*) (\d*)/,
13844
- names: ['start', 'stop'],
13845
- format: '%d %d'
13846
- }],
13847
- c: [{
13848
- // c=IN IP4 10.47.197.26
13849
- name: 'connection',
13850
- reg: /^IN IP(\d) (\S*)/,
13851
- names: ['version', 'ip'],
13852
- format: 'IN IP%d %s'
13853
- }],
13854
- b: [{
13855
- // b=AS:4000
13856
- push: 'bandwidth',
13857
- reg: /^(TIAS|AS|CT|RR|RS):(\d*)/,
13858
- names: ['type', 'limit'],
13859
- format: '%s:%s'
13860
- }],
13861
- m: [{
13862
- // m=video 51744 RTP/AVP 126 97 98 34 31
13863
- // NB: special - pushes to session
13864
- // TODO: rtp/fmtp should be filtered by the payloads found here?
13865
- reg: /^(\w*) (\d*) ([\w/]*)(?: (.*))?/,
13866
- names: ['type', 'port', 'protocol', 'payloads'],
13867
- format: '%s %d %s %s'
13868
- }],
13869
- a: [{
13870
- // a=rtpmap:110 opus/48000/2
13871
- push: 'rtp',
13872
- reg: /^rtpmap:(\d*) ([\w\-.]*)(?:\s*\/(\d*)(?:\s*\/(\S*))?)?/,
13873
- names: ['payload', 'codec', 'rate', 'encoding'],
13874
- format: function (o) {
13875
- return o.encoding ? 'rtpmap:%d %s/%s/%s' : o.rate ? 'rtpmap:%d %s/%s' : 'rtpmap:%d %s';
13876
- }
13877
- }, {
13878
- // a=fmtp:108 profile-level-id=24;object=23;bitrate=64000
13879
- // a=fmtp:111 minptime=10; useinbandfec=1
13880
- push: 'fmtp',
13881
- reg: /^fmtp:(\d*) ([\S| ]*)/,
13882
- names: ['payload', 'config'],
13883
- format: 'fmtp:%d %s'
13884
- }, {
13885
- // a=control:streamid=0
13886
- name: 'control',
13887
- reg: /^control:(.*)/,
13888
- format: 'control:%s'
13889
- }, {
13890
- // a=rtcp:65179 IN IP4 193.84.77.194
13891
- name: 'rtcp',
13892
- reg: /^rtcp:(\d*)(?: (\S*) IP(\d) (\S*))?/,
13893
- names: ['port', 'netType', 'ipVer', 'address'],
13894
- format: function (o) {
13895
- return o.address != null ? 'rtcp:%d %s IP%d %s' : 'rtcp:%d';
13896
- }
13897
- }, {
13898
- // a=rtcp-fb:98 trr-int 100
13899
- push: 'rtcpFbTrrInt',
13900
- reg: /^rtcp-fb:(\*|\d*) trr-int (\d*)/,
13901
- names: ['payload', 'value'],
13902
- format: 'rtcp-fb:%s trr-int %d'
13903
- }, {
13904
- // a=rtcp-fb:98 nack rpsi
13905
- push: 'rtcpFb',
13906
- reg: /^rtcp-fb:(\*|\d*) ([\w-_]*)(?: ([\w-_]*))?/,
13907
- names: ['payload', 'type', 'subtype'],
13908
- format: function (o) {
13909
- return o.subtype != null ? 'rtcp-fb:%s %s %s' : 'rtcp-fb:%s %s';
13910
- }
13911
- }, {
13912
- // a=extmap:2 urn:ietf:params:rtp-hdrext:toffset
13913
- // a=extmap:1/recvonly URI-gps-string
13914
- // a=extmap:3 urn:ietf:params:rtp-hdrext:encrypt urn:ietf:params:rtp-hdrext:smpte-tc 25@600/24
13915
- push: 'ext',
13916
- reg: /^extmap:(\d+)(?:\/(\w+))?(?: (urn:ietf:params:rtp-hdrext:encrypt))? (\S*)(?: (\S*))?/,
13917
- names: ['value', 'direction', 'encrypt-uri', 'uri', 'config'],
13918
- format: function (o) {
13919
- return 'extmap:%d' + (o.direction ? '/%s' : '%v') + (o['encrypt-uri'] ? ' %s' : '%v') + ' %s' + (o.config ? ' %s' : '');
13920
- }
13921
- }, {
13922
- // a=extmap-allow-mixed
13923
- name: 'extmapAllowMixed',
13924
- reg: /^(extmap-allow-mixed)/
13925
- }, {
13926
- // a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:PS1uQCVeeCFCanVmcjkpPywjNWhcYD0mXXtxaVBR|2^20|1:32
13927
- push: 'crypto',
13928
- reg: /^crypto:(\d*) ([\w_]*) (\S*)(?: (\S*))?/,
13929
- names: ['id', 'suite', 'config', 'sessionConfig'],
13930
- format: function (o) {
13931
- return o.sessionConfig != null ? 'crypto:%d %s %s %s' : 'crypto:%d %s %s';
13932
- }
13933
- }, {
13934
- // a=setup:actpass
13935
- name: 'setup',
13936
- reg: /^setup:(\w*)/,
13937
- format: 'setup:%s'
13938
- }, {
13939
- // a=connection:new
13940
- name: 'connectionType',
13941
- reg: /^connection:(new|existing)/,
13942
- format: 'connection:%s'
13943
- }, {
13944
- // a=mid:1
13945
- name: 'mid',
13946
- reg: /^mid:([^\s]*)/,
13947
- format: 'mid:%s'
13948
- }, {
13949
- // a=msid:0c8b064d-d807-43b4-b434-f92a889d8587 98178685-d409-46e0-8e16-7ef0db0db64a
13950
- name: 'msid',
13951
- reg: /^msid:(.*)/,
13952
- format: 'msid:%s'
13953
- }, {
13954
- // a=ptime:20
13955
- name: 'ptime',
13956
- reg: /^ptime:(\d*(?:\.\d*)*)/,
13957
- format: 'ptime:%d'
13958
- }, {
13959
- // a=maxptime:60
13960
- name: 'maxptime',
13961
- reg: /^maxptime:(\d*(?:\.\d*)*)/,
13962
- format: 'maxptime:%d'
13963
- }, {
13964
- // a=sendrecv
13965
- name: 'direction',
13966
- reg: /^(sendrecv|recvonly|sendonly|inactive)/
13967
- }, {
13968
- // a=ice-lite
13969
- name: 'icelite',
13970
- reg: /^(ice-lite)/
13971
- }, {
13972
- // a=ice-ufrag:F7gI
13973
- name: 'iceUfrag',
13974
- reg: /^ice-ufrag:(\S*)/,
13975
- format: 'ice-ufrag:%s'
13976
- }, {
13977
- // a=ice-pwd:x9cml/YzichV2+XlhiMu8g
13978
- name: 'icePwd',
13979
- reg: /^ice-pwd:(\S*)/,
13980
- format: 'ice-pwd:%s'
13981
- }, {
13982
- // a=fingerprint:SHA-1 00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33
13983
- name: 'fingerprint',
13984
- reg: /^fingerprint:(\S*) (\S*)/,
13985
- names: ['type', 'hash'],
13986
- format: 'fingerprint:%s %s'
13987
- }, {
13988
- // a=candidate:0 1 UDP 2113667327 203.0.113.1 54400 typ host
13989
- // a=candidate:1162875081 1 udp 2113937151 192.168.34.75 60017 typ host generation 0 network-id 3 network-cost 10
13990
- // a=candidate:3289912957 2 udp 1845501695 193.84.77.194 60017 typ srflx raddr 192.168.34.75 rport 60017 generation 0 network-id 3 network-cost 10
13991
- // a=candidate:229815620 1 tcp 1518280447 192.168.150.19 60017 typ host tcptype active generation 0 network-id 3 network-cost 10
13992
- // a=candidate:3289912957 2 tcp 1845501695 193.84.77.194 60017 typ srflx raddr 192.168.34.75 rport 60017 tcptype passive generation 0 network-id 3 network-cost 10
13993
- push: 'candidates',
13994
- reg: /^candidate:(\S*) (\d*) (\S*) (\d*) (\S*) (\d*) typ (\S*)(?: raddr (\S*) rport (\d*))?(?: tcptype (\S*))?(?: generation (\d*))?(?: network-id (\d*))?(?: network-cost (\d*))?/,
13995
- names: ['foundation', 'component', 'transport', 'priority', 'ip', 'port', 'type', 'raddr', 'rport', 'tcptype', 'generation', 'network-id', 'network-cost'],
13996
- format: function (o) {
13997
- var str = 'candidate:%s %d %s %d %s %d typ %s';
13998
- str += o.raddr != null ? ' raddr %s rport %d' : '%v%v';
13999
-
14000
- // NB: candidate has three optional chunks, so %void middles one if it's missing
14001
- str += o.tcptype != null ? ' tcptype %s' : '%v';
14002
- if (o.generation != null) {
14003
- str += ' generation %d';
14004
- }
14005
- str += o['network-id'] != null ? ' network-id %d' : '%v';
14006
- str += o['network-cost'] != null ? ' network-cost %d' : '%v';
14007
- return str;
14008
- }
14009
- }, {
14010
- // a=end-of-candidates (keep after the candidates line for readability)
14011
- name: 'endOfCandidates',
14012
- reg: /^(end-of-candidates)/
14013
- }, {
14014
- // a=remote-candidates:1 203.0.113.1 54400 2 203.0.113.1 54401 ...
14015
- name: 'remoteCandidates',
14016
- reg: /^remote-candidates:(.*)/,
14017
- format: 'remote-candidates:%s'
14018
- }, {
14019
- // a=ice-options:google-ice
14020
- name: 'iceOptions',
14021
- reg: /^ice-options:(\S*)/,
14022
- format: 'ice-options:%s'
14023
- }, {
14024
- // a=ssrc:2566107569 cname:t9YU8M1UxTF8Y1A1
14025
- push: 'ssrcs',
14026
- reg: /^ssrc:(\d*) ([\w_-]*)(?::(.*))?/,
14027
- names: ['id', 'attribute', 'value'],
14028
- format: function (o) {
14029
- var str = 'ssrc:%d';
14030
- if (o.attribute != null) {
14031
- str += ' %s';
14032
- if (o.value != null) {
14033
- str += ':%s';
14034
- }
14035
- }
14036
- return str;
14037
- }
14038
- }, {
14039
- // a=ssrc-group:FEC 1 2
14040
- // a=ssrc-group:FEC-FR 3004364195 1080772241
14041
- push: 'ssrcGroups',
14042
- // token-char = %x21 / %x23-27 / %x2A-2B / %x2D-2E / %x30-39 / %x41-5A / %x5E-7E
14043
- reg: /^ssrc-group:([\x21\x23\x24\x25\x26\x27\x2A\x2B\x2D\x2E\w]*) (.*)/,
14044
- names: ['semantics', 'ssrcs'],
14045
- format: 'ssrc-group:%s %s'
14046
- }, {
14047
- // a=msid-semantic: WMS Jvlam5X3SX1OP6pn20zWogvaKJz5Hjf9OnlV
14048
- name: 'msidSemantic',
14049
- reg: /^msid-semantic:\s?(\w*) (\S*)/,
14050
- names: ['semantic', 'token'],
14051
- format: 'msid-semantic: %s %s' // space after ':' is not accidental
14052
- }, {
14053
- // a=group:BUNDLE audio video
14054
- push: 'groups',
14055
- reg: /^group:(\w*) (.*)/,
14056
- names: ['type', 'mids'],
14057
- format: 'group:%s %s'
14058
- }, {
14059
- // a=rtcp-mux
14060
- name: 'rtcpMux',
14061
- reg: /^(rtcp-mux)/
14062
- }, {
14063
- // a=rtcp-rsize
14064
- name: 'rtcpRsize',
14065
- reg: /^(rtcp-rsize)/
14066
- }, {
14067
- // a=sctpmap:5000 webrtc-datachannel 1024
14068
- name: 'sctpmap',
14069
- reg: /^sctpmap:([\w_/]*) (\S*)(?: (\S*))?/,
14070
- names: ['sctpmapNumber', 'app', 'maxMessageSize'],
14071
- format: function (o) {
14072
- return o.maxMessageSize != null ? 'sctpmap:%s %s %s' : 'sctpmap:%s %s';
14073
- }
14074
- }, {
14075
- // a=x-google-flag:conference
14076
- name: 'xGoogleFlag',
14077
- reg: /^x-google-flag:([^\s]*)/,
14078
- format: 'x-google-flag:%s'
14079
- }, {
14080
- // a=rid:1 send max-width=1280;max-height=720;max-fps=30;depend=0
14081
- push: 'rids',
14082
- reg: /^rid:([\d\w]+) (\w+)(?: ([\S| ]*))?/,
14083
- names: ['id', 'direction', 'params'],
14084
- format: function (o) {
14085
- return o.params ? 'rid:%s %s %s' : 'rid:%s %s';
14086
- }
14087
- }, {
14088
- // a=imageattr:97 send [x=800,y=640,sar=1.1,q=0.6] [x=480,y=320] recv [x=330,y=250]
14089
- // a=imageattr:* send [x=800,y=640] recv *
14090
- // a=imageattr:100 recv [x=320,y=240]
14091
- push: 'imageattrs',
14092
- reg: new RegExp(
14093
- // a=imageattr:97
14094
- '^imageattr:(\\d+|\\*)' +
14095
- // send [x=800,y=640,sar=1.1,q=0.6] [x=480,y=320]
14096
- '[\\s\\t]+(send|recv)[\\s\\t]+(\\*|\\[\\S+\\](?:[\\s\\t]+\\[\\S+\\])*)' +
14097
- // recv [x=330,y=250]
14098
- '(?:[\\s\\t]+(recv|send)[\\s\\t]+(\\*|\\[\\S+\\](?:[\\s\\t]+\\[\\S+\\])*))?'),
14099
- names: ['pt', 'dir1', 'attrs1', 'dir2', 'attrs2'],
14100
- format: function (o) {
14101
- return 'imageattr:%s %s %s' + (o.dir2 ? ' %s %s' : '');
14102
- }
14103
- }, {
14104
- // a=simulcast:send 1,2,3;~4,~5 recv 6;~7,~8
14105
- // a=simulcast:recv 1;4,5 send 6;7
14106
- name: 'simulcast',
14107
- reg: new RegExp(
14108
- // a=simulcast:
14109
- '^simulcast:' +
14110
- // send 1,2,3;~4,~5
14111
- '(send|recv) ([a-zA-Z0-9\\-_~;,]+)' +
14112
- // space + recv 6;~7,~8
14113
- '(?:\\s?(send|recv) ([a-zA-Z0-9\\-_~;,]+))?' +
14114
- // end
14115
- '$'),
14116
- names: ['dir1', 'list1', 'dir2', 'list2'],
14117
- format: function (o) {
14118
- return 'simulcast:%s %s' + (o.dir2 ? ' %s %s' : '');
14119
- }
14120
- }, {
14121
- // old simulcast draft 03 (implemented by Firefox)
14122
- // https://tools.ietf.org/html/draft-ietf-mmusic-sdp-simulcast-03
14123
- // a=simulcast: recv pt=97;98 send pt=97
14124
- // a=simulcast: send rid=5;6;7 paused=6,7
14125
- name: 'simulcast_03',
14126
- reg: /^simulcast:[\s\t]+([\S+\s\t]+)$/,
14127
- names: ['value'],
14128
- format: 'simulcast: %s'
14129
- }, {
14130
- // a=framerate:25
14131
- // a=framerate:29.97
14132
- name: 'framerate',
14133
- reg: /^framerate:(\d+(?:$|\.\d+))/,
14134
- format: 'framerate:%s'
14135
- }, {
14136
- // RFC4570
14137
- // a=source-filter: incl IN IP4 239.5.2.31 10.1.15.5
14138
- name: 'sourceFilter',
14139
- reg: /^source-filter: *(excl|incl) (\S*) (IP4|IP6|\*) (\S*) (.*)/,
14140
- names: ['filterMode', 'netType', 'addressTypes', 'destAddress', 'srcList'],
14141
- format: 'source-filter: %s %s %s %s %s'
14142
- }, {
14143
- // a=bundle-only
14144
- name: 'bundleOnly',
14145
- reg: /^(bundle-only)/
14146
- }, {
14147
- // a=label:1
14148
- name: 'label',
14149
- reg: /^label:(.+)/,
14150
- format: 'label:%s'
14151
- }, {
14152
- // RFC version 26 for SCTP over DTLS
14153
- // https://tools.ietf.org/html/draft-ietf-mmusic-sctp-sdp-26#section-5
14154
- name: 'sctpPort',
14155
- reg: /^sctp-port:(\d+)$/,
14156
- format: 'sctp-port:%s'
14157
- }, {
14158
- // RFC version 26 for SCTP over DTLS
14159
- // https://tools.ietf.org/html/draft-ietf-mmusic-sctp-sdp-26#section-6
14160
- name: 'maxMessageSize',
14161
- reg: /^max-message-size:(\d+)$/,
14162
- format: 'max-message-size:%s'
14163
- }, {
14164
- // RFC7273
14165
- // a=ts-refclk:ptp=IEEE1588-2008:39-A7-94-FF-FE-07-CB-D0:37
14166
- push: 'tsRefClocks',
14167
- reg: /^ts-refclk:([^\s=]*)(?:=(\S*))?/,
14168
- names: ['clksrc', 'clksrcExt'],
14169
- format: function (o) {
14170
- return 'ts-refclk:%s' + (o.clksrcExt != null ? '=%s' : '');
14171
- }
14172
- }, {
14173
- // RFC7273
14174
- // a=mediaclk:direct=963214424
14175
- name: 'mediaClk',
14176
- reg: /^mediaclk:(?:id=(\S*))? *([^\s=]*)(?:=(\S*))?(?: *rate=(\d+)\/(\d+))?/,
14177
- names: ['id', 'mediaClockName', 'mediaClockValue', 'rateNumerator', 'rateDenominator'],
14178
- format: function (o) {
14179
- var str = 'mediaclk:';
14180
- str += o.id != null ? 'id=%s %s' : '%v%s';
14181
- str += o.mediaClockValue != null ? '=%s' : '';
14182
- str += o.rateNumerator != null ? ' rate=%s' : '';
14183
- str += o.rateDenominator != null ? '/%s' : '';
14184
- return str;
14185
- }
14186
- }, {
14187
- // a=keywds:keywords
14188
- name: 'keywords',
14189
- reg: /^keywds:(.+)$/,
14190
- format: 'keywds:%s'
14191
- }, {
14192
- // a=content:main
14193
- name: 'content',
14194
- reg: /^content:(.+)/,
14195
- format: 'content:%s'
14196
- },
14197
- // BFCP https://tools.ietf.org/html/rfc4583
14198
- {
14199
- // a=floorctrl:c-s
14200
- name: 'bfcpFloorCtrl',
14201
- reg: /^floorctrl:(c-only|s-only|c-s)/,
14202
- format: 'floorctrl:%s'
14203
- }, {
14204
- // a=confid:1
14205
- name: 'bfcpConfId',
14206
- reg: /^confid:(\d+)/,
14207
- format: 'confid:%s'
14208
- }, {
14209
- // a=userid:1
14210
- name: 'bfcpUserId',
14211
- reg: /^userid:(\d+)/,
14212
- format: 'userid:%s'
14213
- }, {
14214
- // a=floorid:1
14215
- name: 'bfcpFloorId',
14216
- reg: /^floorid:(.+) (?:m-stream|mstrm):(.+)/,
14217
- names: ['id', 'mStream'],
14218
- format: 'floorid:%s mstrm:%s'
14219
- }, {
14220
- // any a= that we don't understand is kept verbatim on media.invalid
14221
- push: 'invalid',
14222
- names: ['value']
14223
- }]
14224
- };
13941
+ var lib = {};
13942
+
13943
+ var parser = {};
13944
+
13945
+ var grammar = {exports: {}};
13946
+
13947
+ var hasRequiredGrammar;
13948
+ function requireGrammar() {
13949
+ if (hasRequiredGrammar) return grammar.exports;
13950
+ hasRequiredGrammar = 1;
13951
+ var grammar$1 = grammar.exports = {
13952
+ v: [{
13953
+ name: 'version',
13954
+ reg: /^(\d*)$/
13955
+ }],
13956
+ o: [{
13957
+ // o=- 20518 0 IN IP4 203.0.113.1
13958
+ // NB: sessionId will be a String in most cases because it is huge
13959
+ name: 'origin',
13960
+ reg: /^(\S*) (\d*) (\d*) (\S*) IP(\d) (\S*)/,
13961
+ names: ['username', 'sessionId', 'sessionVersion', 'netType', 'ipVer', 'address'],
13962
+ format: '%s %s %d %s IP%d %s'
13963
+ }],
13964
+ // default parsing of these only (though some of these feel outdated)
13965
+ s: [{
13966
+ name: 'name'
13967
+ }],
13968
+ i: [{
13969
+ name: 'description'
13970
+ }],
13971
+ u: [{
13972
+ name: 'uri'
13973
+ }],
13974
+ e: [{
13975
+ name: 'email'
13976
+ }],
13977
+ p: [{
13978
+ name: 'phone'
13979
+ }],
13980
+ z: [{
13981
+ name: 'timezones'
13982
+ }],
13983
+ // TODO: this one can actually be parsed properly...
13984
+ r: [{
13985
+ name: 'repeats'
13986
+ }],
13987
+ // TODO: this one can also be parsed properly
13988
+ // k: [{}], // outdated thing ignored
13989
+ t: [{
13990
+ // t=0 0
13991
+ name: 'timing',
13992
+ reg: /^(\d*) (\d*)/,
13993
+ names: ['start', 'stop'],
13994
+ format: '%d %d'
13995
+ }],
13996
+ c: [{
13997
+ // c=IN IP4 10.47.197.26
13998
+ name: 'connection',
13999
+ reg: /^IN IP(\d) (\S*)/,
14000
+ names: ['version', 'ip'],
14001
+ format: 'IN IP%d %s'
14002
+ }],
14003
+ b: [{
14004
+ // b=AS:4000
14005
+ push: 'bandwidth',
14006
+ reg: /^(TIAS|AS|CT|RR|RS):(\d*)/,
14007
+ names: ['type', 'limit'],
14008
+ format: '%s:%s'
14009
+ }],
14010
+ m: [{
14011
+ // m=video 51744 RTP/AVP 126 97 98 34 31
14012
+ // NB: special - pushes to session
14013
+ // TODO: rtp/fmtp should be filtered by the payloads found here?
14014
+ reg: /^(\w*) (\d*) ([\w/]*)(?: (.*))?/,
14015
+ names: ['type', 'port', 'protocol', 'payloads'],
14016
+ format: '%s %d %s %s'
14017
+ }],
14018
+ a: [{
14019
+ // a=rtpmap:110 opus/48000/2
14020
+ push: 'rtp',
14021
+ reg: /^rtpmap:(\d*) ([\w\-.]*)(?:\s*\/(\d*)(?:\s*\/(\S*))?)?/,
14022
+ names: ['payload', 'codec', 'rate', 'encoding'],
14023
+ format: function (o) {
14024
+ return o.encoding ? 'rtpmap:%d %s/%s/%s' : o.rate ? 'rtpmap:%d %s/%s' : 'rtpmap:%d %s';
14025
+ }
14026
+ }, {
14027
+ // a=fmtp:108 profile-level-id=24;object=23;bitrate=64000
14028
+ // a=fmtp:111 minptime=10; useinbandfec=1
14029
+ push: 'fmtp',
14030
+ reg: /^fmtp:(\d*) ([\S| ]*)/,
14031
+ names: ['payload', 'config'],
14032
+ format: 'fmtp:%d %s'
14033
+ }, {
14034
+ // a=control:streamid=0
14035
+ name: 'control',
14036
+ reg: /^control:(.*)/,
14037
+ format: 'control:%s'
14038
+ }, {
14039
+ // a=rtcp:65179 IN IP4 193.84.77.194
14040
+ name: 'rtcp',
14041
+ reg: /^rtcp:(\d*)(?: (\S*) IP(\d) (\S*))?/,
14042
+ names: ['port', 'netType', 'ipVer', 'address'],
14043
+ format: function (o) {
14044
+ return o.address != null ? 'rtcp:%d %s IP%d %s' : 'rtcp:%d';
14045
+ }
14046
+ }, {
14047
+ // a=rtcp-fb:98 trr-int 100
14048
+ push: 'rtcpFbTrrInt',
14049
+ reg: /^rtcp-fb:(\*|\d*) trr-int (\d*)/,
14050
+ names: ['payload', 'value'],
14051
+ format: 'rtcp-fb:%s trr-int %d'
14052
+ }, {
14053
+ // a=rtcp-fb:98 nack rpsi
14054
+ push: 'rtcpFb',
14055
+ reg: /^rtcp-fb:(\*|\d*) ([\w-_]*)(?: ([\w-_]*))?/,
14056
+ names: ['payload', 'type', 'subtype'],
14057
+ format: function (o) {
14058
+ return o.subtype != null ? 'rtcp-fb:%s %s %s' : 'rtcp-fb:%s %s';
14059
+ }
14060
+ }, {
14061
+ // a=extmap:2 urn:ietf:params:rtp-hdrext:toffset
14062
+ // a=extmap:1/recvonly URI-gps-string
14063
+ // a=extmap:3 urn:ietf:params:rtp-hdrext:encrypt urn:ietf:params:rtp-hdrext:smpte-tc 25@600/24
14064
+ push: 'ext',
14065
+ reg: /^extmap:(\d+)(?:\/(\w+))?(?: (urn:ietf:params:rtp-hdrext:encrypt))? (\S*)(?: (\S*))?/,
14066
+ names: ['value', 'direction', 'encrypt-uri', 'uri', 'config'],
14067
+ format: function (o) {
14068
+ return 'extmap:%d' + (o.direction ? '/%s' : '%v') + (o['encrypt-uri'] ? ' %s' : '%v') + ' %s' + (o.config ? ' %s' : '');
14069
+ }
14070
+ }, {
14071
+ // a=extmap-allow-mixed
14072
+ name: 'extmapAllowMixed',
14073
+ reg: /^(extmap-allow-mixed)/
14074
+ }, {
14075
+ // a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:PS1uQCVeeCFCanVmcjkpPywjNWhcYD0mXXtxaVBR|2^20|1:32
14076
+ push: 'crypto',
14077
+ reg: /^crypto:(\d*) ([\w_]*) (\S*)(?: (\S*))?/,
14078
+ names: ['id', 'suite', 'config', 'sessionConfig'],
14079
+ format: function (o) {
14080
+ return o.sessionConfig != null ? 'crypto:%d %s %s %s' : 'crypto:%d %s %s';
14081
+ }
14082
+ }, {
14083
+ // a=setup:actpass
14084
+ name: 'setup',
14085
+ reg: /^setup:(\w*)/,
14086
+ format: 'setup:%s'
14087
+ }, {
14088
+ // a=connection:new
14089
+ name: 'connectionType',
14090
+ reg: /^connection:(new|existing)/,
14091
+ format: 'connection:%s'
14092
+ }, {
14093
+ // a=mid:1
14094
+ name: 'mid',
14095
+ reg: /^mid:([^\s]*)/,
14096
+ format: 'mid:%s'
14097
+ }, {
14098
+ // a=msid:0c8b064d-d807-43b4-b434-f92a889d8587 98178685-d409-46e0-8e16-7ef0db0db64a
14099
+ name: 'msid',
14100
+ reg: /^msid:(.*)/,
14101
+ format: 'msid:%s'
14102
+ }, {
14103
+ // a=ptime:20
14104
+ name: 'ptime',
14105
+ reg: /^ptime:(\d*(?:\.\d*)*)/,
14106
+ format: 'ptime:%d'
14107
+ }, {
14108
+ // a=maxptime:60
14109
+ name: 'maxptime',
14110
+ reg: /^maxptime:(\d*(?:\.\d*)*)/,
14111
+ format: 'maxptime:%d'
14112
+ }, {
14113
+ // a=sendrecv
14114
+ name: 'direction',
14115
+ reg: /^(sendrecv|recvonly|sendonly|inactive)/
14116
+ }, {
14117
+ // a=ice-lite
14118
+ name: 'icelite',
14119
+ reg: /^(ice-lite)/
14120
+ }, {
14121
+ // a=ice-ufrag:F7gI
14122
+ name: 'iceUfrag',
14123
+ reg: /^ice-ufrag:(\S*)/,
14124
+ format: 'ice-ufrag:%s'
14125
+ }, {
14126
+ // a=ice-pwd:x9cml/YzichV2+XlhiMu8g
14127
+ name: 'icePwd',
14128
+ reg: /^ice-pwd:(\S*)/,
14129
+ format: 'ice-pwd:%s'
14130
+ }, {
14131
+ // a=fingerprint:SHA-1 00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33
14132
+ name: 'fingerprint',
14133
+ reg: /^fingerprint:(\S*) (\S*)/,
14134
+ names: ['type', 'hash'],
14135
+ format: 'fingerprint:%s %s'
14136
+ }, {
14137
+ // a=candidate:0 1 UDP 2113667327 203.0.113.1 54400 typ host
14138
+ // a=candidate:1162875081 1 udp 2113937151 192.168.34.75 60017 typ host generation 0 network-id 3 network-cost 10
14139
+ // a=candidate:3289912957 2 udp 1845501695 193.84.77.194 60017 typ srflx raddr 192.168.34.75 rport 60017 generation 0 network-id 3 network-cost 10
14140
+ // a=candidate:229815620 1 tcp 1518280447 192.168.150.19 60017 typ host tcptype active generation 0 network-id 3 network-cost 10
14141
+ // a=candidate:3289912957 2 tcp 1845501695 193.84.77.194 60017 typ srflx raddr 192.168.34.75 rport 60017 tcptype passive generation 0 network-id 3 network-cost 10
14142
+ push: 'candidates',
14143
+ reg: /^candidate:(\S*) (\d*) (\S*) (\d*) (\S*) (\d*) typ (\S*)(?: raddr (\S*) rport (\d*))?(?: tcptype (\S*))?(?: generation (\d*))?(?: network-id (\d*))?(?: network-cost (\d*))?/,
14144
+ names: ['foundation', 'component', 'transport', 'priority', 'ip', 'port', 'type', 'raddr', 'rport', 'tcptype', 'generation', 'network-id', 'network-cost'],
14145
+ format: function (o) {
14146
+ var str = 'candidate:%s %d %s %d %s %d typ %s';
14147
+ str += o.raddr != null ? ' raddr %s rport %d' : '%v%v';
14148
+
14149
+ // NB: candidate has three optional chunks, so %void middles one if it's missing
14150
+ str += o.tcptype != null ? ' tcptype %s' : '%v';
14151
+ if (o.generation != null) {
14152
+ str += ' generation %d';
14153
+ }
14154
+ str += o['network-id'] != null ? ' network-id %d' : '%v';
14155
+ str += o['network-cost'] != null ? ' network-cost %d' : '%v';
14156
+ return str;
14157
+ }
14158
+ }, {
14159
+ // a=end-of-candidates (keep after the candidates line for readability)
14160
+ name: 'endOfCandidates',
14161
+ reg: /^(end-of-candidates)/
14162
+ }, {
14163
+ // a=remote-candidates:1 203.0.113.1 54400 2 203.0.113.1 54401 ...
14164
+ name: 'remoteCandidates',
14165
+ reg: /^remote-candidates:(.*)/,
14166
+ format: 'remote-candidates:%s'
14167
+ }, {
14168
+ // a=ice-options:google-ice
14169
+ name: 'iceOptions',
14170
+ reg: /^ice-options:(\S*)/,
14171
+ format: 'ice-options:%s'
14172
+ }, {
14173
+ // a=ssrc:2566107569 cname:t9YU8M1UxTF8Y1A1
14174
+ push: 'ssrcs',
14175
+ reg: /^ssrc:(\d*) ([\w_-]*)(?::(.*))?/,
14176
+ names: ['id', 'attribute', 'value'],
14177
+ format: function (o) {
14178
+ var str = 'ssrc:%d';
14179
+ if (o.attribute != null) {
14180
+ str += ' %s';
14181
+ if (o.value != null) {
14182
+ str += ':%s';
14183
+ }
14184
+ }
14185
+ return str;
14186
+ }
14187
+ }, {
14188
+ // a=ssrc-group:FEC 1 2
14189
+ // a=ssrc-group:FEC-FR 3004364195 1080772241
14190
+ push: 'ssrcGroups',
14191
+ // token-char = %x21 / %x23-27 / %x2A-2B / %x2D-2E / %x30-39 / %x41-5A / %x5E-7E
14192
+ reg: /^ssrc-group:([\x21\x23\x24\x25\x26\x27\x2A\x2B\x2D\x2E\w]*) (.*)/,
14193
+ names: ['semantics', 'ssrcs'],
14194
+ format: 'ssrc-group:%s %s'
14195
+ }, {
14196
+ // a=msid-semantic: WMS Jvlam5X3SX1OP6pn20zWogvaKJz5Hjf9OnlV
14197
+ name: 'msidSemantic',
14198
+ reg: /^msid-semantic:\s?(\w*) (\S*)/,
14199
+ names: ['semantic', 'token'],
14200
+ format: 'msid-semantic: %s %s' // space after ':' is not accidental
14201
+ }, {
14202
+ // a=group:BUNDLE audio video
14203
+ push: 'groups',
14204
+ reg: /^group:(\w*) (.*)/,
14205
+ names: ['type', 'mids'],
14206
+ format: 'group:%s %s'
14207
+ }, {
14208
+ // a=rtcp-mux
14209
+ name: 'rtcpMux',
14210
+ reg: /^(rtcp-mux)/
14211
+ }, {
14212
+ // a=rtcp-rsize
14213
+ name: 'rtcpRsize',
14214
+ reg: /^(rtcp-rsize)/
14215
+ }, {
14216
+ // a=sctpmap:5000 webrtc-datachannel 1024
14217
+ name: 'sctpmap',
14218
+ reg: /^sctpmap:([\w_/]*) (\S*)(?: (\S*))?/,
14219
+ names: ['sctpmapNumber', 'app', 'maxMessageSize'],
14220
+ format: function (o) {
14221
+ return o.maxMessageSize != null ? 'sctpmap:%s %s %s' : 'sctpmap:%s %s';
14222
+ }
14223
+ }, {
14224
+ // a=x-google-flag:conference
14225
+ name: 'xGoogleFlag',
14226
+ reg: /^x-google-flag:([^\s]*)/,
14227
+ format: 'x-google-flag:%s'
14228
+ }, {
14229
+ // a=rid:1 send max-width=1280;max-height=720;max-fps=30;depend=0
14230
+ push: 'rids',
14231
+ reg: /^rid:([\d\w]+) (\w+)(?: ([\S| ]*))?/,
14232
+ names: ['id', 'direction', 'params'],
14233
+ format: function (o) {
14234
+ return o.params ? 'rid:%s %s %s' : 'rid:%s %s';
14235
+ }
14236
+ }, {
14237
+ // a=imageattr:97 send [x=800,y=640,sar=1.1,q=0.6] [x=480,y=320] recv [x=330,y=250]
14238
+ // a=imageattr:* send [x=800,y=640] recv *
14239
+ // a=imageattr:100 recv [x=320,y=240]
14240
+ push: 'imageattrs',
14241
+ reg: new RegExp(
14242
+ // a=imageattr:97
14243
+ '^imageattr:(\\d+|\\*)' +
14244
+ // send [x=800,y=640,sar=1.1,q=0.6] [x=480,y=320]
14245
+ '[\\s\\t]+(send|recv)[\\s\\t]+(\\*|\\[\\S+\\](?:[\\s\\t]+\\[\\S+\\])*)' +
14246
+ // recv [x=330,y=250]
14247
+ '(?:[\\s\\t]+(recv|send)[\\s\\t]+(\\*|\\[\\S+\\](?:[\\s\\t]+\\[\\S+\\])*))?'),
14248
+ names: ['pt', 'dir1', 'attrs1', 'dir2', 'attrs2'],
14249
+ format: function (o) {
14250
+ return 'imageattr:%s %s %s' + (o.dir2 ? ' %s %s' : '');
14251
+ }
14252
+ }, {
14253
+ // a=simulcast:send 1,2,3;~4,~5 recv 6;~7,~8
14254
+ // a=simulcast:recv 1;4,5 send 6;7
14255
+ name: 'simulcast',
14256
+ reg: new RegExp(
14257
+ // a=simulcast:
14258
+ '^simulcast:' +
14259
+ // send 1,2,3;~4,~5
14260
+ '(send|recv) ([a-zA-Z0-9\\-_~;,]+)' +
14261
+ // space + recv 6;~7,~8
14262
+ '(?:\\s?(send|recv) ([a-zA-Z0-9\\-_~;,]+))?' +
14263
+ // end
14264
+ '$'),
14265
+ names: ['dir1', 'list1', 'dir2', 'list2'],
14266
+ format: function (o) {
14267
+ return 'simulcast:%s %s' + (o.dir2 ? ' %s %s' : '');
14268
+ }
14269
+ }, {
14270
+ // old simulcast draft 03 (implemented by Firefox)
14271
+ // https://tools.ietf.org/html/draft-ietf-mmusic-sdp-simulcast-03
14272
+ // a=simulcast: recv pt=97;98 send pt=97
14273
+ // a=simulcast: send rid=5;6;7 paused=6,7
14274
+ name: 'simulcast_03',
14275
+ reg: /^simulcast:[\s\t]+([\S+\s\t]+)$/,
14276
+ names: ['value'],
14277
+ format: 'simulcast: %s'
14278
+ }, {
14279
+ // a=framerate:25
14280
+ // a=framerate:29.97
14281
+ name: 'framerate',
14282
+ reg: /^framerate:(\d+(?:$|\.\d+))/,
14283
+ format: 'framerate:%s'
14284
+ }, {
14285
+ // RFC4570
14286
+ // a=source-filter: incl IN IP4 239.5.2.31 10.1.15.5
14287
+ name: 'sourceFilter',
14288
+ reg: /^source-filter: *(excl|incl) (\S*) (IP4|IP6|\*) (\S*) (.*)/,
14289
+ names: ['filterMode', 'netType', 'addressTypes', 'destAddress', 'srcList'],
14290
+ format: 'source-filter: %s %s %s %s %s'
14291
+ }, {
14292
+ // a=bundle-only
14293
+ name: 'bundleOnly',
14294
+ reg: /^(bundle-only)/
14295
+ }, {
14296
+ // a=label:1
14297
+ name: 'label',
14298
+ reg: /^label:(.+)/,
14299
+ format: 'label:%s'
14300
+ }, {
14301
+ // RFC version 26 for SCTP over DTLS
14302
+ // https://tools.ietf.org/html/draft-ietf-mmusic-sctp-sdp-26#section-5
14303
+ name: 'sctpPort',
14304
+ reg: /^sctp-port:(\d+)$/,
14305
+ format: 'sctp-port:%s'
14306
+ }, {
14307
+ // RFC version 26 for SCTP over DTLS
14308
+ // https://tools.ietf.org/html/draft-ietf-mmusic-sctp-sdp-26#section-6
14309
+ name: 'maxMessageSize',
14310
+ reg: /^max-message-size:(\d+)$/,
14311
+ format: 'max-message-size:%s'
14312
+ }, {
14313
+ // RFC7273
14314
+ // a=ts-refclk:ptp=IEEE1588-2008:39-A7-94-FF-FE-07-CB-D0:37
14315
+ push: 'tsRefClocks',
14316
+ reg: /^ts-refclk:([^\s=]*)(?:=(\S*))?/,
14317
+ names: ['clksrc', 'clksrcExt'],
14318
+ format: function (o) {
14319
+ return 'ts-refclk:%s' + (o.clksrcExt != null ? '=%s' : '');
14320
+ }
14321
+ }, {
14322
+ // RFC7273
14323
+ // a=mediaclk:direct=963214424
14324
+ name: 'mediaClk',
14325
+ reg: /^mediaclk:(?:id=(\S*))? *([^\s=]*)(?:=(\S*))?(?: *rate=(\d+)\/(\d+))?/,
14326
+ names: ['id', 'mediaClockName', 'mediaClockValue', 'rateNumerator', 'rateDenominator'],
14327
+ format: function (o) {
14328
+ var str = 'mediaclk:';
14329
+ str += o.id != null ? 'id=%s %s' : '%v%s';
14330
+ str += o.mediaClockValue != null ? '=%s' : '';
14331
+ str += o.rateNumerator != null ? ' rate=%s' : '';
14332
+ str += o.rateDenominator != null ? '/%s' : '';
14333
+ return str;
14334
+ }
14335
+ }, {
14336
+ // a=keywds:keywords
14337
+ name: 'keywords',
14338
+ reg: /^keywds:(.+)$/,
14339
+ format: 'keywds:%s'
14340
+ }, {
14341
+ // a=content:main
14342
+ name: 'content',
14343
+ reg: /^content:(.+)/,
14344
+ format: 'content:%s'
14345
+ },
14346
+ // BFCP https://tools.ietf.org/html/rfc4583
14347
+ {
14348
+ // a=floorctrl:c-s
14349
+ name: 'bfcpFloorCtrl',
14350
+ reg: /^floorctrl:(c-only|s-only|c-s)/,
14351
+ format: 'floorctrl:%s'
14352
+ }, {
14353
+ // a=confid:1
14354
+ name: 'bfcpConfId',
14355
+ reg: /^confid:(\d+)/,
14356
+ format: 'confid:%s'
14357
+ }, {
14358
+ // a=userid:1
14359
+ name: 'bfcpUserId',
14360
+ reg: /^userid:(\d+)/,
14361
+ format: 'userid:%s'
14362
+ }, {
14363
+ // a=floorid:1
14364
+ name: 'bfcpFloorId',
14365
+ reg: /^floorid:(.+) (?:m-stream|mstrm):(.+)/,
14366
+ names: ['id', 'mStream'],
14367
+ format: 'floorid:%s mstrm:%s'
14368
+ }, {
14369
+ // any a= that we don't understand is kept verbatim on media.invalid
14370
+ push: 'invalid',
14371
+ names: ['value']
14372
+ }]
14373
+ };
14225
14374
 
14226
- // set sensible defaults to avoid polluting the grammar with boring details
14227
- Object.keys(grammar$1).forEach(function (key) {
14228
- var objs = grammar$1[key];
14229
- objs.forEach(function (obj) {
14230
- if (!obj.reg) {
14231
- obj.reg = /(.*)/;
14232
- }
14233
- if (!obj.format) {
14234
- obj.format = '%s';
14235
- }
14375
+ // set sensible defaults to avoid polluting the grammar with boring details
14376
+ Object.keys(grammar$1).forEach(function (key) {
14377
+ var objs = grammar$1[key];
14378
+ objs.forEach(function (obj) {
14379
+ if (!obj.reg) {
14380
+ obj.reg = /(.*)/;
14381
+ }
14382
+ if (!obj.format) {
14383
+ obj.format = '%s';
14384
+ }
14385
+ });
14236
14386
  });
14237
- });
14238
- var grammarExports = grammar$2.exports;
14387
+ return grammar.exports;
14388
+ }
14239
14389
 
14240
- (function (exports) {
14241
- var toIntIfInt = function (v) {
14242
- return String(Number(v)) === v ? Number(v) : v;
14243
- };
14244
- var attachProperties = function (match, location, names, rawName) {
14245
- if (rawName && !names) {
14246
- location[rawName] = toIntIfInt(match[1]);
14247
- } else {
14248
- for (var i = 0; i < names.length; i += 1) {
14249
- if (match[i + 1] != null) {
14250
- location[names[i]] = toIntIfInt(match[i + 1]);
14390
+ var hasRequiredParser;
14391
+ function requireParser() {
14392
+ if (hasRequiredParser) return parser;
14393
+ hasRequiredParser = 1;
14394
+ (function (exports) {
14395
+ var toIntIfInt = function (v) {
14396
+ return String(Number(v)) === v ? Number(v) : v;
14397
+ };
14398
+ var attachProperties = function (match, location, names, rawName) {
14399
+ if (rawName && !names) {
14400
+ location[rawName] = toIntIfInt(match[1]);
14401
+ } else {
14402
+ for (var i = 0; i < names.length; i += 1) {
14403
+ if (match[i + 1] != null) {
14404
+ location[names[i]] = toIntIfInt(match[i + 1]);
14405
+ }
14251
14406
  }
14252
14407
  }
14253
- }
14254
- };
14255
- var parseReg = function (obj, location, content) {
14256
- var needsBlank = obj.name && obj.names;
14257
- if (obj.push && !location[obj.push]) {
14258
- location[obj.push] = [];
14259
- } else if (needsBlank && !location[obj.name]) {
14260
- location[obj.name] = {};
14261
- }
14262
- var keyLocation = obj.push ? {} :
14263
- // blank object that will be pushed
14264
- needsBlank ? location[obj.name] : location; // otherwise, named location or root
14408
+ };
14409
+ var parseReg = function (obj, location, content) {
14410
+ var needsBlank = obj.name && obj.names;
14411
+ if (obj.push && !location[obj.push]) {
14412
+ location[obj.push] = [];
14413
+ } else if (needsBlank && !location[obj.name]) {
14414
+ location[obj.name] = {};
14415
+ }
14416
+ var keyLocation = obj.push ? {} :
14417
+ // blank object that will be pushed
14418
+ needsBlank ? location[obj.name] : location; // otherwise, named location or root
14265
14419
 
14266
- attachProperties(content.match(obj.reg), keyLocation, obj.names, obj.name);
14267
- if (obj.push) {
14268
- location[obj.push].push(keyLocation);
14269
- }
14270
- };
14271
- var grammar = grammarExports;
14272
- var validLine = RegExp.prototype.test.bind(/^([a-z])=(.*)/);
14273
- exports.parse = function (sdp) {
14274
- var session = {},
14275
- media = [],
14276
- location = session; // points at where properties go under (one of the above)
14277
-
14278
- // parse lines we understand
14279
- sdp.split(/(\r\n|\r|\n)/).filter(validLine).forEach(function (l) {
14280
- var type = l[0];
14281
- var content = l.slice(2);
14282
- if (type === 'm') {
14283
- media.push({
14284
- rtp: [],
14285
- fmtp: []
14286
- });
14287
- location = media[media.length - 1]; // point at latest media line
14420
+ attachProperties(content.match(obj.reg), keyLocation, obj.names, obj.name);
14421
+ if (obj.push) {
14422
+ location[obj.push].push(keyLocation);
14288
14423
  }
14289
- for (var j = 0; j < (grammar[type] || []).length; j += 1) {
14290
- var obj = grammar[type][j];
14291
- if (obj.reg.test(content)) {
14292
- return parseReg(obj, location, content);
14424
+ };
14425
+ var grammar = requireGrammar();
14426
+ var validLine = RegExp.prototype.test.bind(/^([a-z])=(.*)/);
14427
+ exports.parse = function (sdp) {
14428
+ var session = {},
14429
+ media = [],
14430
+ location = session; // points at where properties go under (one of the above)
14431
+
14432
+ // parse lines we understand
14433
+ sdp.split(/(\r\n|\r|\n)/).filter(validLine).forEach(function (l) {
14434
+ var type = l[0];
14435
+ var content = l.slice(2);
14436
+ if (type === 'm') {
14437
+ media.push({
14438
+ rtp: [],
14439
+ fmtp: []
14440
+ });
14441
+ location = media[media.length - 1]; // point at latest media line
14442
+ }
14443
+ for (var j = 0; j < (grammar[type] || []).length; j += 1) {
14444
+ var obj = grammar[type][j];
14445
+ if (obj.reg.test(content)) {
14446
+ return parseReg(obj, location, content);
14447
+ }
14293
14448
  }
14449
+ });
14450
+ session.media = media; // link it up
14451
+ return session;
14452
+ };
14453
+ var paramReducer = function (acc, expr) {
14454
+ var s = expr.split(/=(.+)/, 2);
14455
+ if (s.length === 2) {
14456
+ acc[s[0]] = toIntIfInt(s[1]);
14457
+ } else if (s.length === 1 && expr.length > 1) {
14458
+ acc[s[0]] = undefined;
14294
14459
  }
14295
- });
14296
- session.media = media; // link it up
14297
- return session;
14298
- };
14299
- var paramReducer = function (acc, expr) {
14300
- var s = expr.split(/=(.+)/, 2);
14301
- if (s.length === 2) {
14302
- acc[s[0]] = toIntIfInt(s[1]);
14303
- } else if (s.length === 1 && expr.length > 1) {
14304
- acc[s[0]] = undefined;
14305
- }
14306
- return acc;
14307
- };
14308
- exports.parseParams = function (str) {
14309
- return str.split(/;\s?/).reduce(paramReducer, {});
14310
- };
14460
+ return acc;
14461
+ };
14462
+ exports.parseParams = function (str) {
14463
+ return str.split(/;\s?/).reduce(paramReducer, {});
14464
+ };
14311
14465
 
14312
- // For backward compatibility - alias will be removed in 3.0.0
14313
- exports.parseFmtpConfig = exports.parseParams;
14314
- exports.parsePayloads = function (str) {
14315
- return str.toString().split(' ').map(Number);
14316
- };
14317
- exports.parseRemoteCandidates = function (str) {
14318
- var candidates = [];
14319
- var parts = str.split(' ').map(toIntIfInt);
14320
- for (var i = 0; i < parts.length; i += 3) {
14321
- candidates.push({
14322
- component: parts[i],
14323
- ip: parts[i + 1],
14324
- port: parts[i + 2]
14466
+ // For backward compatibility - alias will be removed in 3.0.0
14467
+ exports.parseFmtpConfig = exports.parseParams;
14468
+ exports.parsePayloads = function (str) {
14469
+ return str.toString().split(' ').map(Number);
14470
+ };
14471
+ exports.parseRemoteCandidates = function (str) {
14472
+ var candidates = [];
14473
+ var parts = str.split(' ').map(toIntIfInt);
14474
+ for (var i = 0; i < parts.length; i += 3) {
14475
+ candidates.push({
14476
+ component: parts[i],
14477
+ ip: parts[i + 1],
14478
+ port: parts[i + 2]
14479
+ });
14480
+ }
14481
+ return candidates;
14482
+ };
14483
+ exports.parseImageAttributes = function (str) {
14484
+ return str.split(' ').map(function (item) {
14485
+ return item.substring(1, item.length - 1).split(',').reduce(paramReducer, {});
14325
14486
  });
14326
- }
14327
- return candidates;
14328
- };
14329
- exports.parseImageAttributes = function (str) {
14330
- return str.split(' ').map(function (item) {
14331
- return item.substring(1, item.length - 1).split(',').reduce(paramReducer, {});
14332
- });
14487
+ };
14488
+ exports.parseSimulcastStreamList = function (str) {
14489
+ return str.split(';').map(function (stream) {
14490
+ return stream.split(',').map(function (format) {
14491
+ var scid,
14492
+ paused = false;
14493
+ if (format[0] !== '~') {
14494
+ scid = toIntIfInt(format);
14495
+ } else {
14496
+ scid = toIntIfInt(format.substring(1, format.length));
14497
+ paused = true;
14498
+ }
14499
+ return {
14500
+ scid: scid,
14501
+ paused: paused
14502
+ };
14503
+ });
14504
+ });
14505
+ };
14506
+ })(parser);
14507
+ return parser;
14508
+ }
14509
+
14510
+ var writer;
14511
+ var hasRequiredWriter;
14512
+ function requireWriter() {
14513
+ if (hasRequiredWriter) return writer;
14514
+ hasRequiredWriter = 1;
14515
+ var grammar = requireGrammar();
14516
+
14517
+ // customized util.format - discards excess arguments and can void middle ones
14518
+ var formatRegExp = /%[sdv%]/g;
14519
+ var format = function (formatStr) {
14520
+ var i = 1;
14521
+ var args = arguments;
14522
+ var len = args.length;
14523
+ return formatStr.replace(formatRegExp, function (x) {
14524
+ if (i >= len) {
14525
+ return x; // missing argument
14526
+ }
14527
+ var arg = args[i];
14528
+ i += 1;
14529
+ switch (x) {
14530
+ case '%%':
14531
+ return '%';
14532
+ case '%s':
14533
+ return String(arg);
14534
+ case '%d':
14535
+ return Number(arg);
14536
+ case '%v':
14537
+ return '';
14538
+ }
14539
+ });
14540
+ // NB: we discard excess arguments - they are typically undefined from makeLine
14333
14541
  };
14334
- exports.parseSimulcastStreamList = function (str) {
14335
- return str.split(';').map(function (stream) {
14336
- return stream.split(',').map(function (format) {
14337
- var scid,
14338
- paused = false;
14339
- if (format[0] !== '~') {
14340
- scid = toIntIfInt(format);
14542
+ var makeLine = function (type, obj, location) {
14543
+ var str = obj.format instanceof Function ? obj.format(obj.push ? location : location[obj.name]) : obj.format;
14544
+ var args = [type + '=' + str];
14545
+ if (obj.names) {
14546
+ for (var i = 0; i < obj.names.length; i += 1) {
14547
+ var n = obj.names[i];
14548
+ if (obj.name) {
14549
+ args.push(location[obj.name][n]);
14341
14550
  } else {
14342
- scid = toIntIfInt(format.substring(1, format.length));
14343
- paused = true;
14551
+ // for mLine and push attributes
14552
+ args.push(location[obj.names[i]]);
14344
14553
  }
14345
- return {
14346
- scid: scid,
14347
- paused: paused
14348
- };
14349
- });
14350
- });
14351
- };
14352
- })(parser$1);
14353
-
14354
- var grammar = grammarExports;
14355
-
14356
- // customized util.format - discards excess arguments and can void middle ones
14357
- var formatRegExp = /%[sdv%]/g;
14358
- var format = function (formatStr) {
14359
- var i = 1;
14360
- var args = arguments;
14361
- var len = args.length;
14362
- return formatStr.replace(formatRegExp, function (x) {
14363
- if (i >= len) {
14364
- return x; // missing argument
14365
- }
14366
- var arg = args[i];
14367
- i += 1;
14368
- switch (x) {
14369
- case '%%':
14370
- return '%';
14371
- case '%s':
14372
- return String(arg);
14373
- case '%d':
14374
- return Number(arg);
14375
- case '%v':
14376
- return '';
14377
- }
14378
- });
14379
- // NB: we discard excess arguments - they are typically undefined from makeLine
14380
- };
14381
- var makeLine = function (type, obj, location) {
14382
- var str = obj.format instanceof Function ? obj.format(obj.push ? location : location[obj.name]) : obj.format;
14383
- var args = [type + '=' + str];
14384
- if (obj.names) {
14385
- for (var i = 0; i < obj.names.length; i += 1) {
14386
- var n = obj.names[i];
14387
- if (obj.name) {
14388
- args.push(location[obj.name][n]);
14389
- } else {
14390
- // for mLine and push attributes
14391
- args.push(location[obj.names[i]]);
14392
14554
  }
14555
+ } else {
14556
+ args.push(location[obj.name]);
14393
14557
  }
14394
- } else {
14395
- args.push(location[obj.name]);
14396
- }
14397
- return format.apply(null, args);
14398
- };
14558
+ return format.apply(null, args);
14559
+ };
14399
14560
 
14400
- // RFC specified order
14401
- // TODO: extend this with all the rest
14402
- var defaultOuterOrder = ['v', 'o', 's', 'i', 'u', 'e', 'p', 'c', 'b', 't', 'r', 'z', 'a'];
14403
- var defaultInnerOrder = ['i', 'c', 'b', 'a'];
14404
- var writer$1 = function (session, opts) {
14405
- opts = opts || {};
14406
- // ensure certain properties exist
14407
- if (session.version == null) {
14408
- session.version = 0; // 'v=0' must be there (only defined version atm)
14409
- }
14410
- if (session.name == null) {
14411
- session.name = ' '; // 's= ' must be there if no meaningful name set
14412
- }
14413
- session.media.forEach(function (mLine) {
14414
- if (mLine.payloads == null) {
14415
- mLine.payloads = '';
14561
+ // RFC specified order
14562
+ // TODO: extend this with all the rest
14563
+ var defaultOuterOrder = ['v', 'o', 's', 'i', 'u', 'e', 'p', 'c', 'b', 't', 'r', 'z', 'a'];
14564
+ var defaultInnerOrder = ['i', 'c', 'b', 'a'];
14565
+ writer = function (session, opts) {
14566
+ opts = opts || {};
14567
+ // ensure certain properties exist
14568
+ if (session.version == null) {
14569
+ session.version = 0; // 'v=0' must be there (only defined version atm)
14416
14570
  }
14417
- });
14418
- var outerOrder = opts.outerOrder || defaultOuterOrder;
14419
- var innerOrder = opts.innerOrder || defaultInnerOrder;
14420
- var sdp = [];
14421
-
14422
- // loop through outerOrder for matching properties on session
14423
- outerOrder.forEach(function (type) {
14424
- grammar[type].forEach(function (obj) {
14425
- if (obj.name in session && session[obj.name] != null) {
14426
- sdp.push(makeLine(type, obj, session));
14427
- } else if (obj.push in session && session[obj.push] != null) {
14428
- session[obj.push].forEach(function (el) {
14429
- sdp.push(makeLine(type, obj, el));
14430
- });
14571
+ if (session.name == null) {
14572
+ session.name = ' '; // 's= ' must be there if no meaningful name set
14573
+ }
14574
+ session.media.forEach(function (mLine) {
14575
+ if (mLine.payloads == null) {
14576
+ mLine.payloads = '';
14431
14577
  }
14432
14578
  });
14433
- });
14579
+ var outerOrder = opts.outerOrder || defaultOuterOrder;
14580
+ var innerOrder = opts.innerOrder || defaultInnerOrder;
14581
+ var sdp = [];
14434
14582
 
14435
- // then for each media line, follow the innerOrder
14436
- session.media.forEach(function (mLine) {
14437
- sdp.push(makeLine('m', grammar.m[0], mLine));
14438
- innerOrder.forEach(function (type) {
14583
+ // loop through outerOrder for matching properties on session
14584
+ outerOrder.forEach(function (type) {
14439
14585
  grammar[type].forEach(function (obj) {
14440
- if (obj.name in mLine && mLine[obj.name] != null) {
14441
- sdp.push(makeLine(type, obj, mLine));
14442
- } else if (obj.push in mLine && mLine[obj.push] != null) {
14443
- mLine[obj.push].forEach(function (el) {
14586
+ if (obj.name in session && session[obj.name] != null) {
14587
+ sdp.push(makeLine(type, obj, session));
14588
+ } else if (obj.push in session && session[obj.push] != null) {
14589
+ session[obj.push].forEach(function (el) {
14444
14590
  sdp.push(makeLine(type, obj, el));
14445
14591
  });
14446
14592
  }
14447
14593
  });
14448
14594
  });
14449
- });
14450
- return sdp.join('\r\n') + '\r\n';
14451
- };
14452
14595
 
14453
- var parser = parser$1;
14454
- var writer = writer$1;
14455
- var write = writer;
14456
- var parse = parser.parse;
14457
- parser.parseParams;
14458
- parser.parseFmtpConfig; // Alias of parseParams().
14459
- parser.parsePayloads;
14460
- parser.parseRemoteCandidates;
14461
- parser.parseImageAttributes;
14462
- parser.parseSimulcastStreamList;
14596
+ // then for each media line, follow the innerOrder
14597
+ session.media.forEach(function (mLine) {
14598
+ sdp.push(makeLine('m', grammar.m[0], mLine));
14599
+ innerOrder.forEach(function (type) {
14600
+ grammar[type].forEach(function (obj) {
14601
+ if (obj.name in mLine && mLine[obj.name] != null) {
14602
+ sdp.push(makeLine(type, obj, mLine));
14603
+ } else if (obj.push in mLine && mLine[obj.push] != null) {
14604
+ mLine[obj.push].forEach(function (el) {
14605
+ sdp.push(makeLine(type, obj, el));
14606
+ });
14607
+ }
14608
+ });
14609
+ });
14610
+ });
14611
+ return sdp.join('\r\n') + '\r\n';
14612
+ };
14613
+ return writer;
14614
+ }
14615
+
14616
+ var hasRequiredLib;
14617
+ function requireLib() {
14618
+ if (hasRequiredLib) return lib;
14619
+ hasRequiredLib = 1;
14620
+ var parser = requireParser();
14621
+ var writer = requireWriter();
14622
+ lib.write = writer;
14623
+ lib.parse = parser.parse;
14624
+ lib.parseParams = parser.parseParams;
14625
+ lib.parseFmtpConfig = parser.parseFmtpConfig; // Alias of parseParams().
14626
+ lib.parsePayloads = parser.parsePayloads;
14627
+ lib.parseRemoteCandidates = parser.parseRemoteCandidates;
14628
+ lib.parseImageAttributes = parser.parseImageAttributes;
14629
+ lib.parseSimulcastStreamList = parser.parseSimulcastStreamList;
14630
+ return lib;
14631
+ }
14632
+
14633
+ var libExports = requireLib();
14463
14634
 
14464
14635
  /* The svc codec (av1/vp9) would use a very low bitrate at the begining and
14465
14636
  increase slowly by the bandwidth estimator until it reach the target bitrate. The
@@ -14589,7 +14760,7 @@ class PCTransport extends eventsExports.EventEmitter {
14589
14760
  this.remoteStereoMids = stereoMids;
14590
14761
  this.remoteNackMids = nackMids;
14591
14762
  } else if (sd.type === 'answer') {
14592
- const sdpParsed = parse((_a = sd.sdp) !== null && _a !== void 0 ? _a : '');
14763
+ const sdpParsed = libExports.parse((_a = sd.sdp) !== null && _a !== void 0 ? _a : '');
14593
14764
  sdpParsed.media.forEach(media => {
14594
14765
  if (media.type === 'audio') {
14595
14766
  // mung sdp for opus bitrate settings
@@ -14631,7 +14802,7 @@ class PCTransport extends eventsExports.EventEmitter {
14631
14802
  });
14632
14803
  }
14633
14804
  });
14634
- mungedSDP = write(sdpParsed);
14805
+ mungedSDP = libExports.write(sdpParsed);
14635
14806
  }
14636
14807
  yield this.setMungedSDP(sd, mungedSDP, true);
14637
14808
  this.pendingCandidates.forEach(candidate => {
@@ -14645,7 +14816,7 @@ class PCTransport extends eventsExports.EventEmitter {
14645
14816
  } else if (sd.type === 'answer') {
14646
14817
  this.emit(PCEvents.NegotiationComplete);
14647
14818
  if (sd.sdp) {
14648
- const sdpParsed = parse(sd.sdp);
14819
+ const sdpParsed = libExports.parse(sd.sdp);
14649
14820
  sdpParsed.media.forEach(media => {
14650
14821
  if (media.type === 'video') {
14651
14822
  this.emit(PCEvents.RTPVideoPayloadTypes, media.rtp);
@@ -14687,7 +14858,7 @@ class PCTransport extends eventsExports.EventEmitter {
14687
14858
  this.log.debug('original offer', Object.assign({
14688
14859
  sdp: offer.sdp
14689
14860
  }, this.logContext));
14690
- const sdpParsed = parse((_a = offer.sdp) !== null && _a !== void 0 ? _a : '');
14861
+ const sdpParsed = libExports.parse((_a = offer.sdp) !== null && _a !== void 0 ? _a : '');
14691
14862
  sdpParsed.media.forEach(media => {
14692
14863
  if (media.type === 'audio') {
14693
14864
  ensureAudioNackAndStereo(media, [], []);
@@ -14731,7 +14902,7 @@ class PCTransport extends eventsExports.EventEmitter {
14731
14902
  });
14732
14903
  }
14733
14904
  });
14734
- yield this.setMungedSDP(offer, write(sdpParsed));
14905
+ yield this.setMungedSDP(offer, libExports.write(sdpParsed));
14735
14906
  this.onOffer(offer);
14736
14907
  });
14737
14908
  }
@@ -14739,13 +14910,13 @@ class PCTransport extends eventsExports.EventEmitter {
14739
14910
  return __awaiter(this, void 0, void 0, function* () {
14740
14911
  var _a;
14741
14912
  const answer = yield this.pc.createAnswer();
14742
- const sdpParsed = parse((_a = answer.sdp) !== null && _a !== void 0 ? _a : '');
14913
+ const sdpParsed = libExports.parse((_a = answer.sdp) !== null && _a !== void 0 ? _a : '');
14743
14914
  sdpParsed.media.forEach(media => {
14744
14915
  if (media.type === 'audio') {
14745
14916
  ensureAudioNackAndStereo(media, this.remoteStereoMids, this.remoteNackMids);
14746
14917
  }
14747
14918
  });
14748
- yield this.setMungedSDP(answer, write(sdpParsed));
14919
+ yield this.setMungedSDP(answer, libExports.write(sdpParsed));
14749
14920
  return answer;
14750
14921
  });
14751
14922
  }
@@ -14953,7 +15124,7 @@ function extractStereoAndNackAudioFromOffer(offer) {
14953
15124
  var _a;
14954
15125
  const stereoMids = [];
14955
15126
  const nackMids = [];
14956
- const sdpParsed = parse((_a = offer.sdp) !== null && _a !== void 0 ? _a : '');
15127
+ const sdpParsed = libExports.parse((_a = offer.sdp) !== null && _a !== void 0 ? _a : '');
14957
15128
  let opusPayload = 0;
14958
15129
  sdpParsed.media.forEach(media => {
14959
15130
  var _a;
@@ -15276,7 +15447,7 @@ class PCTransportManager {
15276
15447
  const abortHandler = () => {
15277
15448
  this.log.warn('abort transport connection', this.logContext);
15278
15449
  CriticalTimers.clearTimeout(connectTimeout);
15279
- reject(new ConnectionError('room connection has been cancelled', 3 /* ConnectionErrorReason.Cancelled */));
15450
+ reject(new ConnectionError('room connection has been cancelled', ConnectionErrorReason.Cancelled));
15280
15451
  };
15281
15452
  if (abortController === null || abortController === void 0 ? void 0 : abortController.signal.aborted) {
15282
15453
  abortHandler();
@@ -15289,7 +15460,7 @@ class PCTransportManager {
15289
15460
  while (this.state !== PCTransportState.CONNECTED) {
15290
15461
  yield sleep(50); // FIXME we shouldn't rely on `sleep` in the connection paths, as it invokes `setTimeout` which can be drastically throttled by browser implementations
15291
15462
  if (abortController === null || abortController === void 0 ? void 0 : abortController.signal.aborted) {
15292
- reject(new ConnectionError('room connection has been cancelled', 3 /* ConnectionErrorReason.Cancelled */));
15463
+ reject(new ConnectionError('room connection has been cancelled', ConnectionErrorReason.Cancelled));
15293
15464
  return;
15294
15465
  }
15295
15466
  }
@@ -16745,7 +16916,7 @@ class RTCEngine extends eventsExports.EventEmitter {
16745
16916
  return joinResponse;
16746
16917
  } catch (e) {
16747
16918
  if (e instanceof ConnectionError) {
16748
- if (e.reason === 1 /* ConnectionErrorReason.ServerUnreachable */) {
16919
+ if (e.reason === ConnectionErrorReason.ServerUnreachable) {
16749
16920
  this.log.warn("Couldn't connect to server, attempt ".concat(this.joinAttempts, " of ").concat(this.maxJoinAttempts), this.logContext);
16750
16921
  if (this.joinAttempts < this.maxJoinAttempts) {
16751
16922
  return this.join(url, token, opts, abortSignal);
@@ -17247,7 +17418,7 @@ class RTCEngine extends eventsExports.EventEmitter {
17247
17418
  // in case a regionUrl is passed, the region URL takes precedence
17248
17419
  joinResponse = yield this.join(regionUrl !== null && regionUrl !== void 0 ? regionUrl : this.url, this.token, this.signalOpts);
17249
17420
  } catch (e) {
17250
- if (e instanceof ConnectionError && e.reason === 0 /* ConnectionErrorReason.NotAllowed */) {
17421
+ if (e instanceof ConnectionError && e.reason === ConnectionErrorReason.NotAllowed) {
17251
17422
  throw new UnexpectedConnectionState('could not reconnect, token might be expired');
17252
17423
  }
17253
17424
  throw new SignalReconnectError();
@@ -17304,10 +17475,10 @@ class RTCEngine extends eventsExports.EventEmitter {
17304
17475
  error
17305
17476
  }));
17306
17477
  }
17307
- if (error instanceof ConnectionError && error.reason === 0 /* ConnectionErrorReason.NotAllowed */) {
17478
+ if (error instanceof ConnectionError && error.reason === ConnectionErrorReason.NotAllowed) {
17308
17479
  throw new UnexpectedConnectionState('could not reconnect, token might be expired');
17309
17480
  }
17310
- if (error instanceof ConnectionError && error.reason === 4 /* ConnectionErrorReason.LeaveRequest */) {
17481
+ if (error instanceof ConnectionError && error.reason === ConnectionErrorReason.LeaveRequest) {
17311
17482
  throw error;
17312
17483
  }
17313
17484
  throw new SignalReconnectError(message);
@@ -17665,7 +17836,7 @@ class RegionUrlProvider {
17665
17836
  this.lastUpdateAt = Date.now();
17666
17837
  return regionSettings;
17667
17838
  } else {
17668
- throw new ConnectionError("Could not fetch region settings: ".concat(regionSettingsResponse.statusText), regionSettingsResponse.status === 401 ? 0 /* ConnectionErrorReason.NotAllowed */ : undefined, regionSettingsResponse.status);
17839
+ throw new ConnectionError("Could not fetch region settings: ".concat(regionSettingsResponse.statusText), regionSettingsResponse.status === 401 ? ConnectionErrorReason.NotAllowed : undefined, regionSettingsResponse.status);
17669
17840
  }
17670
17841
  });
17671
17842
  }
@@ -18825,12 +18996,12 @@ class Participant extends eventsExports.EventEmitter {
18825
18996
  }
18826
18997
  /** @internal */
18827
18998
  setPermissions(permissions) {
18828
- var _a, _b, _c, _d, _e;
18999
+ var _a, _b, _c, _d, _e, _f;
18829
19000
  const prevPermissions = this.permissions;
18830
19001
  const changed = permissions.canPublish !== ((_a = this.permissions) === null || _a === void 0 ? void 0 : _a.canPublish) || permissions.canSubscribe !== ((_b = this.permissions) === null || _b === void 0 ? void 0 : _b.canSubscribe) || permissions.canPublishData !== ((_c = this.permissions) === null || _c === void 0 ? void 0 : _c.canPublishData) || permissions.hidden !== ((_d = this.permissions) === null || _d === void 0 ? void 0 : _d.hidden) || permissions.recorder !== ((_e = this.permissions) === null || _e === void 0 ? void 0 : _e.recorder) || permissions.canPublishSources.length !== this.permissions.canPublishSources.length || permissions.canPublishSources.some((value, index) => {
18831
19002
  var _a;
18832
19003
  return value !== ((_a = this.permissions) === null || _a === void 0 ? void 0 : _a.canPublishSources[index]);
18833
- });
19004
+ }) || permissions.canSubscribeMetrics !== ((_f = this.permissions) === null || _f === void 0 ? void 0 : _f.canSubscribeMetrics);
18834
19005
  this.permissions = permissions;
18835
19006
  if (changed) {
18836
19007
  this.emit(ParticipantEvent.ParticipantPermissionsChanged, prevPermissions);
@@ -20791,12 +20962,12 @@ class Room extends eventsExports.EventEmitter {
20791
20962
  this.abortController = undefined;
20792
20963
  resolve();
20793
20964
  } catch (e) {
20794
- if (this.regionUrlProvider && e instanceof ConnectionError && e.reason !== 3 /* ConnectionErrorReason.Cancelled */ && e.reason !== 0 /* ConnectionErrorReason.NotAllowed */) {
20965
+ if (this.regionUrlProvider && e instanceof ConnectionError && e.reason !== ConnectionErrorReason.Cancelled && e.reason !== ConnectionErrorReason.NotAllowed) {
20795
20966
  let nextUrl = null;
20796
20967
  try {
20797
20968
  nextUrl = yield this.regionUrlProvider.getNextBestRegionUrl((_a = this.abortController) === null || _a === void 0 ? void 0 : _a.signal);
20798
20969
  } catch (error) {
20799
- if (error instanceof ConnectionError && (error.status === 401 || error.reason === 3 /* ConnectionErrorReason.Cancelled */)) {
20970
+ if (error instanceof ConnectionError && (error.status === 401 || error.reason === ConnectionErrorReason.Cancelled)) {
20800
20971
  this.handleDisconnect(this.options.stopLocalTrackOnUnpublish);
20801
20972
  reject(error);
20802
20973
  return;
@@ -20841,6 +21012,7 @@ class Room extends eventsExports.EventEmitter {
20841
21012
  region: joinResponse.serverRegion
20842
21013
  };
20843
21014
  }
21015
+ this.serverInfo = serverInfo;
20844
21016
  this.log.debug("connected to Livekit Server ".concat(Object.entries(serverInfo).map(_ref => {
20845
21017
  let [key, value] = _ref;
20846
21018
  return "".concat(key, ": ").concat(value);
@@ -20849,10 +21021,10 @@ class Room extends eventsExports.EventEmitter {
20849
21021
  roomSid: (_b = joinResponse.room) === null || _b === void 0 ? void 0 : _b.sid,
20850
21022
  identity: (_c = joinResponse.participant) === null || _c === void 0 ? void 0 : _c.identity
20851
21023
  });
20852
- if (!joinResponse.serverVersion) {
21024
+ if (!serverInfo.version) {
20853
21025
  throw new UnsupportedServer('unknown server version');
20854
21026
  }
20855
- if (joinResponse.serverVersion === '0.15.1' && this.options.dynacast) {
21027
+ if (serverInfo.version === '0.15.1' && this.options.dynacast) {
20856
21028
  this.log.debug('disabling dynacast due to server version', this.logContext);
20857
21029
  // dynacast has a bug in 0.15.1, so we cannot use it then
20858
21030
  roomOptions.dynacast = false;
@@ -21223,9 +21395,12 @@ class Room extends eventsExports.EventEmitter {
21223
21395
  if (!pub || !pub.track) {
21224
21396
  return;
21225
21397
  }
21226
- pub.track.streamState = Track.streamStateFromProto(streamState.state);
21227
- participant.emit(ParticipantEvent.TrackStreamStateChanged, pub, pub.track.streamState);
21228
- this.emitWhenConnected(RoomEvent.TrackStreamStateChanged, pub, pub.track.streamState, participant);
21398
+ const newStreamState = Track.streamStateFromProto(streamState.state);
21399
+ if (newStreamState !== pub.track.streamState) {
21400
+ pub.track.streamState = newStreamState;
21401
+ participant.emit(ParticipantEvent.TrackStreamStateChanged, pub, pub.track.streamState);
21402
+ this.emitWhenConnected(RoomEvent.TrackStreamStateChanged, pub, pub.track.streamState, participant);
21403
+ }
21229
21404
  });
21230
21405
  };
21231
21406
  this.handleSubscriptionPermissionUpdate = update => {
@@ -22879,5 +23054,5 @@ function isFacingModeValue(item) {
22879
23054
  return item === undefined || allowedValues.includes(item);
22880
23055
  }
22881
23056
 
22882
- export { AudioPresets, BaseKeyProvider, CheckStatus, Checker, ConnectionCheck, ConnectionError, ConnectionQuality, ConnectionState, CriticalTimers, CryptorError, CryptorErrorReason, CryptorEvent, DataPacket_Kind, DefaultReconnectPolicy, DeviceUnsupportedError, DisconnectReason, EncryptionEvent, EngineEvent, ExternalE2EEKeyProvider, KeyHandlerEvent, KeyProviderEvent, LivekitError, LocalAudioTrack, LocalParticipant, LocalTrack, LocalTrackPublication, LocalVideoTrack, LogLevel, LoggerNames, MediaDeviceFailure, Mutex, NegotiationError, Participant, ParticipantEvent, ParticipantInfo_Kind as ParticipantKind, PublishDataError, RemoteAudioTrack, RemoteParticipant, RemoteTrack, RemoteTrackPublication, RemoteVideoTrack, Room, RoomEvent, ScreenSharePresets, SignalRequestError, SubscriptionError, Track, TrackEvent, TrackInvalidError, TrackPublication, UnexpectedConnectionState, UnsupportedServer, VideoPreset, VideoPresets, VideoPresets43, VideoQuality, attachToElement, createAudioAnalyser, createE2EEKey, createKeyMaterialFromBuffer, createKeyMaterialFromString, createLocalAudioTrack, createLocalScreenTracks, createLocalTracks, createLocalVideoTrack, deriveKeys, detachTrack, extractProcessorsFromOptions, facingModeFromDeviceLabel, facingModeFromLocalTrack, getBrowser, getEmptyAudioStreamTrack, getEmptyVideoStreamTrack, getLogger, importKey, isBackupCodec, isBrowserSupported, isE2EESupported, isInsertableStreamSupported, isScriptTransformSupported, isVideoFrame, needsRbspUnescaping, parseRbsp, protocolVersion, ratchet, setLogExtension, setLogLevel, supportsAV1, supportsAdaptiveStream, supportsDynacast, supportsVP9, version, videoCodecs, writeRbsp };
23057
+ export { AudioPresets, BaseKeyProvider, CheckStatus, Checker, ConnectionCheck, ConnectionError, ConnectionErrorReason, ConnectionQuality, ConnectionState, CriticalTimers, CryptorError, CryptorErrorReason, CryptorEvent, DataPacket_Kind, DefaultReconnectPolicy, DeviceUnsupportedError, DisconnectReason, EncryptionEvent, EngineEvent, ExternalE2EEKeyProvider, KeyHandlerEvent, KeyProviderEvent, LivekitError, LocalAudioTrack, LocalParticipant, LocalTrack, LocalTrackPublication, LocalVideoTrack, LogLevel, LoggerNames, MediaDeviceFailure, Mutex, NegotiationError, Participant, ParticipantEvent, ParticipantInfo_Kind as ParticipantKind, PublishDataError, RemoteAudioTrack, RemoteParticipant, RemoteTrack, RemoteTrackPublication, RemoteVideoTrack, Room, RoomEvent, ScreenSharePresets, SignalRequestError, SubscriptionError, Track, TrackEvent, TrackInvalidError, TrackPublication, UnexpectedConnectionState, UnsupportedServer, VideoPreset, VideoPresets, VideoPresets43, VideoQuality, attachToElement, compareVersions, createAudioAnalyser, createE2EEKey, createKeyMaterialFromBuffer, createKeyMaterialFromString, createLocalAudioTrack, createLocalScreenTracks, createLocalTracks, createLocalVideoTrack, deriveKeys, detachTrack, extractProcessorsFromOptions, facingModeFromDeviceLabel, facingModeFromLocalTrack, getBrowser, getEmptyAudioStreamTrack, getEmptyVideoStreamTrack, getLogger, importKey, isBackupCodec, isBrowserSupported, isE2EESupported, isInsertableStreamSupported, isScriptTransformSupported, isVideoFrame, needsRbspUnescaping, parseRbsp, protocolVersion, ratchet, setLogExtension, setLogLevel, supportsAV1, supportsAdaptiveStream, supportsDynacast, supportsVP9, version, videoCodecs, writeRbsp };
22883
23058
  //# sourceMappingURL=livekit-client.esm.mjs.map