livekit-client 1.10.0 → 1.11.1

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 +504 -527
  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 +3 -2
  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 +3 -2
  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 +68 -46
  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() {}
6672
+
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);
6720
6682
 
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 + '.');
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.1";
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;
@@ -18438,14 +18377,66 @@ class LocalTrack extends Track {
18438
18377
  if (this.isInBackground) {
18439
18378
  this.reacquireTrack = true;
18440
18379
  }
18380
+ this._mediaStreamTrack.removeEventListener('mute', this.pauseUpstream);
18381
+ this._mediaStreamTrack.removeEventListener('unmute', this.resumeUpstream);
18441
18382
  this.emit(TrackEvent.Ended, this);
18442
18383
  };
18443
- this._mediaStreamTrack.addEventListener('ended', this.handleEnded);
18444
- this.constraints = constraints !== null && constraints !== void 0 ? constraints : mediaTrack.getConstraints();
18384
+ /**
18385
+ * pauses publishing to the server without disabling the local MediaStreamTrack
18386
+ * this is used to display a user's own video locally while pausing publishing to
18387
+ * the server.
18388
+ * this API is unsupported on Safari < 12 due to a bug
18389
+ **/
18390
+ this.pauseUpstream = () => __awaiter(this, void 0, void 0, function* () {
18391
+ const unlock = yield this.pauseUpstreamLock.lock();
18392
+ try {
18393
+ if (this._isUpstreamPaused === true) {
18394
+ return;
18395
+ }
18396
+ if (!this.sender) {
18397
+ livekitLogger.warn('unable to pause upstream for an unpublished track');
18398
+ return;
18399
+ }
18400
+ this._isUpstreamPaused = true;
18401
+ this.emit(TrackEvent.UpstreamPaused, this);
18402
+ const browser = getBrowser();
18403
+ if ((browser === null || browser === void 0 ? void 0 : browser.name) === 'Safari' && compareVersions(browser.version, '12.0') < 0) {
18404
+ // https://bugs.webkit.org/show_bug.cgi?id=184911
18405
+ throw new DeviceUnsupportedError('pauseUpstream is not supported on Safari < 12.');
18406
+ }
18407
+ yield this.sender.replaceTrack(null);
18408
+ } finally {
18409
+ unlock();
18410
+ }
18411
+ });
18412
+ this.resumeUpstream = () => __awaiter(this, void 0, void 0, function* () {
18413
+ const unlock = yield this.pauseUpstreamLock.lock();
18414
+ try {
18415
+ if (this._isUpstreamPaused === false) {
18416
+ return;
18417
+ }
18418
+ if (!this.sender) {
18419
+ livekitLogger.warn('unable to resume upstream for an unpublished track');
18420
+ return;
18421
+ }
18422
+ this._isUpstreamPaused = false;
18423
+ this.emit(TrackEvent.UpstreamResumed, this);
18424
+ // this operation is noop if mediastreamtrack is already being sent
18425
+ yield this.sender.replaceTrack(this._mediaStreamTrack);
18426
+ } finally {
18427
+ unlock();
18428
+ }
18429
+ });
18445
18430
  this.reacquireTrack = false;
18446
18431
  this.providedByUser = userProvidedTrack;
18447
18432
  this.muteLock = new Mutex();
18448
18433
  this.pauseUpstreamLock = new Mutex();
18434
+ // added to satisfy TS compiler, constraints are synced with MediaStreamTrack
18435
+ this.constraints = mediaTrack.getConstraints();
18436
+ this.setMediaStreamTrack(mediaTrack);
18437
+ if (constraints) {
18438
+ this.constraints = constraints;
18439
+ }
18449
18440
  }
18450
18441
  get id() {
18451
18442
  return this._mediaStreamTrack.id;
@@ -18476,6 +18467,50 @@ class LocalTrack extends Track {
18476
18467
  var _a, _b;
18477
18468
  return (_b = (_a = this.processor) === null || _a === void 0 ? void 0 : _a.processedTrack) !== null && _b !== void 0 ? _b : this._mediaStreamTrack;
18478
18469
  }
18470
+ setMediaStreamTrack(newTrack) {
18471
+ return __awaiter(this, void 0, void 0, function* () {
18472
+ if (newTrack === this._mediaStreamTrack) {
18473
+ return;
18474
+ }
18475
+ if (this._mediaStreamTrack) {
18476
+ // detach
18477
+ this.attachedElements.forEach(el => {
18478
+ detachTrack(this._mediaStreamTrack, el);
18479
+ });
18480
+ this._mediaStreamTrack.removeEventListener('ended', this.handleEnded);
18481
+ this._mediaStreamTrack.removeEventListener('mute', this.pauseUpstream);
18482
+ this._mediaStreamTrack.removeEventListener('unmute', this.resumeUpstream);
18483
+ if (!this.providedByUser) {
18484
+ this._mediaStreamTrack.stop();
18485
+ }
18486
+ }
18487
+ this.mediaStream = new MediaStream([newTrack]);
18488
+ if (newTrack) {
18489
+ newTrack.addEventListener('ended', this.handleEnded);
18490
+ // when underlying track emits mute, it indicates that the device is unable
18491
+ // to produce media. In this case we'll need to signal with remote that
18492
+ // the track is "muted"
18493
+ // note this is different from LocalTrack.mute because we do not want to
18494
+ // touch MediaStreamTrack.enabled
18495
+ newTrack.addEventListener('mute', this.pauseUpstream);
18496
+ newTrack.addEventListener('unmute', this.resumeUpstream);
18497
+ this.constraints = newTrack.getConstraints();
18498
+ }
18499
+ if (this.sender) {
18500
+ yield this.sender.replaceTrack(newTrack);
18501
+ }
18502
+ this._mediaStreamTrack = newTrack;
18503
+ if (newTrack) {
18504
+ // sync muted state with the enabled state of the newly provided track
18505
+ this._mediaStreamTrack.enabled = !this.isMuted;
18506
+ // when a valid track is replace, we'd want to start producing
18507
+ yield this.resumeUpstream();
18508
+ this.attachedElements.forEach(el => {
18509
+ attachToElement(newTrack, el);
18510
+ });
18511
+ }
18512
+ });
18513
+ }
18479
18514
  waitForDimensions() {
18480
18515
  let timeout = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : defaultDimensionsTimeout;
18481
18516
  return __awaiter(this, void 0, void 0, function* () {
@@ -18528,30 +18563,10 @@ class LocalTrack extends Track {
18528
18563
  if (!this.sender) {
18529
18564
  throw new TrackInvalidError('unable to replace an unpublished track');
18530
18565
  }
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
18566
  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]);
18567
+ this.setMediaStreamTrack(track);
18568
+ // this must be synced *after* setting mediaStreamTrack above, since it relies
18569
+ // on the previous state in order to cleanup
18555
18570
  this.providedByUser = userProvidedTrack;
18556
18571
  if (this.processor) {
18557
18572
  yield this.stopProcessor();
@@ -18574,7 +18589,8 @@ class LocalTrack extends Track {
18574
18589
  } else {
18575
18590
  streamConstraints.audio = constraints;
18576
18591
  }
18577
- // detach
18592
+ // these steps are duplicated from setMediaStreamTrack because we must stop
18593
+ // the previous tracks before new tracks can be acquired
18578
18594
  this.attachedElements.forEach(el => {
18579
18595
  detachTrack(this.mediaStreamTrack, el);
18580
18596
  });
@@ -18588,13 +18604,7 @@ class LocalTrack extends Track {
18588
18604
  const newTrack = mediaStream.getTracks()[0];
18589
18605
  newTrack.addEventListener('ended', this.handleEnded);
18590
18606
  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;
18607
+ this.setMediaStreamTrack(newTrack);
18598
18608
  this.constraints = constraints;
18599
18609
  if (this.processor) {
18600
18610
  const processor = this.processor;
@@ -18640,58 +18650,12 @@ class LocalTrack extends Track {
18640
18650
  stop() {
18641
18651
  var _a;
18642
18652
  super.stop();
18653
+ this._mediaStreamTrack.removeEventListener('ended', this.handleEnded);
18654
+ this._mediaStreamTrack.removeEventListener('mute', this.pauseUpstream);
18655
+ this._mediaStreamTrack.removeEventListener('unmute', this.resumeUpstream);
18643
18656
  (_a = this.processor) === null || _a === void 0 ? void 0 : _a.destroy();
18644
18657
  this.processor = undefined;
18645
18658
  }
18646
- /**
18647
- * pauses publishing to the server without disabling the local MediaStreamTrack
18648
- * this is used to display a user's own video locally while pausing publishing to
18649
- * the server.
18650
- * this API is unsupported on Safari < 12 due to a bug
18651
- **/
18652
- pauseUpstream() {
18653
- return __awaiter(this, void 0, void 0, function* () {
18654
- const unlock = yield this.pauseUpstreamLock.lock();
18655
- try {
18656
- if (this._isUpstreamPaused === true) {
18657
- return;
18658
- }
18659
- if (!this.sender) {
18660
- livekitLogger.warn('unable to pause upstream for an unpublished track');
18661
- return;
18662
- }
18663
- this._isUpstreamPaused = true;
18664
- this.emit(TrackEvent.UpstreamPaused, this);
18665
- const browser = getBrowser();
18666
- if ((browser === null || browser === void 0 ? void 0 : browser.name) === 'Safari' && compareVersions(browser.version, '12.0') < 0) {
18667
- // https://bugs.webkit.org/show_bug.cgi?id=184911
18668
- throw new DeviceUnsupportedError('pauseUpstream is not supported on Safari < 12.');
18669
- }
18670
- yield this.sender.replaceTrack(null);
18671
- } finally {
18672
- unlock();
18673
- }
18674
- });
18675
- }
18676
- resumeUpstream() {
18677
- return __awaiter(this, void 0, void 0, function* () {
18678
- const unlock = yield this.pauseUpstreamLock.lock();
18679
- try {
18680
- if (this._isUpstreamPaused === false) {
18681
- return;
18682
- }
18683
- if (!this.sender) {
18684
- livekitLogger.warn('unable to resume upstream for an unpublished track');
18685
- return;
18686
- }
18687
- this._isUpstreamPaused = false;
18688
- this.emit(TrackEvent.UpstreamResumed, this);
18689
- yield this.sender.replaceTrack(this._mediaStreamTrack);
18690
- } finally {
18691
- unlock();
18692
- }
18693
- });
18694
- }
18695
18659
  /**
18696
18660
  * Sets a processor on this track.
18697
18661
  * See https://github.com/livekit/track-processors-js for example usage
@@ -19003,25 +18967,23 @@ function computeVideoEncodings(isScreenShare, width, height, options) {
19003
18967
  const original = new VideoPreset(width, height, videoEncoding.maxBitrate, videoEncoding.maxFramerate);
19004
18968
  if (scalabilityMode && isSVCCodec(videoCodec)) {
19005
18969
  livekitLogger.debug("using svc with scalabilityMode ".concat(scalabilityMode));
18970
+ const sm = new ScalabilityMode(scalabilityMode);
19006
18971
  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));
18972
+ if (sm.spatial > 3) {
18973
+ throw new Error("unsupported scalabilityMode: ".concat(scalabilityMode));
18974
+ }
18975
+ for (let i = 0; i < sm.spatial; i += 1) {
18976
+ encodings.push({
18977
+ rid: videoRids[2 - i],
18978
+ maxBitrate: videoEncoding.maxBitrate / Math.pow(3, i),
18979
+ /* @ts-ignore */
18980
+ maxFramerate: original.encoding.maxFramerate
18981
+ });
19024
18982
  }
18983
+ /* @ts-ignore */
18984
+ encodings[0].scalabilityMode = scalabilityMode;
18985
+ livekitLogger.debug('encodings', encodings);
18986
+ return encodings;
19025
18987
  }
19026
18988
  if (!useSimulcast) {
19027
18989
  return [videoEncoding];
@@ -19554,44 +19516,13 @@ function setPublishingLayersForSender(sender, senderEncodings, qualities, sender
19554
19516
  return;
19555
19517
  }
19556
19518
  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
19519
+ /* disable closable spatial layer as it has video blur / frozen issue with current server / client
19520
+ 1. chrome 113: when switching to up layer with scalability Mode change, it will generate a
19579
19521
  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 {
19522
+ 2. livekit sfu: additional pli request cause video frozen for a few frames, also noticable */
19523
+ const closableSpatial = false;
19524
+ /* @ts-ignore */
19525
+ if (closableSpatial && encodings[0].scalabilityMode) ; else {
19595
19526
  // simulcast dynacast encodings
19596
19527
  encodings.forEach((encoding, idx) => {
19597
19528
  var _a;
@@ -19648,7 +19579,7 @@ function videoQualityForRid(rid) {
19648
19579
  return VideoQuality.UNRECOGNIZED;
19649
19580
  }
19650
19581
  }
19651
- function videoLayersFromEncodings(width, height, encodings) {
19582
+ function videoLayersFromEncodings(width, height, encodings, svc) {
19652
19583
  // default to a single layer, HQ
19653
19584
  if (!encodings) {
19654
19585
  return [{
@@ -19659,8 +19590,7 @@ function videoLayersFromEncodings(width, height, encodings) {
19659
19590
  ssrc: 0
19660
19591
  }];
19661
19592
  }
19662
- /* @ts-ignore */
19663
- if (encodings.length === 1 && encodings[0].scalabilityMode) {
19593
+ if (svc) {
19664
19594
  // svc layers
19665
19595
  /* @ts-ignore */
19666
19596
  const sm = new ScalabilityMode(encodings[0].scalabilityMode);
@@ -20114,20 +20044,19 @@ class RemoteVideoTrack extends RemoteTrack {
20114
20044
  this.emit(TrackEvent.VisibilityChanged, isVisible, this);
20115
20045
  }
20116
20046
  updateDimensions() {
20117
- var _a, _b, _c, _d;
20047
+ var _a, _b;
20118
20048
  let maxWidth = 0;
20119
20049
  let maxHeight = 0;
20050
+ const pixelDensity = this.getPixelDensity();
20120
20051
  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;
20052
+ const currentElementWidth = info.width() * pixelDensity;
20053
+ const currentElementHeight = info.height() * pixelDensity;
20125
20054
  if (currentElementWidth + currentElementHeight > maxWidth + maxHeight) {
20126
20055
  maxWidth = currentElementWidth;
20127
20056
  maxHeight = currentElementHeight;
20128
20057
  }
20129
20058
  }
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) {
20059
+ 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
20060
  return;
20132
20061
  }
20133
20062
  this.lastDimensions = {
@@ -20136,6 +20065,24 @@ class RemoteVideoTrack extends RemoteTrack {
20136
20065
  };
20137
20066
  this.emit(TrackEvent.VideoDimensionsChanged, this.lastDimensions, this);
20138
20067
  }
20068
+ getPixelDensity() {
20069
+ var _a;
20070
+ const pixelDensity = (_a = this.adaptiveStreamSettings) === null || _a === void 0 ? void 0 : _a.pixelDensity;
20071
+ if (pixelDensity === 'screen') {
20072
+ return getDevicePixelRatio();
20073
+ } else if (!pixelDensity) {
20074
+ // when unset, we'll pick a sane default here.
20075
+ // for higher pixel density devices (mobile phones, etc), we'll use 2
20076
+ // otherwise it defaults to 1
20077
+ const devicePixelRatio = getDevicePixelRatio();
20078
+ if (devicePixelRatio > 2) {
20079
+ return 2;
20080
+ } else {
20081
+ return 1;
20082
+ }
20083
+ }
20084
+ return pixelDensity;
20085
+ }
20139
20086
  }
20140
20087
  class HTMLElementInfo {
20141
20088
  get visible() {
@@ -20221,7 +20168,7 @@ function isElementInViewport(el) {
20221
20168
  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
20169
  }
20223
20170
 
20224
- class TrackPublication extends eventsExports.EventEmitter {
20171
+ class TrackPublication extends EventEmitter {
20225
20172
  constructor(kind, id, name) {
20226
20173
  super();
20227
20174
  this.metadataMuted = false;
@@ -20231,7 +20178,6 @@ class TrackPublication extends eventsExports.EventEmitter {
20231
20178
  this.handleUnmuted = () => {
20232
20179
  this.emit(TrackEvent.Unmuted);
20233
20180
  };
20234
- this.setMaxListeners(100);
20235
20181
  this.kind = kind;
20236
20182
  this.trackSid = id;
20237
20183
  this.trackName = name;
@@ -20401,7 +20347,7 @@ function qualityFromProto(q) {
20401
20347
  return ConnectionQuality.Unknown;
20402
20348
  }
20403
20349
  }
20404
- class Participant extends eventsExports.EventEmitter {
20350
+ class Participant extends EventEmitter {
20405
20351
  /** @internal */
20406
20352
  constructor(sid, identity, name, metadata) {
20407
20353
  super();
@@ -20410,7 +20356,6 @@ class Participant extends eventsExports.EventEmitter {
20410
20356
  /** if participant is currently speaking */
20411
20357
  this.isSpeaking = false;
20412
20358
  this._connectionQuality = ConnectionQuality.Unknown;
20413
- this.setMaxListeners(100);
20414
20359
  this.sid = sid;
20415
20360
  this.identity = identity;
20416
20361
  this.name = name;
@@ -21114,8 +21059,11 @@ class LocalParticipant extends Participant {
21114
21059
  };
21115
21060
  this.handleDisconnected = () => {
21116
21061
  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;
21062
+ if (this.reconnectFuture) {
21063
+ this.reconnectFuture.promise.catch(e => livekitLogger.warn(e));
21064
+ (_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');
21065
+ this.reconnectFuture = undefined;
21066
+ }
21119
21067
  };
21120
21068
  this.updateTrackSubscriptionPermissions = () => {
21121
21069
  livekitLogger.debug('updating track subscription permissions', {
@@ -21727,7 +21675,7 @@ class LocalParticipant extends Participant {
21727
21675
  }
21728
21676
  }
21729
21677
  encodings = computeVideoEncodings(track.source === Track.Source.ScreenShare, dims.width, dims.height, opts);
21730
- req.layers = videoLayersFromEncodings(req.width, req.height, encodings);
21678
+ req.layers = videoLayersFromEncodings(req.width, req.height, encodings, isSVCCodec(opts.videoCodec));
21731
21679
  } else if (track.kind === Track.Kind.Audio) {
21732
21680
  encodings = [{
21733
21681
  maxBitrate: (_h = (_g = opts.audioPreset) === null || _g === void 0 ? void 0 : _g.maxBitrate) !== null && _h !== void 0 ? _h : opts.audioBitrate,
@@ -22107,7 +22055,7 @@ const RoomState = ConnectionState;
22107
22055
  *
22108
22056
  * @noInheritDoc
22109
22057
  */
22110
- class Room extends eventsExports.EventEmitter {
22058
+ class Room extends EventEmitter {
22111
22059
  /**
22112
22060
  * Creates a new Room, the primary construct for a LiveKit session.
22113
22061
  * @param options
@@ -22272,6 +22220,9 @@ class Room extends eventsExports.EventEmitter {
22272
22220
  // capturing both 'pagehide' and 'beforeunload' to capture broadest set of browser behaviors
22273
22221
  window.addEventListener('pagehide', this.onPageLeave);
22274
22222
  window.addEventListener('beforeunload', this.onPageLeave);
22223
+ }
22224
+ if (isWeb()) {
22225
+ document.addEventListener('freeze', this.onPageLeave);
22275
22226
  (_b = navigator.mediaDevices) === null || _b === void 0 ? void 0 : _b.addEventListener('devicechange', this.handleDeviceChange);
22276
22227
  }
22277
22228
  this.setAndEmitConnectionState(ConnectionState.Connected);
@@ -22589,7 +22540,6 @@ class Room extends eventsExports.EventEmitter {
22589
22540
  this.onLocalParticipantPermissionsChanged = prevPermissions => {
22590
22541
  this.emit(RoomEvent.ParticipantPermissionsChanged, prevPermissions, this.localParticipant);
22591
22542
  };
22592
- this.setMaxListeners(100);
22593
22543
  this.participants = new Map();
22594
22544
  this.cachedParticipantSids = [];
22595
22545
  this.identityToSid = new Map();
@@ -22813,6 +22763,28 @@ class Room extends eventsExports.EventEmitter {
22813
22763
  return __awaiter(this, void 0, void 0, function* () {
22814
22764
  yield this.acquireAudioContext();
22815
22765
  const elements = [];
22766
+ if (isSafari()) {
22767
+ /**
22768
+ * iOS Safari blocks audio element playback if
22769
+ * - user is not publishing audio themselves and
22770
+ * - no other audio source is playing
22771
+ *
22772
+ * as a workaround, we create an audio element with an empty track, so that
22773
+ * silent audio is always playing
22774
+ */
22775
+ const audioId = 'livekit-dummy-audio-el';
22776
+ let dummyAudioEl = document.getElementById(audioId);
22777
+ if (!dummyAudioEl) {
22778
+ dummyAudioEl = document.createElement('audio');
22779
+ dummyAudioEl.autoplay = true;
22780
+ dummyAudioEl.hidden = true;
22781
+ const track = getEmptyAudioStreamTrack();
22782
+ track.enabled = true;
22783
+ dummyAudioEl.srcObject = new MediaStream([track]);
22784
+ document.body.append(dummyAudioEl);
22785
+ }
22786
+ elements.push(dummyAudioEl);
22787
+ }
22816
22788
  this.participants.forEach(p => {
22817
22789
  p.audioTracks.forEach(t => {
22818
22790
  if (t.track) {
@@ -23008,6 +22980,7 @@ class Room extends eventsExports.EventEmitter {
23008
22980
  if (isWeb()) {
23009
22981
  window.removeEventListener('beforeunload', this.onPageLeave);
23010
22982
  window.removeEventListener('pagehide', this.onPageLeave);
22983
+ window.removeEventListener('freeze', this.onPageLeave);
23011
22984
  (_a = navigator.mediaDevices) === null || _a === void 0 ? void 0 : _a.removeEventListener('devicechange', this.handleDeviceChange);
23012
22985
  }
23013
22986
  } finally {
@@ -23321,6 +23294,10 @@ class Room extends eventsExports.EventEmitter {
23321
23294
  for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
23322
23295
  args[_key2 - 1] = arguments[_key2];
23323
23296
  }
23297
+ // emit<E extends keyof RoomEventCallbacks>(
23298
+ // event: E,
23299
+ // ...args: Parameters<RoomEventCallbacks[E]>
23300
+ // ): boolean {
23324
23301
  // active speaker updates are too spammy
23325
23302
  if (event !== RoomEvent.ActiveSpeakersChanged) {
23326
23303
  livekitLogger.debug("room event ".concat(event), {
@@ -23340,7 +23317,7 @@ var CheckStatus;
23340
23317
  CheckStatus[CheckStatus["SUCCESS"] = 3] = "SUCCESS";
23341
23318
  CheckStatus[CheckStatus["FAILED"] = 4] = "FAILED";
23342
23319
  })(CheckStatus || (CheckStatus = {}));
23343
- class Checker extends eventsExports.EventEmitter {
23320
+ class Checker extends EventEmitter {
23344
23321
  constructor(url, token) {
23345
23322
  let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
23346
23323
  super();
@@ -23752,7 +23729,7 @@ class WebSocketCheck extends Checker {
23752
23729
  }
23753
23730
  }
23754
23731
 
23755
- class ConnectionCheck extends eventsExports.EventEmitter {
23732
+ class ConnectionCheck extends EventEmitter {
23756
23733
  constructor(url, token) {
23757
23734
  super();
23758
23735
  this.checkResults = new Map();