videomail-client 16.2.0 → 16.4.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.
package/dist/umd/index.js CHANGED
@@ -1654,7 +1654,7 @@
1654
1654
  return 0 === comparison || comparison & DOCUMENT_POSITION_CONTAINED_BY;
1655
1655
  }
1656
1656
  },
1657
- TU (__unused_rspack_module, exports1, __webpack_require__) {
1657
+ T (__unused_rspack_module, exports1, __webpack_require__) {
1658
1658
  function isArray(arg) {
1659
1659
  if (Array.isArray) return Array.isArray(arg);
1660
1660
  return '[object Array]' === objectToString(arg);
@@ -2119,7 +2119,7 @@
2119
2119
  return keys;
2120
2120
  };
2121
2121
  module1.exports = Duplex;
2122
- var util = Object.create(__webpack_require__("TU"));
2122
+ var util = Object.create(__webpack_require__("T"));
2123
2123
  util.inherits = __webpack_require__("c5");
2124
2124
  var Readable = __webpack_require__("rp");
2125
2125
  var Writable = __webpack_require__("pv");
@@ -2173,7 +2173,7 @@
2173
2173
  "use strict";
2174
2174
  module1.exports = PassThrough;
2175
2175
  var Transform = __webpack_require__("It");
2176
- var util = Object.create(__webpack_require__("TU"));
2176
+ var util = Object.create(__webpack_require__("T"));
2177
2177
  util.inherits = __webpack_require__("c5");
2178
2178
  util.inherits(PassThrough, Transform);
2179
2179
  function PassThrough(options) {
@@ -2205,7 +2205,7 @@
2205
2205
  function _isUint8Array(obj) {
2206
2206
  return Buffer.isBuffer(obj) || obj instanceof OurUint8Array;
2207
2207
  }
2208
- var util = Object.create(__webpack_require__("TU"));
2208
+ var util = Object.create(__webpack_require__("T"));
2209
2209
  util.inherits = __webpack_require__("c5");
2210
2210
  var debugUtil = __webpack_require__("AN");
2211
2211
  var debug = void 0;
@@ -2832,7 +2832,7 @@
2832
2832
  "use strict";
2833
2833
  module1.exports = Transform;
2834
2834
  var Duplex = __webpack_require__("OO");
2835
- var util = Object.create(__webpack_require__("TU"));
2835
+ var util = Object.create(__webpack_require__("T"));
2836
2836
  util.inherits = __webpack_require__("c5");
2837
2837
  util.inherits(Transform, Duplex);
2838
2838
  function afterTransform(er, data) {
@@ -2932,7 +2932,7 @@
2932
2932
  ].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : pna.nextTick;
2933
2933
  var Duplex;
2934
2934
  Writable.WritableState = WritableState;
2935
- var util = Object.create(__webpack_require__("TU"));
2935
+ var util = Object.create(__webpack_require__("T"));
2936
2936
  util.inherits = __webpack_require__("c5");
2937
2937
  var internalUtil = {
2938
2938
  deprecate: __webpack_require__("NQ")
@@ -5954,7 +5954,8 @@
5954
5954
  var percentTwenties = /%20/g;
5955
5955
  var Format = {
5956
5956
  RFC1738: 'RFC1738',
5957
- RFC3986: 'RFC3986'
5957
+ RFC3986: 'RFC3986',
5958
+ WHATWG: 'WHATWG'
5958
5959
  };
5959
5960
  module1.exports = {
5960
5961
  default: Format.RFC3986,
@@ -5964,10 +5965,14 @@
5964
5965
  },
5965
5966
  RFC3986: function(value) {
5966
5967
  return String(value);
5968
+ },
5969
+ WHATWG: function(value) {
5970
+ return replace.call(value, percentTwenties, '+');
5967
5971
  }
5968
5972
  },
5969
5973
  RFC1738: Format.RFC1738,
5970
- RFC3986: Format.RFC3986
5974
+ RFC3986: Format.RFC3986,
5975
+ WHATWG: Format.WHATWG
5971
5976
  };
5972
5977
  },
5973
5978
  b (module1, __unused_rspack_exports, __webpack_require__) {
@@ -6028,8 +6033,8 @@
6028
6033
  target: copy
6029
6034
  };
6030
6035
  }
6031
- target[keys[j]] = copies.get(value);
6032
- } else target[keys[j]] = value;
6036
+ utils.setProperty(target, keys[j], copies.get(value));
6037
+ } else utils.setProperty(target, keys[j], value);
6033
6038
  }
6034
6039
  }
6035
6040
  return result;
@@ -6076,7 +6081,7 @@
6076
6081
  }
6077
6082
  return val.split(',');
6078
6083
  }
6079
- if (options.throwOnLimitExceeded && currentArrayLength >= options.arrayLimit) throw new RangeError('Array limit exceeded. Only ' + options.arrayLimit + ' element' + (1 === options.arrayLimit ? '' : 's') + ' allowed in an array.');
6084
+ if (options.throwOnLimitExceeded && currentArrayLength >= options.arrayLimit && currentArrayLength > 0) throw new RangeError('Array limit exceeded. Only ' + options.arrayLimit + ' element' + (1 === options.arrayLimit ? '' : 's') + ' allowed in an array.');
6080
6085
  return val;
6081
6086
  };
6082
6087
  var isoSentinel = 'utf8=%26%2310003%3B';
@@ -6113,11 +6118,13 @@
6113
6118
  val = options.strictNullHandling ? null : '';
6114
6119
  } else {
6115
6120
  key = options.decoder(part.slice(0, pos), defaults.decoder, charset, 'key');
6116
- if (null !== key) val = utils.maybeMap(parseArrayValue(part.slice(pos + 1), options, isArray(obj[key]) ? obj[key].length : 0), function(encodedVal) {
6121
+ if (null !== key) val = utils.maybeMap(parseArrayValue(part.slice(pos + 1), options, isArray(obj[key]) && ('combine' === options.duplicates || isEmptyBracketKey) ? obj[key].length : 0), function(encodedVal) {
6117
6122
  return options.decoder(encodedVal, defaults.decoder, charset, 'value');
6118
6123
  });
6119
6124
  }
6120
- if (val && options.interpretNumericEntities && 'iso-8859-1' === charset) val = interpretNumericEntities(String(val));
6125
+ if (val && options.interpretNumericEntities && 'iso-8859-1' === charset) val = utils.maybeMap(val, function(value) {
6126
+ return value ? interpretNumericEntities(String(value)) : value;
6127
+ });
6121
6128
  if (isEmptyBracketKey) val = isArray(val) ? [
6122
6129
  val
6123
6130
  ] : val;
@@ -6146,7 +6153,7 @@
6146
6153
  __proto__: null
6147
6154
  } : {};
6148
6155
  var cleanRoot = '[' === root.charAt(0) && ']' === root.charAt(root.length - 1) ? root.slice(1, -1) : root;
6149
- var decodedRoot = options.decodeDotInKeys ? cleanRoot.replace(/%2E/g, '.') : cleanRoot;
6156
+ var decodedRoot = options.decodeDotInKeys ? cleanRoot.replace(/%2E/gi, '.') : cleanRoot;
6150
6157
  var index = parseInt(decodedRoot, 10);
6151
6158
  var isValidArrayIndex = !isNaN(index) && root !== decodedRoot && String(index) === decodedRoot && index >= 0 && options.parseArrays;
6152
6159
  if (options.parseArrays || '' !== decodedRoot) {
@@ -6408,7 +6415,7 @@
6408
6415
  }
6409
6416
  var encodedPrefix = String(prefix);
6410
6417
  var adjustedPrefix = commaRoundTrip && isArray(obj) && 1 === obj.length ? encodedPrefix + '[]' : encodedPrefix;
6411
- if (allowEmptyArrays && isArray(obj) && 0 === obj.length && 0 === Object.keys(obj).length) return adjustedPrefix + '[]';
6418
+ if (allowEmptyArrays && isArray(obj) && 0 === obj.length && 0 === Object.keys(obj).length) return formatter(encoder && !encodeValuesOnly ? encoder(adjustedPrefix, defaults.encoder, charset, 'key', format) : adjustedPrefix) + '[]';
6412
6419
  for(var j = 0; j < objKeys.length; ++j){
6413
6420
  var key = objKeys[j];
6414
6421
  var value = 'object' == typeof key && key && void 0 !== key.value ? key.value : obj[key];
@@ -6474,7 +6481,7 @@
6474
6481
  filter = options.filter;
6475
6482
  obj = filter('', obj);
6476
6483
  } else if (isArray(options.filter)) {
6477
- filter = options.filter;
6484
+ filter = options.filter.slice();
6478
6485
  objKeys = filter;
6479
6486
  }
6480
6487
  var keys = [];
@@ -6490,7 +6497,7 @@
6490
6497
  var value = obj[key];
6491
6498
  if (!options.skipNulls || null !== value) {
6492
6499
  var encodedKey = options.encodeDotInKeys ? String(key).replace(/\./g, '%2E') : String(key);
6493
- pushToArray(keys, stringify(value, encodedKey, generateArrayPrefix, commaRoundTrip, options.allowEmptyArrays, options.strictNullHandling, options.skipNulls, options.encodeDotInKeys, options.encode ? options.encoder : null, options.filter, options.sort, options.allowDots, options.serializeDate, options.format, options.formatter, options.encodeValuesOnly, options.charset, sideChannel, options.depth, 0));
6500
+ pushToArray(keys, stringify(value, encodedKey, generateArrayPrefix, commaRoundTrip, options.allowEmptyArrays, options.strictNullHandling, options.skipNulls, options.encodeDotInKeys, options.encode ? options.encoder : null, filter, options.sort, options.allowDots, options.serializeDate, options.format, options.formatter, options.encodeValuesOnly, options.charset, sideChannel, options.depth, 0));
6494
6501
  }
6495
6502
  }
6496
6503
  }
@@ -6739,7 +6746,7 @@
6739
6746
  var arr = [];
6740
6747
  for(var i = 0; i < segment.length; ++i){
6741
6748
  var c = segment.charCodeAt(i);
6742
- if (0x2D === c || 0x2E === c || 0x5F === c || 0x7E === c || c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x5A || c >= 0x61 && c <= 0x7A || format === formats.RFC1738 && (0x28 === c || 0x29 === c)) {
6749
+ if (0x2D === c || 0x2E === c || 0x5F === c || 0x7E === c && format !== formats.WHATWG || c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x5A || c >= 0x61 && c <= 0x7A || format === formats.RFC1738 && (0x28 === c || 0x29 === c) || format === formats.WHATWG && 0x2A === c) {
6743
6750
  arr[arr.length] = segment.charAt(i);
6744
6751
  continue;
6745
6752
  }
@@ -6755,9 +6762,12 @@
6755
6762
  arr[arr.length] = hexTable[0xE0 | c >> 12] + hexTable[0x80 | c >> 6 & 0x3F] + hexTable[0x80 | 0x3F & c];
6756
6763
  continue;
6757
6764
  }
6758
- i += 1;
6759
- c = 0x10000 + ((0x3FF & c) << 10 | 0x3FF & segment.charCodeAt(i));
6760
- arr[arr.length] = hexTable[0xF0 | c >> 18] + hexTable[0x80 | c >> 12 & 0x3F] + hexTable[0x80 | c >> 6 & 0x3F] + hexTable[0x80 | 0x3F & c];
6765
+ var next = segment.charCodeAt(i + 1);
6766
+ if (c <= 0xDBFF && next >= 0xDC00 && next <= 0xDFFF) {
6767
+ i += 1;
6768
+ c = 0x10000 + ((0x3FF & c) << 10 | 0x3FF & next);
6769
+ arr[arr.length] = hexTable[0xF0 | c >> 18] + hexTable[0x80 | c >> 12 & 0x3F] + hexTable[0x80 | c >> 6 & 0x3F] + hexTable[0x80 | 0x3F & c];
6770
+ } else arr[arr.length] = '%EF%BF%BD';
6761
6771
  }
6762
6772
  out += arr.join('');
6763
6773
  }
@@ -6843,6 +6853,7 @@
6843
6853
  markOverflow: markOverflow,
6844
6854
  maybeMap: maybeMap,
6845
6855
  merge: merge,
6856
+ setProperty: setProperty,
6846
6857
  toCoercible: toCoercible
6847
6858
  };
6848
6859
  },
@@ -7195,7 +7206,7 @@
7195
7206
  const qs = __webpack_require__("b");
7196
7207
  const RequestBase = __webpack_require__("d");
7197
7208
  const { isObject, mixin, hasOwn, isSafeKey } = __webpack_require__("Dp");
7198
- const ResponseBase = __webpack_require__("e");
7209
+ const ResponseBase = __webpack_require__("es");
7199
7210
  const Agent = __webpack_require__("pf");
7200
7211
  function noop() {}
7201
7212
  module1.exports = function(method, url) {
@@ -7909,7 +7920,7 @@
7909
7920
  }, this._responseTimeout);
7910
7921
  };
7911
7922
  },
7912
- e (module1, __unused_rspack_exports, __webpack_require__) {
7923
+ es (module1, __unused_rspack_exports, __webpack_require__) {
7913
7924
  "use strict";
7914
7925
  const utils = __webpack_require__("Dp");
7915
7926
  module1.exports = ResponseBase;
@@ -8733,7 +8744,7 @@
8733
8744
  return keys;
8734
8745
  };
8735
8746
  module1.exports = Duplex;
8736
- var util = Object.create(__webpack_require__("TU"));
8747
+ var util = Object.create(__webpack_require__("T"));
8737
8748
  util.inherits = __webpack_require__("c5");
8738
8749
  var Readable = __webpack_require__("w");
8739
8750
  var Writable = __webpack_require__("S5");
@@ -8787,7 +8798,7 @@
8787
8798
  "use strict";
8788
8799
  module1.exports = PassThrough;
8789
8800
  var Transform = __webpack_require__("Ge");
8790
- var util = Object.create(__webpack_require__("TU"));
8801
+ var util = Object.create(__webpack_require__("T"));
8791
8802
  util.inherits = __webpack_require__("c5");
8792
8803
  util.inherits(PassThrough, Transform);
8793
8804
  function PassThrough(options) {
@@ -8819,7 +8830,7 @@
8819
8830
  function _isUint8Array(obj) {
8820
8831
  return Buffer.isBuffer(obj) || obj instanceof OurUint8Array;
8821
8832
  }
8822
- var util = Object.create(__webpack_require__("TU"));
8833
+ var util = Object.create(__webpack_require__("T"));
8823
8834
  util.inherits = __webpack_require__("c5");
8824
8835
  var debugUtil = __webpack_require__("eD");
8825
8836
  var debug = void 0;
@@ -9446,7 +9457,7 @@
9446
9457
  "use strict";
9447
9458
  module1.exports = Transform;
9448
9459
  var Duplex = __webpack_require__("S7");
9449
- var util = Object.create(__webpack_require__("TU"));
9460
+ var util = Object.create(__webpack_require__("T"));
9450
9461
  util.inherits = __webpack_require__("c5");
9451
9462
  util.inherits(Transform, Duplex);
9452
9463
  function afterTransform(er, data) {
@@ -9546,7 +9557,7 @@
9546
9557
  ].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : pna.nextTick;
9547
9558
  var Duplex;
9548
9559
  Writable.WritableState = WritableState;
9549
- var util = Object.create(__webpack_require__("TU"));
9560
+ var util = Object.create(__webpack_require__("T"));
9550
9561
  util.inherits = __webpack_require__("c5");
9551
9562
  var internalUtil = {
9552
9563
  deprecate: __webpack_require__("NQ")
@@ -11121,7 +11132,7 @@
11121
11132
  var client = __webpack_require__("Q");
11122
11133
  var client_default = /*#__PURE__*/ __webpack_require__.n(client);
11123
11134
  var package_namespaceObject = {
11124
- rE: "16.2.0"
11135
+ rE: "16.4.0"
11125
11136
  };
11126
11137
  function isAudioEnabled(options) {
11127
11138
  return Boolean(options.audio.enabled);
@@ -20689,51 +20700,172 @@
20689
20700
  const esm = esm_src;
20690
20701
  var is_power_of_two = __webpack_require__("dZ");
20691
20702
  var is_power_of_two_default = /*#__PURE__*/ __webpack_require__.n(is_power_of_two);
20692
- const CHANNELS = 1;
20693
- function getAudioContextClass() {
20694
- return window.AudioContext;
20703
+ const AUDIO_RECORDER_PROCESSOR_NAME = "videomail-pcm-recorder";
20704
+ function registerAudioRecorderProcessor(name, Processor, register) {
20705
+ class PcmRecorderProcessor extends Processor {
20706
+ constructor(options){
20707
+ super();
20708
+ this.samples = new Float32Array(options.processorOptions.bufferSize);
20709
+ this.offset = 0;
20710
+ this.recordingId = 0;
20711
+ this.port.onmessage = (event)=>{
20712
+ const recordingId = event.data;
20713
+ if ("number" != typeof recordingId) return;
20714
+ if (!Number.isSafeInteger(recordingId) || recordingId < -1) return;
20715
+ this.recordingId = recordingId;
20716
+ this.offset = 0;
20717
+ };
20718
+ }
20719
+ process(inputs) {
20720
+ if (this.recordingId < 0) return false;
20721
+ const channel = inputs[0]?.[0];
20722
+ if (!channel || 0 === this.recordingId) return true;
20723
+ let inputOffset = 0;
20724
+ while(inputOffset < channel.length){
20725
+ const count = Math.min(this.samples.length - this.offset, channel.length - inputOffset);
20726
+ this.samples.set(channel.subarray(inputOffset, inputOffset + count), this.offset);
20727
+ this.offset += count;
20728
+ inputOffset += count;
20729
+ if (this.offset === this.samples.length) {
20730
+ const samples = this.samples;
20731
+ this.port.postMessage({
20732
+ recordingId: this.recordingId,
20733
+ samples
20734
+ }, [
20735
+ samples.buffer
20736
+ ]);
20737
+ this.samples = new Float32Array(this.offset);
20738
+ this.offset = 0;
20739
+ }
20740
+ }
20741
+ return true;
20742
+ }
20743
+ }
20744
+ register(name, PcmRecorderProcessor);
20695
20745
  }
20696
- class AudioRecorder {
20697
- scriptProcessor;
20746
+ const CHANNELS = 1;
20747
+ const DEFAULT_BUFFER_SIZE = 2048;
20748
+ const MIN_BUFFER_SIZE = 256;
20749
+ const MAX_BUFFER_SIZE = 16384;
20750
+ class AudioRecorder extends util_Despot {
20751
+ userMedia;
20752
+ worklet;
20698
20753
  audioInput;
20699
20754
  volume;
20700
20755
  vcAudioContext;
20701
- userMedia;
20702
- options;
20756
+ workletReady;
20757
+ moduleUrl;
20758
+ audioCallback;
20759
+ initializationId = 0;
20760
+ recordingSequence = 0;
20761
+ recordingId = 0;
20703
20762
  constructor(userMedia, options){
20704
- this.options = options;
20763
+ super("AudioRecorder", options);
20705
20764
  this.userMedia = userMedia;
20706
20765
  }
20707
- hasAudioContext() {
20708
- return Boolean(getAudioContextClass()) && Boolean(this.getAudioContext());
20709
- }
20710
20766
  getAudioContext() {
20711
- if (!this.vcAudioContext) {
20712
- const AudioContext = getAudioContextClass();
20713
- this.vcAudioContext = new AudioContext();
20714
- }
20767
+ if (!this.vcAudioContext) this.vcAudioContext = new window.AudioContext();
20715
20768
  return this.vcAudioContext;
20716
20769
  }
20717
- onAudioProcess(e, cb) {
20770
+ getBufferSize() {
20771
+ const configuredSize = this.options.audio.bufferSize;
20772
+ const bufferSize = "auto" === configuredSize ? DEFAULT_BUFFER_SIZE : configuredSize;
20773
+ if (void 0 === bufferSize) throw error_createError({
20774
+ message: "Audio buffer size is required.",
20775
+ options: this.options
20776
+ });
20777
+ const validBufferSize = Number.isInteger(bufferSize) && bufferSize >= MIN_BUFFER_SIZE && bufferSize <= MAX_BUFFER_SIZE && is_power_of_two_default()(bufferSize);
20778
+ if (!validBufferSize) throw error_createError({
20779
+ message: `Audio buffer size must be a power of two between ${MIN_BUFFER_SIZE} and ${MAX_BUFFER_SIZE}. The current buffer size is ${bufferSize}.`,
20780
+ options: this.options
20781
+ });
20782
+ return bufferSize;
20783
+ }
20784
+ validateVolume() {
20785
+ const { volume } = this.options.audio;
20786
+ const validVolume = Number.isFinite(volume) && volume >= 0 && volume <= 1;
20787
+ if (!validVolume) throw error_createError({
20788
+ message: `Audio volume must be between zero and one. The current volume is ${volume}.`,
20789
+ options: this.options
20790
+ });
20791
+ }
20792
+ revokeModuleUrl() {
20793
+ if (this.moduleUrl) {
20794
+ URL.revokeObjectURL(this.moduleUrl);
20795
+ this.moduleUrl = void 0;
20796
+ }
20797
+ }
20798
+ async loadWorklet(context) {
20799
+ const source = `(${registerAudioRecorderProcessor.toString()})(${JSON.stringify(AUDIO_RECORDER_PROCESSOR_NAME)}, AudioWorkletProcessor, registerProcessor);`;
20800
+ const moduleUrl = URL.createObjectURL(new Blob([
20801
+ source
20802
+ ], {
20803
+ type: "text/javascript"
20804
+ }));
20805
+ this.moduleUrl = moduleUrl;
20806
+ try {
20807
+ await context.audioWorklet.addModule(moduleUrl);
20808
+ } finally{
20809
+ if (this.moduleUrl === moduleUrl) this.revokeModuleUrl();
20810
+ }
20811
+ }
20812
+ onAudioProcess(event) {
20813
+ const callback = this.audioCallback;
20814
+ if (!callback) return;
20718
20815
  if (!this.userMedia.isRecording() || this.userMedia.isPaused()) return;
20719
- const float32Array = e.inputBuffer.getChannelData(0);
20720
- cb(new esm(float32Array));
20816
+ const message = event.data;
20817
+ if ("object" != typeof message || null === message) return;
20818
+ if (!("recordingId" in message) || message.recordingId !== this.recordingId) return;
20819
+ if (!("samples" in message) || !(message.samples instanceof Float32Array)) return;
20820
+ if (0 === message.samples.length) return;
20821
+ callback(new esm(message.samples));
20721
20822
  }
20722
20823
  disconnect() {
20723
- if (this.scriptProcessor) {
20724
- this.scriptProcessor.onaudioprocess = null;
20725
- this.scriptProcessor.disconnect();
20824
+ if (this.worklet) {
20825
+ this.worklet.port.onmessage = null;
20826
+ this.worklet.onprocessorerror = null;
20827
+ this.worklet.port.postMessage(-1);
20828
+ this.worklet.port.close();
20829
+ this.worklet.disconnect();
20830
+ this.worklet = void 0;
20726
20831
  }
20727
20832
  this.audioInput?.disconnect();
20728
20833
  this.volume?.disconnect();
20834
+ this.audioInput = void 0;
20835
+ this.volume = void 0;
20836
+ this.audioCallback = void 0;
20837
+ this.recordingId = 0;
20729
20838
  }
20730
- init(localMediaStream) {
20839
+ async init(localMediaStream) {
20731
20840
  this.options.logger.debug("AudioRecorder: init()");
20841
+ const initializationId = ++this.initializationId;
20732
20842
  this.disconnect();
20733
- const volume = this.getAudioContext().createGain();
20734
- this.volume = volume;
20843
+ const bufferSize = this.getBufferSize();
20844
+ this.validateVolume();
20845
+ if ("function" != typeof window.AudioContext) throw error_createError({
20846
+ message: "Audio recording requires Web Audio support.",
20847
+ options: this.options
20848
+ });
20849
+ const context = this.getAudioContext();
20850
+ if (void 0 === context.audioWorklet || "function" != typeof window.AudioWorkletNode) throw error_createError({
20851
+ message: "Audio recording requires AudioWorklet support in a secure context.",
20852
+ options: this.options
20853
+ });
20854
+ const workletReady = this.workletReady ??= this.loadWorklet(context);
20855
+ try {
20856
+ await workletReady;
20857
+ } catch (exc) {
20858
+ if (this.workletReady === workletReady) this.workletReady = void 0;
20859
+ if (initializationId !== this.initializationId) return;
20860
+ throw error_createError({
20861
+ message: "Unable to load the audio recorder worklet. Check AudioWorklet and Content Security Policy support for blob: scripts.",
20862
+ cause: exc,
20863
+ options: this.options
20864
+ });
20865
+ }
20866
+ if (initializationId !== this.initializationId) return;
20735
20867
  try {
20736
- this.audioInput = this.getAudioContext().createMediaStreamSource(localMediaStream);
20868
+ this.audioInput = context.createMediaStreamSource(localMediaStream);
20737
20869
  } catch (exc) {
20738
20870
  throw error_createError({
20739
20871
  message: "Webcam has no audio",
@@ -20741,38 +20873,69 @@
20741
20873
  options: this.options
20742
20874
  });
20743
20875
  }
20744
- let { bufferSize } = this.options.audio;
20745
- if ("auto" === bufferSize) bufferSize = util_getBrowser(this.options).isFirefox() ? 512 : 2048;
20746
- if (void 0 === bufferSize || !is_power_of_two_default()(bufferSize)) throw error_createError({
20747
- message: `Audio buffer size must be a power of two. The current buffer size is ${bufferSize}.`,
20748
- options: this.options
20749
- });
20750
- if (!Number.isFinite(this.options.audio.volume) || this.options.audio.volume < 0 || this.options.audio.volume > 1) throw error_createError({
20751
- message: `Audio volume must be between zero and one. The current volume is ${this.options.audio.volume}.`,
20752
- options: this.options
20753
- });
20754
- volume.gain.value = this.options.audio.volume;
20755
- this.scriptProcessor = this.getAudioContext().createScriptProcessor(bufferSize, CHANNELS, CHANNELS);
20756
- this.audioInput.connect(volume);
20757
- volume.connect(this.scriptProcessor);
20758
- this.scriptProcessor.connect(this.getAudioContext().destination);
20876
+ try {
20877
+ this.volume = context.createGain();
20878
+ this.volume.gain.value = this.options.audio.volume;
20879
+ this.worklet = new window.AudioWorkletNode(context, AUDIO_RECORDER_PROCESSOR_NAME, {
20880
+ channelCount: CHANNELS,
20881
+ channelCountMode: "explicit",
20882
+ outputChannelCount: [
20883
+ CHANNELS
20884
+ ],
20885
+ processorOptions: {
20886
+ bufferSize
20887
+ }
20888
+ });
20889
+ this.worklet.port.onmessage = (event)=>{
20890
+ this.onAudioProcess(event);
20891
+ };
20892
+ this.worklet.onprocessorerror = ()=>{
20893
+ this.stop();
20894
+ this.emit("ERROR", {
20895
+ err: error_createError({
20896
+ message: "Audio recording processor failed.",
20897
+ options: this.options
20898
+ })
20899
+ });
20900
+ };
20901
+ this.audioInput.connect(this.volume);
20902
+ this.volume.connect(this.worklet);
20903
+ this.worklet.connect(context.destination);
20904
+ } catch (exc) {
20905
+ this.disconnect();
20906
+ throw error_createError({
20907
+ message: "Failed to connect the audio recorder.",
20908
+ exc,
20909
+ options: this.options
20910
+ });
20911
+ }
20759
20912
  }
20760
20913
  record(cb) {
20761
20914
  this.options.logger.debug("AudioRecorder: record()");
20762
- if (this.scriptProcessor) this.scriptProcessor.onaudioprocess = (e)=>{
20763
- this.onAudioProcess(e, cb);
20764
- };
20915
+ this.audioCallback = cb;
20916
+ this.updateRecordingState();
20917
+ }
20918
+ updateRecordingState() {
20919
+ if (!this.worklet) return;
20920
+ const shouldRecord = Boolean(this.audioCallback) && this.userMedia.isRecording() && !this.userMedia.isPaused();
20921
+ this.recordingId = shouldRecord ? ++this.recordingSequence : 0;
20922
+ this.worklet.port.postMessage(this.recordingId);
20765
20923
  }
20766
20924
  async resume() {
20767
- const context = this.getAudioContext();
20925
+ const context = this.vcAudioContext;
20926
+ if (!context) return;
20768
20927
  if ("running" !== context.state) await context.resume();
20769
20928
  }
20770
20929
  stop() {
20771
20930
  this.options.logger.debug("AudioRecorder: stop()");
20931
+ this.initializationId++;
20772
20932
  this.disconnect();
20773
- if (this.hasAudioContext()) this.getAudioContext().close().then(()=>{
20933
+ this.revokeModuleUrl();
20934
+ const context = this.vcAudioContext;
20935
+ this.vcAudioContext = void 0;
20936
+ this.workletReady = void 0;
20937
+ if (context && "closed" !== context.state) context.close().then(()=>{
20774
20938
  this.options.logger.debug("AudioRecorder: audio context is closed");
20775
- this.vcAudioContext = void 0;
20776
20939
  }).catch((err)=>{
20777
20940
  if (err instanceof Error) return void this.options.logger.error(error_createError({
20778
20941
  err,
@@ -20782,7 +20945,7 @@
20782
20945
  });
20783
20946
  }
20784
20947
  getSampleRate() {
20785
- if (this.hasAudioContext()) return this.getAudioContext().sampleRate;
20948
+ if ("function" == typeof window.AudioContext) return this.getAudioContext().sampleRate;
20786
20949
  return -1;
20787
20950
  }
20788
20951
  }
@@ -20947,27 +21110,33 @@
20947
21110
  const fireCallbacks = ()=>{
20948
21111
  const readyState = this.rawVisualUserMedia?.readyState;
20949
21112
  this.options.logger.debug(`UserMedia: fireCallbacks(readyState=${readyState}, onPlayReached=${this.onPlayReached}, onLoadedMetaDataReached=${this.onLoadedMetaDataReached})`);
20950
- if (this.onPlayReached && this.onLoadedMetaDataReached) if (this.audioRecorder) try {
20951
- this.audioRecorder.init(localMediaStream);
20952
- const onAudioReady = ()=>{
20953
- if (initializationId !== this.initializationId || this.currentVisualStream !== localMediaStream) return;
20954
- if (this.recording) this.audioRecord(audioCallback);
20955
- else this.on("SENDING_FIRST_FRAME", ()=>{
20956
- this.audioRecord(audioCallback);
20957
- });
20958
- this.clearInitializationListeners?.();
20959
- videoCallback();
21113
+ if (this.onPlayReached && this.onLoadedMetaDataReached) if (this.audioRecorder) {
21114
+ const initializeAudio = async (audioRecorder)=>{
21115
+ try {
21116
+ await audioRecorder.init(localMediaStream);
21117
+ if (initializationId !== this.initializationId || this.currentVisualStream !== localMediaStream) return;
21118
+ const onAudioReady = ()=>{
21119
+ if (initializationId !== this.initializationId || this.currentVisualStream !== localMediaStream) return;
21120
+ if (this.recording) this.audioRecord(audioCallback);
21121
+ else this.on("SENDING_FIRST_FRAME", ()=>{
21122
+ this.audioRecord(audioCallback);
21123
+ });
21124
+ this.clearInitializationListeners?.();
21125
+ videoCallback();
21126
+ };
21127
+ if (params?.recovering) await audioRecorder.resume();
21128
+ onAudioReady();
21129
+ } catch (exc) {
21130
+ if (initializationId !== this.initializationId) return;
21131
+ unloadAllEventListeners();
21132
+ this.stop(void 0, {
21133
+ preserveRecordingState: Boolean(params?.recovering)
21134
+ });
21135
+ endedEarlyCallback(exc);
21136
+ }
20960
21137
  };
20961
- if (params?.recovering) this.audioRecorder.resume().then(onAudioReady).catch(endedEarlyCallback);
20962
- else onAudioReady();
20963
- } catch (exc) {
20964
- unloadAllEventListeners();
20965
- this.stop(void 0, {
20966
- preserveRecordingState: Boolean(params?.recovering)
20967
- });
20968
- endedEarlyCallback(exc);
20969
- }
20970
- else {
21138
+ initializeAudio(this.audioRecorder);
21139
+ } else {
20971
21140
  this.clearInitializationListeners?.();
20972
21141
  videoCallback();
20973
21142
  }
@@ -21124,15 +21293,18 @@
21124
21293
  }
21125
21294
  pause() {
21126
21295
  this.paused = true;
21296
+ this.audioRecorder?.updateRecordingState();
21127
21297
  }
21128
21298
  isPaused() {
21129
21299
  return this.paused;
21130
21300
  }
21131
21301
  resume() {
21132
21302
  this.paused = false;
21303
+ this.audioRecorder?.updateRecordingState();
21133
21304
  }
21134
21305
  record() {
21135
21306
  this.recording = true;
21307
+ this.audioRecorder?.updateRecordingState();
21136
21308
  }
21137
21309
  isRecording() {
21138
21310
  return this.recording;