livekit-client 1.10.0 → 1.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/dist/livekit-client.esm.mjs +457 -478
  2. package/dist/livekit-client.esm.mjs.map +1 -1
  3. package/dist/livekit-client.umd.js +1 -1
  4. package/dist/livekit-client.umd.js.map +1 -1
  5. package/dist/src/connectionHelper/ConnectionCheck.d.ts +2 -3
  6. package/dist/src/connectionHelper/ConnectionCheck.d.ts.map +1 -1
  7. package/dist/src/connectionHelper/checks/Checker.d.ts +2 -3
  8. package/dist/src/connectionHelper/checks/Checker.d.ts.map +1 -1
  9. package/dist/src/room/PCTransport.d.ts +1 -1
  10. package/dist/src/room/PCTransport.d.ts.map +1 -1
  11. package/dist/src/room/RTCEngine.d.ts +2 -4
  12. package/dist/src/room/RTCEngine.d.ts.map +1 -1
  13. package/dist/src/room/Room.d.ts +3 -4
  14. package/dist/src/room/Room.d.ts.map +1 -1
  15. package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
  16. package/dist/src/room/participant/Participant.d.ts +2 -4
  17. package/dist/src/room/participant/Participant.d.ts.map +1 -1
  18. package/dist/src/room/participant/RemoteParticipant.d.ts +2 -1
  19. package/dist/src/room/participant/RemoteParticipant.d.ts.map +1 -1
  20. package/dist/src/room/participant/publishUtils.d.ts.map +1 -1
  21. package/dist/src/room/track/LocalTrack.d.ts +1 -0
  22. package/dist/src/room/track/LocalTrack.d.ts.map +1 -1
  23. package/dist/src/room/track/LocalVideoTrack.d.ts +1 -1
  24. package/dist/src/room/track/LocalVideoTrack.d.ts.map +1 -1
  25. package/dist/src/room/track/RemoteVideoTrack.d.ts +1 -0
  26. package/dist/src/room/track/RemoteVideoTrack.d.ts.map +1 -1
  27. package/dist/src/room/track/Track.d.ts +2 -4
  28. package/dist/src/room/track/Track.d.ts.map +1 -1
  29. package/dist/src/room/track/TrackPublication.d.ts +2 -4
  30. package/dist/src/room/track/TrackPublication.d.ts.map +1 -1
  31. package/dist/src/room/track/options.d.ts +13 -4
  32. package/dist/src/room/track/options.d.ts.map +1 -1
  33. package/dist/src/room/track/types.d.ts +2 -1
  34. package/dist/src/room/track/types.d.ts.map +1 -1
  35. package/dist/src/room/utils.d.ts.map +1 -1
  36. package/dist/ts4.2/src/connectionHelper/ConnectionCheck.d.ts +2 -3
  37. package/dist/ts4.2/src/connectionHelper/checks/Checker.d.ts +2 -3
  38. package/dist/ts4.2/src/room/PCTransport.d.ts +1 -1
  39. package/dist/ts4.2/src/room/RTCEngine.d.ts +2 -4
  40. package/dist/ts4.2/src/room/Room.d.ts +3 -4
  41. package/dist/ts4.2/src/room/participant/Participant.d.ts +2 -4
  42. package/dist/ts4.2/src/room/participant/RemoteParticipant.d.ts +2 -1
  43. package/dist/ts4.2/src/room/track/LocalTrack.d.ts +1 -0
  44. package/dist/ts4.2/src/room/track/LocalVideoTrack.d.ts +1 -1
  45. package/dist/ts4.2/src/room/track/RemoteVideoTrack.d.ts +1 -0
  46. package/dist/ts4.2/src/room/track/Track.d.ts +2 -4
  47. package/dist/ts4.2/src/room/track/TrackPublication.d.ts +2 -4
  48. package/dist/ts4.2/src/room/track/options.d.ts +13 -4
  49. package/dist/ts4.2/src/room/track/types.d.ts +2 -1
  50. package/package.json +2 -3
  51. package/src/connectionHelper/ConnectionCheck.ts +2 -3
  52. package/src/connectionHelper/checks/Checker.ts +2 -3
  53. package/src/logger.ts +4 -4
  54. package/src/room/PCTransport.ts +1 -1
  55. package/src/room/RTCEngine.ts +4 -4
  56. package/src/room/Room.ts +41 -11
  57. package/src/room/participant/LocalParticipant.ts +11 -3
  58. package/src/room/participant/Participant.ts +2 -4
  59. package/src/room/participant/RemoteParticipant.ts +4 -3
  60. package/src/room/participant/publishUtils.ts +16 -18
  61. package/src/room/track/LocalTrack.ts +61 -42
  62. package/src/room/track/LocalVideoTrack.ts +9 -7
  63. package/src/room/track/RemoteVideoTrack.ts +23 -6
  64. package/src/room/track/Track.ts +2 -4
  65. package/src/room/track/TrackPublication.ts +2 -4
  66. package/src/room/track/options.ts +13 -4
  67. package/src/room/track/types.ts +2 -1
  68. package/src/room/utils.ts +6 -3
@@ -296,7 +296,7 @@ var LogLevel;
296
296
  LogLevel[LogLevel["silent"] = 5] = "silent";
297
297
  })(LogLevel || (LogLevel = {}));
298
298
  const livekitLogger = loglevelExports.getLogger('livekit');
299
- livekitLogger.setLevel(LogLevel.info);
299
+ livekitLogger.setDefaultLevel(LogLevel.info);
300
300
  function setLogLevel(level) {
301
301
  livekitLogger.setLevel(level);
302
302
  }
@@ -306,9 +306,9 @@ function setLogLevel(level) {
306
306
  */
307
307
  function setLogExtension(extension) {
308
308
  const originalFactory = livekitLogger.methodFactory;
309
- livekitLogger.methodFactory = (methodName, logLevel, loggerName) => {
310
- const rawMethod = originalFactory(methodName, logLevel, loggerName);
311
- const configLevel = livekitLogger.getLevel();
309
+ livekitLogger.methodFactory = (methodName, configLevel, loggerName) => {
310
+ const rawMethod = originalFactory(methodName, configLevel, loggerName);
311
+ const logLevel = LogLevel[methodName];
312
312
  const needLog = logLevel >= configLevel && logLevel < LogLevel.silent;
313
313
  return (msg, context) => {
314
314
  if (context) rawMethod(msg, context);else rawMethod(msg);
@@ -6654,386 +6654,322 @@ function __asyncValues(o) {
6654
6654
  function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
6655
6655
  }
6656
6656
 
6657
- var events = {exports: {}};
6657
+ var eventemitter3 = {exports: {}};
6658
6658
 
6659
- var R = typeof Reflect === 'object' ? Reflect : null;
6660
- var ReflectApply = R && typeof R.apply === 'function' ? R.apply : function ReflectApply(target, receiver, args) {
6661
- return Function.prototype.apply.call(target, receiver, args);
6662
- };
6663
- var ReflectOwnKeys;
6664
- if (R && typeof R.ownKeys === 'function') {
6665
- ReflectOwnKeys = R.ownKeys;
6666
- } else if (Object.getOwnPropertySymbols) {
6667
- ReflectOwnKeys = function ReflectOwnKeys(target) {
6668
- return Object.getOwnPropertyNames(target).concat(Object.getOwnPropertySymbols(target));
6669
- };
6670
- } else {
6671
- ReflectOwnKeys = function ReflectOwnKeys(target) {
6672
- return Object.getOwnPropertyNames(target);
6673
- };
6674
- }
6675
- function ProcessEmitWarning(warning) {
6676
- if (console && console.warn) console.warn(warning);
6677
- }
6678
- var NumberIsNaN = Number.isNaN || function NumberIsNaN(value) {
6679
- return value !== value;
6680
- };
6681
- function EventEmitter() {
6682
- EventEmitter.init.call(this);
6683
- }
6684
- events.exports = EventEmitter;
6685
- events.exports.once = once;
6659
+ (function (module) {
6686
6660
 
6687
- // Backwards-compat with node 0.10.x
6688
- EventEmitter.EventEmitter = EventEmitter;
6689
- EventEmitter.prototype._events = undefined;
6690
- EventEmitter.prototype._eventsCount = 0;
6691
- EventEmitter.prototype._maxListeners = undefined;
6661
+ var has = Object.prototype.hasOwnProperty,
6662
+ prefix = '~';
6692
6663
 
6693
- // By default EventEmitters will print a warning if more than 10 listeners are
6694
- // added to it. This is a useful default which helps finding memory leaks.
6695
- var defaultMaxListeners = 10;
6696
- function checkListener(listener) {
6697
- if (typeof listener !== 'function') {
6698
- throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener);
6699
- }
6700
- }
6701
- Object.defineProperty(EventEmitter, 'defaultMaxListeners', {
6702
- enumerable: true,
6703
- get: function () {
6704
- return defaultMaxListeners;
6705
- },
6706
- set: function (arg) {
6707
- if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) {
6708
- throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + arg + '.');
6709
- }
6710
- defaultMaxListeners = arg;
6711
- }
6712
- });
6713
- EventEmitter.init = function () {
6714
- if (this._events === undefined || this._events === Object.getPrototypeOf(this)._events) {
6715
- this._events = Object.create(null);
6716
- this._eventsCount = 0;
6717
- }
6718
- this._maxListeners = this._maxListeners || undefined;
6719
- };
6664
+ /**
6665
+ * Constructor to create a storage for our `EE` objects.
6666
+ * An `Events` instance is a plain object whose properties are event names.
6667
+ *
6668
+ * @constructor
6669
+ * @private
6670
+ */
6671
+ function Events() {}
6720
6672
 
6721
- // Obviously not all Emitters should be limited to 10. This function allows
6722
- // that to be increased. Set to zero for unlimited.
6723
- EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {
6724
- if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) {
6725
- throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received ' + n + '.');
6673
+ //
6674
+ // We try to not inherit from `Object.prototype`. In some engines creating an
6675
+ // instance in this way is faster than calling `Object.create(null)` directly.
6676
+ // If `Object.create(null)` is not supported we prefix the event names with a
6677
+ // character to make sure that the built-in object properties are not
6678
+ // overridden or used as an attack vector.
6679
+ //
6680
+ if (Object.create) {
6681
+ Events.prototype = Object.create(null);
6682
+
6683
+ //
6684
+ // This hack is needed because the `__proto__` property is still inherited in
6685
+ // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.
6686
+ //
6687
+ if (!new Events().__proto__) prefix = false;
6726
6688
  }
6727
- this._maxListeners = n;
6728
- return this;
6729
- };
6730
- function _getMaxListeners(that) {
6731
- if (that._maxListeners === undefined) return EventEmitter.defaultMaxListeners;
6732
- return that._maxListeners;
6733
- }
6734
- EventEmitter.prototype.getMaxListeners = function getMaxListeners() {
6735
- return _getMaxListeners(this);
6736
- };
6737
- EventEmitter.prototype.emit = function emit(type) {
6738
- var args = [];
6739
- for (var i = 1; i < arguments.length; i++) args.push(arguments[i]);
6740
- var doError = type === 'error';
6741
- var events = this._events;
6742
- if (events !== undefined) doError = doError && events.error === undefined;else if (!doError) return false;
6743
-
6744
- // If there is no 'error' event listener then throw.
6745
- if (doError) {
6746
- var er;
6747
- if (args.length > 0) er = args[0];
6748
- if (er instanceof Error) {
6749
- // Note: The comments on the `throw` lines are intentional, they show
6750
- // up in Node's output if this results in an unhandled exception.
6751
- throw er; // Unhandled 'error' event
6752
- }
6753
- // At least give some kind of context to the user
6754
- var err = new Error('Unhandled error.' + (er ? ' (' + er.message + ')' : ''));
6755
- err.context = er;
6756
- throw err; // Unhandled 'error' event
6757
- }
6758
-
6759
- var handler = events[type];
6760
- if (handler === undefined) return false;
6761
- if (typeof handler === 'function') {
6762
- ReflectApply(handler, this, args);
6763
- } else {
6764
- var len = handler.length;
6765
- var listeners = arrayClone(handler, len);
6766
- for (var i = 0; i < len; ++i) ReflectApply(listeners[i], this, args);
6689
+
6690
+ /**
6691
+ * Representation of a single event listener.
6692
+ *
6693
+ * @param {Function} fn The listener function.
6694
+ * @param {*} context The context to invoke the listener with.
6695
+ * @param {Boolean} [once=false] Specify if the listener is a one-time listener.
6696
+ * @constructor
6697
+ * @private
6698
+ */
6699
+ function EE(fn, context, once) {
6700
+ this.fn = fn;
6701
+ this.context = context;
6702
+ this.once = once || false;
6767
6703
  }
6768
- return true;
6769
- };
6770
- function _addListener(target, type, listener, prepend) {
6771
- var m;
6772
- var events;
6773
- var existing;
6774
- checkListener(listener);
6775
- events = target._events;
6776
- if (events === undefined) {
6777
- events = target._events = Object.create(null);
6778
- target._eventsCount = 0;
6779
- } else {
6780
- // To avoid recursion in the case that type === "newListener"! Before
6781
- // adding it to the listeners, first emit "newListener".
6782
- if (events.newListener !== undefined) {
6783
- target.emit('newListener', type, listener.listener ? listener.listener : listener);
6784
6704
 
6785
- // Re-assign `events` because a newListener handler could have caused the
6786
- // this._events to be assigned to a new object
6787
- events = target._events;
6705
+ /**
6706
+ * Add a listener for a given event.
6707
+ *
6708
+ * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
6709
+ * @param {(String|Symbol)} event The event name.
6710
+ * @param {Function} fn The listener function.
6711
+ * @param {*} context The context to invoke the listener with.
6712
+ * @param {Boolean} once Specify if the listener is a one-time listener.
6713
+ * @returns {EventEmitter}
6714
+ * @private
6715
+ */
6716
+ function addListener(emitter, event, fn, context, once) {
6717
+ if (typeof fn !== 'function') {
6718
+ throw new TypeError('The listener must be a function');
6788
6719
  }
6789
- existing = events[type];
6720
+ var listener = new EE(fn, context || emitter, once),
6721
+ evt = prefix ? prefix + event : event;
6722
+ if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);else emitter._events[evt] = [emitter._events[evt], listener];
6723
+ return emitter;
6790
6724
  }
6791
- if (existing === undefined) {
6792
- // Optimize the case of one listener. Don't need the extra array object.
6793
- existing = events[type] = listener;
6794
- ++target._eventsCount;
6795
- } else {
6796
- if (typeof existing === 'function') {
6797
- // Adding the second element, need to change to array.
6798
- existing = events[type] = prepend ? [listener, existing] : [existing, listener];
6799
- // If we've already got an array, just append.
6800
- } else if (prepend) {
6801
- existing.unshift(listener);
6802
- } else {
6803
- existing.push(listener);
6804
- }
6805
6725
 
6806
- // Check for listener leak
6807
- m = _getMaxListeners(target);
6808
- if (m > 0 && existing.length > m && !existing.warned) {
6809
- existing.warned = true;
6810
- // No error code for this since it is a Warning
6811
- // eslint-disable-next-line no-restricted-syntax
6812
- var w = new Error('Possible EventEmitter memory leak detected. ' + existing.length + ' ' + String(type) + ' listeners ' + 'added. Use emitter.setMaxListeners() to ' + 'increase limit');
6813
- w.name = 'MaxListenersExceededWarning';
6814
- w.emitter = target;
6815
- w.type = type;
6816
- w.count = existing.length;
6817
- ProcessEmitWarning(w);
6818
- }
6726
+ /**
6727
+ * Clear event by name.
6728
+ *
6729
+ * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
6730
+ * @param {(String|Symbol)} evt The Event name.
6731
+ * @private
6732
+ */
6733
+ function clearEvent(emitter, evt) {
6734
+ if (--emitter._eventsCount === 0) emitter._events = new Events();else delete emitter._events[evt];
6819
6735
  }
6820
- return target;
6821
- }
6822
- EventEmitter.prototype.addListener = function addListener(type, listener) {
6823
- return _addListener(this, type, listener, false);
6824
- };
6825
- EventEmitter.prototype.on = EventEmitter.prototype.addListener;
6826
- EventEmitter.prototype.prependListener = function prependListener(type, listener) {
6827
- return _addListener(this, type, listener, true);
6828
- };
6829
- function onceWrapper() {
6830
- if (!this.fired) {
6831
- this.target.removeListener(this.type, this.wrapFn);
6832
- this.fired = true;
6833
- if (arguments.length === 0) return this.listener.call(this.target);
6834
- return this.listener.apply(this.target, arguments);
6835
- }
6836
- }
6837
- function _onceWrap(target, type, listener) {
6838
- var state = {
6839
- fired: false,
6840
- wrapFn: undefined,
6841
- target: target,
6842
- type: type,
6843
- listener: listener
6736
+
6737
+ /**
6738
+ * Minimal `EventEmitter` interface that is molded against the Node.js
6739
+ * `EventEmitter` interface.
6740
+ *
6741
+ * @constructor
6742
+ * @public
6743
+ */
6744
+ function EventEmitter() {
6745
+ this._events = new Events();
6746
+ this._eventsCount = 0;
6747
+ }
6748
+
6749
+ /**
6750
+ * Return an array listing the events for which the emitter has registered
6751
+ * listeners.
6752
+ *
6753
+ * @returns {Array}
6754
+ * @public
6755
+ */
6756
+ EventEmitter.prototype.eventNames = function eventNames() {
6757
+ var names = [],
6758
+ events,
6759
+ name;
6760
+ if (this._eventsCount === 0) return names;
6761
+ for (name in events = this._events) {
6762
+ if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);
6763
+ }
6764
+ if (Object.getOwnPropertySymbols) {
6765
+ return names.concat(Object.getOwnPropertySymbols(events));
6766
+ }
6767
+ return names;
6844
6768
  };
6845
- var wrapped = onceWrapper.bind(state);
6846
- wrapped.listener = listener;
6847
- state.wrapFn = wrapped;
6848
- return wrapped;
6849
- }
6850
- EventEmitter.prototype.once = function once(type, listener) {
6851
- checkListener(listener);
6852
- this.on(type, _onceWrap(this, type, listener));
6853
- return this;
6854
- };
6855
- EventEmitter.prototype.prependOnceListener = function prependOnceListener(type, listener) {
6856
- checkListener(listener);
6857
- this.prependListener(type, _onceWrap(this, type, listener));
6858
- return this;
6859
- };
6860
6769
 
6861
- // Emits a 'removeListener' event if and only if the listener was removed.
6862
- EventEmitter.prototype.removeListener = function removeListener(type, listener) {
6863
- var list, events, position, i, originalListener;
6864
- checkListener(listener);
6865
- events = this._events;
6866
- if (events === undefined) return this;
6867
- list = events[type];
6868
- if (list === undefined) return this;
6869
- if (list === listener || list.listener === listener) {
6870
- if (--this._eventsCount === 0) this._events = Object.create(null);else {
6871
- delete events[type];
6872
- if (events.removeListener) this.emit('removeListener', type, list.listener || listener);
6873
- }
6874
- } else if (typeof list !== 'function') {
6875
- position = -1;
6876
- for (i = list.length - 1; i >= 0; i--) {
6877
- if (list[i] === listener || list[i].listener === listener) {
6878
- originalListener = list[i].listener;
6879
- position = i;
6880
- break;
6770
+ /**
6771
+ * Return the listeners registered for a given event.
6772
+ *
6773
+ * @param {(String|Symbol)} event The event name.
6774
+ * @returns {Array} The registered listeners.
6775
+ * @public
6776
+ */
6777
+ EventEmitter.prototype.listeners = function listeners(event) {
6778
+ var evt = prefix ? prefix + event : event,
6779
+ handlers = this._events[evt];
6780
+ if (!handlers) return [];
6781
+ if (handlers.fn) return [handlers.fn];
6782
+ for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {
6783
+ ee[i] = handlers[i].fn;
6784
+ }
6785
+ return ee;
6786
+ };
6787
+
6788
+ /**
6789
+ * Return the number of listeners listening to a given event.
6790
+ *
6791
+ * @param {(String|Symbol)} event The event name.
6792
+ * @returns {Number} The number of listeners.
6793
+ * @public
6794
+ */
6795
+ EventEmitter.prototype.listenerCount = function listenerCount(event) {
6796
+ var evt = prefix ? prefix + event : event,
6797
+ listeners = this._events[evt];
6798
+ if (!listeners) return 0;
6799
+ if (listeners.fn) return 1;
6800
+ return listeners.length;
6801
+ };
6802
+
6803
+ /**
6804
+ * Calls each of the listeners registered for a given event.
6805
+ *
6806
+ * @param {(String|Symbol)} event The event name.
6807
+ * @returns {Boolean} `true` if the event had listeners, else `false`.
6808
+ * @public
6809
+ */
6810
+ EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
6811
+ var evt = prefix ? prefix + event : event;
6812
+ if (!this._events[evt]) return false;
6813
+ var listeners = this._events[evt],
6814
+ len = arguments.length,
6815
+ args,
6816
+ i;
6817
+ if (listeners.fn) {
6818
+ if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);
6819
+ switch (len) {
6820
+ case 1:
6821
+ return listeners.fn.call(listeners.context), true;
6822
+ case 2:
6823
+ return listeners.fn.call(listeners.context, a1), true;
6824
+ case 3:
6825
+ return listeners.fn.call(listeners.context, a1, a2), true;
6826
+ case 4:
6827
+ return listeners.fn.call(listeners.context, a1, a2, a3), true;
6828
+ case 5:
6829
+ return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;
6830
+ case 6:
6831
+ return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;
6832
+ }
6833
+ for (i = 1, args = new Array(len - 1); i < len; i++) {
6834
+ args[i - 1] = arguments[i];
6835
+ }
6836
+ listeners.fn.apply(listeners.context, args);
6837
+ } else {
6838
+ var length = listeners.length,
6839
+ j;
6840
+ for (i = 0; i < length; i++) {
6841
+ if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);
6842
+ switch (len) {
6843
+ case 1:
6844
+ listeners[i].fn.call(listeners[i].context);
6845
+ break;
6846
+ case 2:
6847
+ listeners[i].fn.call(listeners[i].context, a1);
6848
+ break;
6849
+ case 3:
6850
+ listeners[i].fn.call(listeners[i].context, a1, a2);
6851
+ break;
6852
+ case 4:
6853
+ listeners[i].fn.call(listeners[i].context, a1, a2, a3);
6854
+ break;
6855
+ default:
6856
+ if (!args) for (j = 1, args = new Array(len - 1); j < len; j++) {
6857
+ args[j - 1] = arguments[j];
6858
+ }
6859
+ listeners[i].fn.apply(listeners[i].context, args);
6860
+ }
6881
6861
  }
6882
6862
  }
6883
- if (position < 0) return this;
6884
- if (position === 0) list.shift();else {
6885
- spliceOne(list, position);
6863
+ return true;
6864
+ };
6865
+
6866
+ /**
6867
+ * Add a listener for a given event.
6868
+ *
6869
+ * @param {(String|Symbol)} event The event name.
6870
+ * @param {Function} fn The listener function.
6871
+ * @param {*} [context=this] The context to invoke the listener with.
6872
+ * @returns {EventEmitter} `this`.
6873
+ * @public
6874
+ */
6875
+ EventEmitter.prototype.on = function on(event, fn, context) {
6876
+ return addListener(this, event, fn, context, false);
6877
+ };
6878
+
6879
+ /**
6880
+ * Add a one-time listener for a given event.
6881
+ *
6882
+ * @param {(String|Symbol)} event The event name.
6883
+ * @param {Function} fn The listener function.
6884
+ * @param {*} [context=this] The context to invoke the listener with.
6885
+ * @returns {EventEmitter} `this`.
6886
+ * @public
6887
+ */
6888
+ EventEmitter.prototype.once = function once(event, fn, context) {
6889
+ return addListener(this, event, fn, context, true);
6890
+ };
6891
+
6892
+ /**
6893
+ * Remove the listeners of a given event.
6894
+ *
6895
+ * @param {(String|Symbol)} event The event name.
6896
+ * @param {Function} fn Only remove the listeners that match this function.
6897
+ * @param {*} context Only remove the listeners that have this context.
6898
+ * @param {Boolean} once Only remove one-time listeners.
6899
+ * @returns {EventEmitter} `this`.
6900
+ * @public
6901
+ */
6902
+ EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {
6903
+ var evt = prefix ? prefix + event : event;
6904
+ if (!this._events[evt]) return this;
6905
+ if (!fn) {
6906
+ clearEvent(this, evt);
6907
+ return this;
6886
6908
  }
6887
- if (list.length === 1) events[type] = list[0];
6888
- if (events.removeListener !== undefined) this.emit('removeListener', type, originalListener || listener);
6889
- }
6890
- return this;
6891
- };
6892
- EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
6893
- EventEmitter.prototype.removeAllListeners = function removeAllListeners(type) {
6894
- var listeners, events, i;
6895
- events = this._events;
6896
- if (events === undefined) return this;
6897
-
6898
- // not listening for removeListener, no need to emit
6899
- if (events.removeListener === undefined) {
6900
- if (arguments.length === 0) {
6901
- this._events = Object.create(null);
6902
- this._eventsCount = 0;
6903
- } else if (events[type] !== undefined) {
6904
- if (--this._eventsCount === 0) this._events = Object.create(null);else delete events[type];
6909
+ var listeners = this._events[evt];
6910
+ if (listeners.fn) {
6911
+ if (listeners.fn === fn && (!once || listeners.once) && (!context || listeners.context === context)) {
6912
+ clearEvent(this, evt);
6913
+ }
6914
+ } else {
6915
+ for (var i = 0, events = [], length = listeners.length; i < length; i++) {
6916
+ if (listeners[i].fn !== fn || once && !listeners[i].once || context && listeners[i].context !== context) {
6917
+ events.push(listeners[i]);
6918
+ }
6919
+ }
6920
+
6921
+ //
6922
+ // Reset the array, or remove it completely if we have no more listeners.
6923
+ //
6924
+ if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;else clearEvent(this, evt);
6905
6925
  }
6906
6926
  return this;
6907
- }
6927
+ };
6908
6928
 
6909
- // emit removeListener for all listeners on all events
6910
- if (arguments.length === 0) {
6911
- var keys = Object.keys(events);
6912
- var key;
6913
- for (i = 0; i < keys.length; ++i) {
6914
- key = keys[i];
6915
- if (key === 'removeListener') continue;
6916
- this.removeAllListeners(key);
6929
+ /**
6930
+ * Remove all listeners, or those of the specified event.
6931
+ *
6932
+ * @param {(String|Symbol)} [event] The event name.
6933
+ * @returns {EventEmitter} `this`.
6934
+ * @public
6935
+ */
6936
+ EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {
6937
+ var evt;
6938
+ if (event) {
6939
+ evt = prefix ? prefix + event : event;
6940
+ if (this._events[evt]) clearEvent(this, evt);
6941
+ } else {
6942
+ this._events = new Events();
6943
+ this._eventsCount = 0;
6917
6944
  }
6918
- this.removeAllListeners('removeListener');
6919
- this._events = Object.create(null);
6920
- this._eventsCount = 0;
6921
6945
  return this;
6946
+ };
6947
+
6948
+ //
6949
+ // Alias methods names because people roll like that.
6950
+ //
6951
+ EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
6952
+ EventEmitter.prototype.addListener = EventEmitter.prototype.on;
6953
+
6954
+ //
6955
+ // Expose the prefix.
6956
+ //
6957
+ EventEmitter.prefixed = prefix;
6958
+
6959
+ //
6960
+ // Allow `EventEmitter` to be imported as module namespace.
6961
+ //
6962
+ EventEmitter.EventEmitter = EventEmitter;
6963
+
6964
+ //
6965
+ // Expose the module.
6966
+ //
6967
+ {
6968
+ module.exports = EventEmitter;
6922
6969
  }
6923
- listeners = events[type];
6924
- if (typeof listeners === 'function') {
6925
- this.removeListener(type, listeners);
6926
- } else if (listeners !== undefined) {
6927
- // LIFO order
6928
- for (i = listeners.length - 1; i >= 0; i--) {
6929
- this.removeListener(type, listeners[i]);
6930
- }
6931
- }
6932
- return this;
6933
- };
6934
- function _listeners(target, type, unwrap) {
6935
- var events = target._events;
6936
- if (events === undefined) return [];
6937
- var evlistener = events[type];
6938
- if (evlistener === undefined) return [];
6939
- if (typeof evlistener === 'function') return unwrap ? [evlistener.listener || evlistener] : [evlistener];
6940
- return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);
6941
- }
6942
- EventEmitter.prototype.listeners = function listeners(type) {
6943
- return _listeners(this, type, true);
6944
- };
6945
- EventEmitter.prototype.rawListeners = function rawListeners(type) {
6946
- return _listeners(this, type, false);
6947
- };
6948
- EventEmitter.listenerCount = function (emitter, type) {
6949
- if (typeof emitter.listenerCount === 'function') {
6950
- return emitter.listenerCount(type);
6951
- } else {
6952
- return listenerCount.call(emitter, type);
6953
- }
6954
- };
6955
- EventEmitter.prototype.listenerCount = listenerCount;
6956
- function listenerCount(type) {
6957
- var events = this._events;
6958
- if (events !== undefined) {
6959
- var evlistener = events[type];
6960
- if (typeof evlistener === 'function') {
6961
- return 1;
6962
- } else if (evlistener !== undefined) {
6963
- return evlistener.length;
6964
- }
6965
- }
6966
- return 0;
6967
- }
6968
- EventEmitter.prototype.eventNames = function eventNames() {
6969
- return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : [];
6970
- };
6971
- function arrayClone(arr, n) {
6972
- var copy = new Array(n);
6973
- for (var i = 0; i < n; ++i) copy[i] = arr[i];
6974
- return copy;
6975
- }
6976
- function spliceOne(list, index) {
6977
- for (; index + 1 < list.length; index++) list[index] = list[index + 1];
6978
- list.pop();
6979
- }
6980
- function unwrapListeners(arr) {
6981
- var ret = new Array(arr.length);
6982
- for (var i = 0; i < ret.length; ++i) {
6983
- ret[i] = arr[i].listener || arr[i];
6984
- }
6985
- return ret;
6986
- }
6987
- function once(emitter, name) {
6988
- return new Promise(function (resolve, reject) {
6989
- function errorListener(err) {
6990
- emitter.removeListener(name, resolver);
6991
- reject(err);
6992
- }
6993
- function resolver() {
6994
- if (typeof emitter.removeListener === 'function') {
6995
- emitter.removeListener('error', errorListener);
6996
- }
6997
- resolve([].slice.call(arguments));
6998
- }
6999
- eventTargetAgnosticAddListener(emitter, name, resolver, {
7000
- once: true
7001
- });
7002
- if (name !== 'error') {
7003
- addErrorHandlerIfEventEmitter(emitter, errorListener, {
7004
- once: true
7005
- });
7006
- }
7007
- });
7008
- }
7009
- function addErrorHandlerIfEventEmitter(emitter, handler, flags) {
7010
- if (typeof emitter.on === 'function') {
7011
- eventTargetAgnosticAddListener(emitter, 'error', handler, flags);
7012
- }
7013
- }
7014
- function eventTargetAgnosticAddListener(emitter, name, listener, flags) {
7015
- if (typeof emitter.on === 'function') {
7016
- if (flags.once) {
7017
- emitter.once(name, listener);
7018
- } else {
7019
- emitter.on(name, listener);
7020
- }
7021
- } else if (typeof emitter.addEventListener === 'function') {
7022
- // EventTarget does not have `error` event semantics like Node
7023
- // EventEmitters, we do not listen for `error` events here.
7024
- emitter.addEventListener(name, function wrapListener(arg) {
7025
- // IE does not have builtin `{ once: true }` support so we
7026
- // have to do it manually.
7027
- if (flags.once) {
7028
- emitter.removeEventListener(name, wrapListener);
7029
- }
7030
- listener(arg);
7031
- });
7032
- } else {
7033
- throw new TypeError('The "emitter" argument must be of type EventEmitter. Received type ' + typeof emitter);
7034
- }
7035
- }
7036
- var eventsExports = events.exports;
6970
+ })(eventemitter3);
6971
+ var eventemitter3Exports = eventemitter3.exports;
6972
+ var EventEmitter = /*@__PURE__*/getDefaultExportFromCjs(eventemitter3Exports);
7037
6973
 
7038
6974
  /*
7039
6975
  * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
@@ -14251,7 +14187,7 @@ function getMatch(exp, ua) {
14251
14187
  return match && match.length >= id && match[id] || '';
14252
14188
  }
14253
14189
 
14254
- var version$1 = "1.10.0";
14190
+ var version$1 = "1.11.0";
14255
14191
 
14256
14192
  const version = version$1;
14257
14193
  const protocolVersion = 9;
@@ -14566,7 +14502,7 @@ function getEmptyVideoStreamTrack() {
14566
14502
  if (!emptyVideoStreamTrack) {
14567
14503
  emptyVideoStreamTrack = createDummyVideoStreamTrack();
14568
14504
  }
14569
- return emptyVideoStreamTrack;
14505
+ return emptyVideoStreamTrack.clone();
14570
14506
  }
14571
14507
  function createDummyVideoStreamTrack() {
14572
14508
  let width = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 16;
@@ -14601,8 +14537,11 @@ function getEmptyAudioStreamTrack() {
14601
14537
  // implementation adapted from https://blog.mozilla.org/webrtc/warm-up-with-replacetrack/
14602
14538
  const ctx = new AudioContext();
14603
14539
  const oscillator = ctx.createOscillator();
14540
+ const gain = ctx.createGain();
14541
+ gain.gain.setValueAtTime(0, 0);
14604
14542
  const dst = ctx.createMediaStreamDestination();
14605
- oscillator.connect(dst);
14543
+ oscillator.connect(gain);
14544
+ gain.connect(dst);
14606
14545
  oscillator.start();
14607
14546
  [emptyAudioStreamTrack] = dst.stream.getAudioTracks();
14608
14547
  if (!emptyAudioStreamTrack) {
@@ -14610,7 +14549,7 @@ function getEmptyAudioStreamTrack() {
14610
14549
  }
14611
14550
  emptyAudioStreamTrack.enabled = false;
14612
14551
  }
14613
- return emptyAudioStreamTrack;
14552
+ return emptyAudioStreamTrack.clone();
14614
14553
  }
14615
14554
  class Future {
14616
14555
  constructor(futureBase, onFinally) {
@@ -16082,7 +16021,7 @@ const PCEvents = {
16082
16021
  NegotiationComplete: 'negotiationComplete'
16083
16022
  };
16084
16023
  /** @internal */
16085
- class PCTransport extends eventsExports.EventEmitter {
16024
+ class PCTransport extends EventEmitter {
16086
16025
  constructor(config) {
16087
16026
  let mediaConstraints = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
16088
16027
  super();
@@ -17017,7 +16956,7 @@ const BACKGROUND_REACTION_DELAY = 5000;
17017
16956
  // keep old audio elements when detached, we would re-use them since on iOS
17018
16957
  // Safari tracks which audio elements have been "blessed" by the user.
17019
16958
  const recycledElements = [];
17020
- class Track extends eventsExports.EventEmitter {
16959
+ class Track extends EventEmitter {
17021
16960
  constructor(mediaTrack, kind) {
17022
16961
  super();
17023
16962
  this.attachedElements = [];
@@ -17041,7 +16980,6 @@ class Track extends eventsExports.EventEmitter {
17041
16980
  this.handleAppVisibilityChanged();
17042
16981
  }
17043
16982
  };
17044
- this.setMaxListeners(100);
17045
16983
  this.kind = kind;
17046
16984
  this._mediaStreamTrack = mediaTrack;
17047
16985
  this._mediaStreamID = mediaTrack.id;
@@ -17361,7 +17299,7 @@ var PCState;
17361
17299
  PCState[PCState["Closed"] = 4] = "Closed";
17362
17300
  })(PCState || (PCState = {}));
17363
17301
  /** @internal */
17364
- class RTCEngine extends eventsExports.EventEmitter {
17302
+ class RTCEngine extends EventEmitter {
17365
17303
  get isClosed() {
17366
17304
  return this._isClosed;
17367
17305
  }
@@ -17499,6 +17437,7 @@ class RTCEngine extends eventsExports.EventEmitter {
17499
17437
  };
17500
17438
  this.once(EngineEvent.Restarted, onRestarted);
17501
17439
  this.once(EngineEvent.Disconnected, onDisconnected);
17440
+ this.once(EngineEvent.Closing, onDisconnected);
17502
17441
  });
17503
17442
  };
17504
17443
  this.updateAndEmitDCBufferStatus = kind => {
@@ -18291,7 +18230,7 @@ class RTCEngine extends eventsExports.EventEmitter {
18291
18230
  }
18292
18231
  this.hasPublished = true;
18293
18232
  const handleClosed = () => {
18294
- livekitLogger.debug('engine disconnected while negotiation was ongoing');
18233
+ livekitLogger.warn('engine disconnected while negotiation was ongoing');
18295
18234
  cleanup();
18296
18235
  resolve();
18297
18236
  return;
@@ -18440,12 +18379,16 @@ class LocalTrack extends Track {
18440
18379
  }
18441
18380
  this.emit(TrackEvent.Ended, this);
18442
18381
  };
18443
- this._mediaStreamTrack.addEventListener('ended', this.handleEnded);
18444
- this.constraints = constraints !== null && constraints !== void 0 ? constraints : mediaTrack.getConstraints();
18445
18382
  this.reacquireTrack = false;
18446
18383
  this.providedByUser = userProvidedTrack;
18447
18384
  this.muteLock = new Mutex();
18448
18385
  this.pauseUpstreamLock = new Mutex();
18386
+ // added to satisfy TS compiler, constraints are synced with MediaStreamTrack
18387
+ this.constraints = mediaTrack.getConstraints();
18388
+ this.setMediaStreamTrack(mediaTrack);
18389
+ if (constraints) {
18390
+ this.constraints = constraints;
18391
+ }
18449
18392
  }
18450
18393
  get id() {
18451
18394
  return this._mediaStreamTrack.id;
@@ -18476,6 +18419,53 @@ class LocalTrack extends Track {
18476
18419
  var _a, _b;
18477
18420
  return (_b = (_a = this.processor) === null || _a === void 0 ? void 0 : _a.processedTrack) !== null && _b !== void 0 ? _b : this._mediaStreamTrack;
18478
18421
  }
18422
+ setMediaStreamTrack(newTrack) {
18423
+ return __awaiter(this, void 0, void 0, function* () {
18424
+ if (newTrack === this._mediaStreamTrack) {
18425
+ return;
18426
+ }
18427
+ if (this._mediaStreamTrack) {
18428
+ // detach
18429
+ this.attachedElements.forEach(el => {
18430
+ detachTrack(this._mediaStreamTrack, el);
18431
+ });
18432
+ this._mediaStreamTrack.removeEventListener('ended', this.handleEnded);
18433
+ this._mediaStreamTrack.removeEventListener('mute', this.pauseUpstream);
18434
+ this._mediaStreamTrack.removeEventListener('unmute', this.resumeUpstream);
18435
+ if (!this.providedByUser) {
18436
+ this._mediaStreamTrack.stop();
18437
+ }
18438
+ }
18439
+ this.mediaStream = new MediaStream([newTrack]);
18440
+ if (newTrack) {
18441
+ newTrack.addEventListener('ended', this.handleEnded);
18442
+ // when underlying track emits mute, it indicates that the device is unable
18443
+ // to produce media. In this case we'll need to signal with remote that
18444
+ // the track is "muted"
18445
+ // note this is different from LocalTrack.mute because we do not want to
18446
+ // touch MediaStreamTrack.enabled
18447
+ newTrack.addEventListener('mute', () => {
18448
+ livekitLogger.info('pausing upstream due to device mute');
18449
+ this.pauseUpstream();
18450
+ });
18451
+ newTrack.addEventListener('unmute', this.resumeUpstream);
18452
+ this.constraints = newTrack.getConstraints();
18453
+ }
18454
+ if (this.sender) {
18455
+ yield this.sender.replaceTrack(newTrack);
18456
+ }
18457
+ this._mediaStreamTrack = newTrack;
18458
+ if (newTrack) {
18459
+ // sync muted state with the enabled state of the newly provided track
18460
+ this._mediaStreamTrack.enabled = !this.isMuted;
18461
+ // when a valid track is replace, we'd want to start producing
18462
+ yield this.resumeUpstream();
18463
+ this.attachedElements.forEach(el => {
18464
+ attachToElement(newTrack, el);
18465
+ });
18466
+ }
18467
+ });
18468
+ }
18479
18469
  waitForDimensions() {
18480
18470
  let timeout = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : defaultDimensionsTimeout;
18481
18471
  return __awaiter(this, void 0, void 0, function* () {
@@ -18528,30 +18518,10 @@ class LocalTrack extends Track {
18528
18518
  if (!this.sender) {
18529
18519
  throw new TrackInvalidError('unable to replace an unpublished track');
18530
18520
  }
18531
- // detach
18532
- this.attachedElements.forEach(el => {
18533
- detachTrack(this._mediaStreamTrack, el);
18534
- });
18535
- this._mediaStreamTrack.removeEventListener('ended', this.handleEnded);
18536
- // on Safari, the old audio track must be stopped before attempting to acquire
18537
- // the new track, otherwise the new track will stop with
18538
- // 'A MediaStreamTrack ended due to a capture failure`
18539
- if (!this.providedByUser) {
18540
- this._mediaStreamTrack.stop();
18541
- }
18542
- track.addEventListener('ended', this.handleEnded);
18543
18521
  livekitLogger.debug('replace MediaStreamTrack');
18544
- if (this.sender) {
18545
- yield this.sender.replaceTrack(track);
18546
- }
18547
- this._mediaStreamTrack = track;
18548
- // sync muted state with the enabled state of the newly provided track
18549
- this._mediaStreamTrack.enabled = !this.isMuted;
18550
- yield this.resumeUpstream();
18551
- this.attachedElements.forEach(el => {
18552
- attachToElement(track, el);
18553
- });
18554
- this.mediaStream = new MediaStream([track]);
18522
+ this.setMediaStreamTrack(track);
18523
+ // this must be synced *after* setting mediaStreamTrack above, since it relies
18524
+ // on the previous state in order to cleanup
18555
18525
  this.providedByUser = userProvidedTrack;
18556
18526
  if (this.processor) {
18557
18527
  yield this.stopProcessor();
@@ -18574,7 +18544,8 @@ class LocalTrack extends Track {
18574
18544
  } else {
18575
18545
  streamConstraints.audio = constraints;
18576
18546
  }
18577
- // detach
18547
+ // these steps are duplicated from setMediaStreamTrack because we must stop
18548
+ // the previous tracks before new tracks can be acquired
18578
18549
  this.attachedElements.forEach(el => {
18579
18550
  detachTrack(this.mediaStreamTrack, el);
18580
18551
  });
@@ -18588,13 +18559,7 @@ class LocalTrack extends Track {
18588
18559
  const newTrack = mediaStream.getTracks()[0];
18589
18560
  newTrack.addEventListener('ended', this.handleEnded);
18590
18561
  livekitLogger.debug('re-acquired MediaStreamTrack');
18591
- if (this.sender) {
18592
- // Track can be restarted after it's unpublished
18593
- yield this.sender.replaceTrack(newTrack);
18594
- }
18595
- this._mediaStreamTrack = newTrack;
18596
- yield this.resumeUpstream();
18597
- this.mediaStream = mediaStream;
18562
+ this.setMediaStreamTrack(newTrack);
18598
18563
  this.constraints = constraints;
18599
18564
  if (this.processor) {
18600
18565
  const processor = this.processor;
@@ -18686,6 +18651,7 @@ class LocalTrack extends Track {
18686
18651
  }
18687
18652
  this._isUpstreamPaused = false;
18688
18653
  this.emit(TrackEvent.UpstreamResumed, this);
18654
+ // this operation is noop if mediastreamtrack is already being sent
18689
18655
  yield this.sender.replaceTrack(this._mediaStreamTrack);
18690
18656
  } finally {
18691
18657
  unlock();
@@ -19003,25 +18969,23 @@ function computeVideoEncodings(isScreenShare, width, height, options) {
19003
18969
  const original = new VideoPreset(width, height, videoEncoding.maxBitrate, videoEncoding.maxFramerate);
19004
18970
  if (scalabilityMode && isSVCCodec(videoCodec)) {
19005
18971
  livekitLogger.debug("using svc with scalabilityMode ".concat(scalabilityMode));
18972
+ const sm = new ScalabilityMode(scalabilityMode);
19006
18973
  const encodings = [];
19007
- // svc use first encoding as the original, so we sort encoding from high to low
19008
- switch (scalabilityMode) {
19009
- case 'L3T3':
19010
- case 'L3T3_KEY':
19011
- encodings.push({
19012
- rid: videoRids[2],
19013
- maxBitrate: videoEncoding.maxBitrate,
19014
- /* @ts-ignore */
19015
- maxFramerate: original.encoding.maxFramerate,
19016
- /* @ts-ignore */
19017
- scalabilityMode: scalabilityMode
19018
- });
19019
- livekitLogger.debug('encodings', encodings);
19020
- return encodings;
19021
- default:
19022
- // TODO : support other scalability modes
19023
- throw new Error("unsupported scalabilityMode: ".concat(scalabilityMode));
18974
+ if (sm.spatial > 3) {
18975
+ throw new Error("unsupported scalabilityMode: ".concat(scalabilityMode));
18976
+ }
18977
+ for (let i = 0; i < sm.spatial; i += 1) {
18978
+ encodings.push({
18979
+ rid: videoRids[2 - i],
18980
+ maxBitrate: videoEncoding.maxBitrate / Math.pow(3, i),
18981
+ /* @ts-ignore */
18982
+ maxFramerate: original.encoding.maxFramerate
18983
+ });
19024
18984
  }
18985
+ /* @ts-ignore */
18986
+ encodings[0].scalabilityMode = scalabilityMode;
18987
+ livekitLogger.debug('encodings', encodings);
18988
+ return encodings;
19025
18989
  }
19026
18990
  if (!useSimulcast) {
19027
18991
  return [videoEncoding];
@@ -19554,44 +19518,13 @@ function setPublishingLayersForSender(sender, senderEncodings, qualities, sender
19554
19518
  return;
19555
19519
  }
19556
19520
  let hasChanged = false;
19557
- /* @ts-ignore */
19558
- if (encodings.length === 1 && encodings[0].scalabilityMode) {
19559
- // svc dynacast encodings
19560
- const encoding = encodings[0];
19561
- /* @ts-ignore */
19562
- // const mode = new ScalabilityMode(encoding.scalabilityMode);
19563
- let maxQuality = VideoQuality.OFF;
19564
- qualities.forEach(q => {
19565
- if (q.enabled && (maxQuality === VideoQuality.OFF || q.quality > maxQuality)) {
19566
- maxQuality = q.quality;
19567
- }
19568
- });
19569
- if (maxQuality === VideoQuality.OFF) {
19570
- if (encoding.active) {
19571
- encoding.active = false;
19572
- hasChanged = true;
19573
- }
19574
- } else if (!encoding.active /* || mode.spatial !== maxQuality + 1*/) {
19575
- hasChanged = true;
19576
- encoding.active = true;
19577
- /* disable closable spatial layer as it has video blur/frozen issue with current server/client
19578
- 1. chrome 113: when switching to up layer with scalability Mode change, it will generate a
19521
+ /* disable closable spatial layer as it has video blur / frozen issue with current server / client
19522
+ 1. chrome 113: when switching to up layer with scalability Mode change, it will generate a
19579
19523
  low resolution frame and recover very quickly, but noticable
19580
- 2. livekit sfu: additional pli request cause video frozen for a few frames, also noticable
19581
- @ts-ignore
19582
- const originalMode = new ScalabilityMode(senderEncodings[0].scalabilityMode)
19583
- mode.spatial = maxQuality + 1;
19584
- mode.suffix = originalMode.suffix;
19585
- if (mode.spatial === 1) {
19586
- // no suffix for L1Tx
19587
- mode.suffix = undefined;
19588
- }
19589
- @ts-ignore
19590
- encoding.scalabilityMode = mode.toString();
19591
- encoding.scaleResolutionDownBy = 2 ** (2 - maxQuality);
19592
- */
19593
- }
19594
- } else {
19524
+ 2. livekit sfu: additional pli request cause video frozen for a few frames, also noticable */
19525
+ const closableSpatial = false;
19526
+ /* @ts-ignore */
19527
+ if (closableSpatial && encodings[0].scalabilityMode) ; else {
19595
19528
  // simulcast dynacast encodings
19596
19529
  encodings.forEach((encoding, idx) => {
19597
19530
  var _a;
@@ -19648,7 +19581,7 @@ function videoQualityForRid(rid) {
19648
19581
  return VideoQuality.UNRECOGNIZED;
19649
19582
  }
19650
19583
  }
19651
- function videoLayersFromEncodings(width, height, encodings) {
19584
+ function videoLayersFromEncodings(width, height, encodings, svc) {
19652
19585
  // default to a single layer, HQ
19653
19586
  if (!encodings) {
19654
19587
  return [{
@@ -19659,8 +19592,7 @@ function videoLayersFromEncodings(width, height, encodings) {
19659
19592
  ssrc: 0
19660
19593
  }];
19661
19594
  }
19662
- /* @ts-ignore */
19663
- if (encodings.length === 1 && encodings[0].scalabilityMode) {
19595
+ if (svc) {
19664
19596
  // svc layers
19665
19597
  /* @ts-ignore */
19666
19598
  const sm = new ScalabilityMode(encodings[0].scalabilityMode);
@@ -20114,20 +20046,19 @@ class RemoteVideoTrack extends RemoteTrack {
20114
20046
  this.emit(TrackEvent.VisibilityChanged, isVisible, this);
20115
20047
  }
20116
20048
  updateDimensions() {
20117
- var _a, _b, _c, _d;
20049
+ var _a, _b;
20118
20050
  let maxWidth = 0;
20119
20051
  let maxHeight = 0;
20052
+ const pixelDensity = this.getPixelDensity();
20120
20053
  for (const info of this.elementInfos) {
20121
- const pixelDensity = (_b = (_a = this.adaptiveStreamSettings) === null || _a === void 0 ? void 0 : _a.pixelDensity) !== null && _b !== void 0 ? _b : 1;
20122
- const pixelDensityValue = pixelDensity === 'screen' ? getDevicePixelRatio() : pixelDensity;
20123
- const currentElementWidth = info.width() * pixelDensityValue;
20124
- const currentElementHeight = info.height() * pixelDensityValue;
20054
+ const currentElementWidth = info.width() * pixelDensity;
20055
+ const currentElementHeight = info.height() * pixelDensity;
20125
20056
  if (currentElementWidth + currentElementHeight > maxWidth + maxHeight) {
20126
20057
  maxWidth = currentElementWidth;
20127
20058
  maxHeight = currentElementHeight;
20128
20059
  }
20129
20060
  }
20130
- if (((_c = this.lastDimensions) === null || _c === void 0 ? void 0 : _c.width) === maxWidth && ((_d = this.lastDimensions) === null || _d === void 0 ? void 0 : _d.height) === maxHeight) {
20061
+ if (((_a = this.lastDimensions) === null || _a === void 0 ? void 0 : _a.width) === maxWidth && ((_b = this.lastDimensions) === null || _b === void 0 ? void 0 : _b.height) === maxHeight) {
20131
20062
  return;
20132
20063
  }
20133
20064
  this.lastDimensions = {
@@ -20136,6 +20067,24 @@ class RemoteVideoTrack extends RemoteTrack {
20136
20067
  };
20137
20068
  this.emit(TrackEvent.VideoDimensionsChanged, this.lastDimensions, this);
20138
20069
  }
20070
+ getPixelDensity() {
20071
+ var _a;
20072
+ const pixelDensity = (_a = this.adaptiveStreamSettings) === null || _a === void 0 ? void 0 : _a.pixelDensity;
20073
+ if (pixelDensity === 'screen') {
20074
+ return getDevicePixelRatio();
20075
+ } else if (!pixelDensity) {
20076
+ // when unset, we'll pick a sane default here.
20077
+ // for higher pixel density devices (mobile phones, etc), we'll use 2
20078
+ // otherwise it defaults to 1
20079
+ const devicePixelRatio = getDevicePixelRatio();
20080
+ if (devicePixelRatio > 2) {
20081
+ return 2;
20082
+ } else {
20083
+ return 1;
20084
+ }
20085
+ }
20086
+ return pixelDensity;
20087
+ }
20139
20088
  }
20140
20089
  class HTMLElementInfo {
20141
20090
  get visible() {
@@ -20221,7 +20170,7 @@ function isElementInViewport(el) {
20221
20170
  return top < window.pageYOffset + window.innerHeight && left < window.pageXOffset + window.innerWidth && top + height > window.pageYOffset && left + width > window.pageXOffset && !hidden && (opacity !== '' ? parseFloat(opacity) > 0 : true) && display !== 'none';
20222
20171
  }
20223
20172
 
20224
- class TrackPublication extends eventsExports.EventEmitter {
20173
+ class TrackPublication extends EventEmitter {
20225
20174
  constructor(kind, id, name) {
20226
20175
  super();
20227
20176
  this.metadataMuted = false;
@@ -20231,7 +20180,6 @@ class TrackPublication extends eventsExports.EventEmitter {
20231
20180
  this.handleUnmuted = () => {
20232
20181
  this.emit(TrackEvent.Unmuted);
20233
20182
  };
20234
- this.setMaxListeners(100);
20235
20183
  this.kind = kind;
20236
20184
  this.trackSid = id;
20237
20185
  this.trackName = name;
@@ -20401,7 +20349,7 @@ function qualityFromProto(q) {
20401
20349
  return ConnectionQuality.Unknown;
20402
20350
  }
20403
20351
  }
20404
- class Participant extends eventsExports.EventEmitter {
20352
+ class Participant extends EventEmitter {
20405
20353
  /** @internal */
20406
20354
  constructor(sid, identity, name, metadata) {
20407
20355
  super();
@@ -20410,7 +20358,6 @@ class Participant extends eventsExports.EventEmitter {
20410
20358
  /** if participant is currently speaking */
20411
20359
  this.isSpeaking = false;
20412
20360
  this._connectionQuality = ConnectionQuality.Unknown;
20413
- this.setMaxListeners(100);
20414
20361
  this.sid = sid;
20415
20362
  this.identity = identity;
20416
20363
  this.name = name;
@@ -21114,8 +21061,11 @@ class LocalParticipant extends Participant {
21114
21061
  };
21115
21062
  this.handleDisconnected = () => {
21116
21063
  var _a, _b;
21117
- (_b = (_a = this.reconnectFuture) === null || _a === void 0 ? void 0 : _a.reject) === null || _b === void 0 ? void 0 : _b.call(_a, 'Got disconnected during publishing attempt');
21118
- this.reconnectFuture = undefined;
21064
+ if (this.reconnectFuture) {
21065
+ this.reconnectFuture.promise.catch(e => livekitLogger.warn(e));
21066
+ (_b = (_a = this.reconnectFuture) === null || _a === void 0 ? void 0 : _a.reject) === null || _b === void 0 ? void 0 : _b.call(_a, 'Got disconnected during reconnection attempt');
21067
+ this.reconnectFuture = undefined;
21068
+ }
21119
21069
  };
21120
21070
  this.updateTrackSubscriptionPermissions = () => {
21121
21071
  livekitLogger.debug('updating track subscription permissions', {
@@ -21727,7 +21677,7 @@ class LocalParticipant extends Participant {
21727
21677
  }
21728
21678
  }
21729
21679
  encodings = computeVideoEncodings(track.source === Track.Source.ScreenShare, dims.width, dims.height, opts);
21730
- req.layers = videoLayersFromEncodings(req.width, req.height, encodings);
21680
+ req.layers = videoLayersFromEncodings(req.width, req.height, encodings, isSVCCodec(opts.videoCodec));
21731
21681
  } else if (track.kind === Track.Kind.Audio) {
21732
21682
  encodings = [{
21733
21683
  maxBitrate: (_h = (_g = opts.audioPreset) === null || _g === void 0 ? void 0 : _g.maxBitrate) !== null && _h !== void 0 ? _h : opts.audioBitrate,
@@ -22107,7 +22057,7 @@ const RoomState = ConnectionState;
22107
22057
  *
22108
22058
  * @noInheritDoc
22109
22059
  */
22110
- class Room extends eventsExports.EventEmitter {
22060
+ class Room extends EventEmitter {
22111
22061
  /**
22112
22062
  * Creates a new Room, the primary construct for a LiveKit session.
22113
22063
  * @param options
@@ -22272,6 +22222,9 @@ class Room extends eventsExports.EventEmitter {
22272
22222
  // capturing both 'pagehide' and 'beforeunload' to capture broadest set of browser behaviors
22273
22223
  window.addEventListener('pagehide', this.onPageLeave);
22274
22224
  window.addEventListener('beforeunload', this.onPageLeave);
22225
+ }
22226
+ if (isWeb()) {
22227
+ document.addEventListener('freeze', this.onPageLeave);
22275
22228
  (_b = navigator.mediaDevices) === null || _b === void 0 ? void 0 : _b.addEventListener('devicechange', this.handleDeviceChange);
22276
22229
  }
22277
22230
  this.setAndEmitConnectionState(ConnectionState.Connected);
@@ -22589,7 +22542,6 @@ class Room extends eventsExports.EventEmitter {
22589
22542
  this.onLocalParticipantPermissionsChanged = prevPermissions => {
22590
22543
  this.emit(RoomEvent.ParticipantPermissionsChanged, prevPermissions, this.localParticipant);
22591
22544
  };
22592
- this.setMaxListeners(100);
22593
22545
  this.participants = new Map();
22594
22546
  this.cachedParticipantSids = [];
22595
22547
  this.identityToSid = new Map();
@@ -22813,6 +22765,28 @@ class Room extends eventsExports.EventEmitter {
22813
22765
  return __awaiter(this, void 0, void 0, function* () {
22814
22766
  yield this.acquireAudioContext();
22815
22767
  const elements = [];
22768
+ if (isSafari()) {
22769
+ /**
22770
+ * iOS Safari blocks audio element playback if
22771
+ * - user is not publishing audio themselves and
22772
+ * - no other audio source is playing
22773
+ *
22774
+ * as a workaround, we create an audio element with an empty track, so that
22775
+ * silent audio is always playing
22776
+ */
22777
+ const audioId = 'livekit-dummy-audio-el';
22778
+ let dummyAudioEl = document.getElementById(audioId);
22779
+ if (!dummyAudioEl) {
22780
+ dummyAudioEl = document.createElement('audio');
22781
+ dummyAudioEl.autoplay = true;
22782
+ dummyAudioEl.hidden = true;
22783
+ const track = getEmptyAudioStreamTrack();
22784
+ track.enabled = true;
22785
+ dummyAudioEl.srcObject = new MediaStream([track]);
22786
+ document.body.append(dummyAudioEl);
22787
+ }
22788
+ elements.push(dummyAudioEl);
22789
+ }
22816
22790
  this.participants.forEach(p => {
22817
22791
  p.audioTracks.forEach(t => {
22818
22792
  if (t.track) {
@@ -23008,6 +22982,7 @@ class Room extends eventsExports.EventEmitter {
23008
22982
  if (isWeb()) {
23009
22983
  window.removeEventListener('beforeunload', this.onPageLeave);
23010
22984
  window.removeEventListener('pagehide', this.onPageLeave);
22985
+ window.removeEventListener('freeze', this.onPageLeave);
23011
22986
  (_a = navigator.mediaDevices) === null || _a === void 0 ? void 0 : _a.removeEventListener('devicechange', this.handleDeviceChange);
23012
22987
  }
23013
22988
  } finally {
@@ -23321,6 +23296,10 @@ class Room extends eventsExports.EventEmitter {
23321
23296
  for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
23322
23297
  args[_key2 - 1] = arguments[_key2];
23323
23298
  }
23299
+ // emit<E extends keyof RoomEventCallbacks>(
23300
+ // event: E,
23301
+ // ...args: Parameters<RoomEventCallbacks[E]>
23302
+ // ): boolean {
23324
23303
  // active speaker updates are too spammy
23325
23304
  if (event !== RoomEvent.ActiveSpeakersChanged) {
23326
23305
  livekitLogger.debug("room event ".concat(event), {
@@ -23340,7 +23319,7 @@ var CheckStatus;
23340
23319
  CheckStatus[CheckStatus["SUCCESS"] = 3] = "SUCCESS";
23341
23320
  CheckStatus[CheckStatus["FAILED"] = 4] = "FAILED";
23342
23321
  })(CheckStatus || (CheckStatus = {}));
23343
- class Checker extends eventsExports.EventEmitter {
23322
+ class Checker extends EventEmitter {
23344
23323
  constructor(url, token) {
23345
23324
  let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
23346
23325
  super();
@@ -23752,7 +23731,7 @@ class WebSocketCheck extends Checker {
23752
23731
  }
23753
23732
  }
23754
23733
 
23755
- class ConnectionCheck extends eventsExports.EventEmitter {
23734
+ class ConnectionCheck extends EventEmitter {
23756
23735
  constructor(url, token) {
23757
23736
  super();
23758
23737
  this.checkResults = new Map();