videomail-client 16.0.3 → 16.1.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.
@@ -11115,7 +11115,7 @@ var __webpack_exports__ = {};
11115
11115
  var client = __webpack_require__("Q");
11116
11116
  var client_default = /*#__PURE__*/ __webpack_require__.n(client);
11117
11117
  var package_namespaceObject = {
11118
- rE: "16.0.3"
11118
+ rE: "16.1.0"
11119
11119
  };
11120
11120
  function isAudioEnabled(options) {
11121
11121
  return Boolean(options.audio.enabled);
@@ -18844,10 +18844,15 @@ var __webpack_exports__ = {};
18844
18844
  var _this_facingMode;
18845
18845
  null == (_this_facingMode = this.facingMode) || _this_facingMode.show();
18846
18846
  });
18847
+ this.on("CAMERA_RECOVERING", ()=>{
18848
+ var _this_facingMode;
18849
+ null == (_this_facingMode = this.facingMode) || _this_facingMode.hide();
18850
+ });
18847
18851
  this.on("RECORDING", ()=>{
18848
18852
  this.startRecording();
18849
18853
  });
18850
18854
  this.on("RESUMING", ()=>{
18855
+ this.hidePause();
18851
18856
  this.resumeRecording();
18852
18857
  });
18853
18858
  this.on("STOPPING", ()=>{
@@ -19491,6 +19496,32 @@ var __webpack_exports__ = {};
19491
19496
  const esm = esm_src;
19492
19497
  var is_power_of_two = __webpack_require__("dZ");
19493
19498
  var is_power_of_two_default = /*#__PURE__*/ __webpack_require__.n(is_power_of_two);
19499
+ function AudioRecorder_asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
19500
+ try {
19501
+ var info = gen[key](arg);
19502
+ var value = info.value;
19503
+ } catch (error) {
19504
+ reject(error);
19505
+ return;
19506
+ }
19507
+ if (info.done) resolve(value);
19508
+ else Promise.resolve(value).then(_next, _throw);
19509
+ }
19510
+ function AudioRecorder_async_to_generator(fn) {
19511
+ return function() {
19512
+ var self1 = this, args = arguments;
19513
+ return new Promise(function(resolve, reject) {
19514
+ var gen = fn.apply(self1, args);
19515
+ function _next(value) {
19516
+ AudioRecorder_asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
19517
+ }
19518
+ function _throw(err) {
19519
+ AudioRecorder_asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
19520
+ }
19521
+ _next(void 0);
19522
+ });
19523
+ };
19524
+ }
19494
19525
  function AudioRecorder_define_property(obj, key, value) {
19495
19526
  if (key in obj) Object.defineProperty(obj, key, {
19496
19527
  value: value,
@@ -19521,9 +19552,20 @@ var __webpack_exports__ = {};
19521
19552
  const float32Array = e.inputBuffer.getChannelData(0);
19522
19553
  cb(new esm(float32Array));
19523
19554
  }
19555
+ disconnect() {
19556
+ var _this_audioInput, _this_volume;
19557
+ if (this.scriptProcessor) {
19558
+ this.scriptProcessor.onaudioprocess = null;
19559
+ this.scriptProcessor.disconnect();
19560
+ }
19561
+ null == (_this_audioInput = this.audioInput) || _this_audioInput.disconnect();
19562
+ null == (_this_volume = this.volume) || _this_volume.disconnect();
19563
+ }
19524
19564
  init(localMediaStream) {
19525
19565
  this.options.logger.debug("AudioRecorder: init()");
19566
+ this.disconnect();
19526
19567
  const volume = this.getAudioContext().createGain();
19568
+ this.volume = volume;
19527
19569
  try {
19528
19570
  this.audioInput = this.getAudioContext().createMediaStreamSource(localMediaStream);
19529
19571
  } catch (exc) {
@@ -19555,10 +19597,15 @@ var __webpack_exports__ = {};
19555
19597
  this.onAudioProcess(e, cb);
19556
19598
  };
19557
19599
  }
19600
+ resume() {
19601
+ return AudioRecorder_async_to_generator(function*() {
19602
+ const context = this.getAudioContext();
19603
+ if ("running" !== context.state) yield context.resume();
19604
+ }).call(this);
19605
+ }
19558
19606
  stop() {
19559
19607
  this.options.logger.debug("AudioRecorder: stop()");
19560
- if (this.scriptProcessor) this.scriptProcessor.onaudioprocess = null;
19561
- if (this.audioInput) this.audioInput.disconnect();
19608
+ this.disconnect();
19562
19609
  if (this.hasAudioContext()) this.getAudioContext().close().then(()=>{
19563
19610
  this.options.logger.debug("AudioRecorder: audio context is closed");
19564
19611
  this.vcAudioContext = void 0;
@@ -19577,6 +19624,7 @@ var __webpack_exports__ = {};
19577
19624
  constructor(userMedia, options){
19578
19625
  AudioRecorder_define_property(this, "scriptProcessor", void 0);
19579
19626
  AudioRecorder_define_property(this, "audioInput", void 0);
19627
+ AudioRecorder_define_property(this, "volume", void 0);
19580
19628
  AudioRecorder_define_property(this, "vcAudioContext", void 0);
19581
19629
  AudioRecorder_define_property(this, "userMedia", void 0);
19582
19630
  AudioRecorder_define_property(this, "options", void 0);
@@ -19600,6 +19648,32 @@ var __webpack_exports__ = {};
19600
19648
  return isVirtual;
19601
19649
  }
19602
19650
  const util_isVirtualCamera = isVirtualCamera;
19651
+ function userMedia_asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
19652
+ try {
19653
+ var info = gen[key](arg);
19654
+ var value = info.value;
19655
+ } catch (error) {
19656
+ reject(error);
19657
+ return;
19658
+ }
19659
+ if (info.done) resolve(value);
19660
+ else Promise.resolve(value).then(_next, _throw);
19661
+ }
19662
+ function userMedia_async_to_generator(fn) {
19663
+ return function() {
19664
+ var self1 = this, args = arguments;
19665
+ return new Promise(function(resolve, reject) {
19666
+ var gen = fn.apply(self1, args);
19667
+ function _next(value) {
19668
+ userMedia_asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
19669
+ }
19670
+ function _throw(err) {
19671
+ userMedia_asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
19672
+ }
19673
+ _next(void 0);
19674
+ });
19675
+ };
19676
+ }
19603
19677
  function userMedia_define_property(obj, key, value) {
19604
19678
  if (key in obj) Object.defineProperty(obj, key, {
19605
19679
  value: value,
@@ -19636,6 +19710,20 @@ var __webpack_exports__ = {};
19636
19710
  this.currentVisualStream = void 0;
19637
19711
  }
19638
19712
  }
19713
+ restorePlayback() {
19714
+ return userMedia_async_to_generator(function*() {
19715
+ var _this_audioRecorder;
19716
+ if (!this.rawVisualUserMedia) throw new Error("No camera preview is available.");
19717
+ yield this.rawVisualUserMedia.play();
19718
+ yield null == (_this_audioRecorder = this.audioRecorder) ? void 0 : _this_audioRecorder.resume();
19719
+ }).call(this);
19720
+ }
19721
+ hasLiveStream() {
19722
+ var _this_currentVisualStream, _this_currentVisualStream1, _this_currentVisualStream2;
19723
+ const videoReady = null == (_this_currentVisualStream = this.currentVisualStream) ? void 0 : _this_currentVisualStream.getVideoTracks().some((track)=>"live" === track.readyState && track.enabled && !track.muted);
19724
+ const audioReady = !isAudioEnabled(this.options) || (null == (_this_currentVisualStream1 = this.currentVisualStream) ? void 0 : _this_currentVisualStream1.getAudioTracks().some((track)=>"live" === track.readyState && track.enabled && !track.muted));
19725
+ return Boolean((null == (_this_currentVisualStream2 = this.currentVisualStream) ? void 0 : _this_currentVisualStream2.active) && videoReady && audioReady);
19726
+ }
19639
19727
  hasEnded() {
19640
19728
  var _this_rawVisualUserMedia, _this_currentVisualStream;
19641
19729
  if (null == (_this_rawVisualUserMedia = this.rawVisualUserMedia) ? void 0 : _this_rawVisualUserMedia.ended) return this.rawVisualUserMedia.ended;
@@ -19650,8 +19738,9 @@ var __webpack_exports__ = {};
19650
19738
  this.options.logger.debug(`UserMedia: ... ${EVENT_ASCII} event ${eventType}: ${string_pretty(params)}`);
19651
19739
  }
19652
19740
  unloadRemainingEventListeners() {
19653
- var _this_rawVisualUserMedia;
19741
+ var _this_clearInitializationListeners, _this, _this_rawVisualUserMedia;
19654
19742
  this.options.logger.debug("UserMedia: unloadRemainingEventListeners()");
19743
+ null == (_this_clearInitializationListeners = (_this = this).clearInitializationListeners) || _this_clearInitializationListeners.call(_this);
19655
19744
  mediaEvents.forEach((eventName)=>{
19656
19745
  var _this_rawVisualUserMedia;
19657
19746
  null == (_this_rawVisualUserMedia = this.rawVisualUserMedia) || _this_rawVisualUserMedia.removeEventListener(eventName, this.outputEvent);
@@ -19663,11 +19752,14 @@ var __webpack_exports__ = {};
19663
19752
  this.removeListener("SENDING_FIRST_FRAME");
19664
19753
  null == (_this_audioRecorder = this.audioRecorder) || _this_audioRecorder.record(audioCallback);
19665
19754
  }
19666
- init(localMediaStream, videoCallback, audioCallback, endedEarlyCallback, switchingFacingMode) {
19755
+ init(localMediaStream, videoCallback, audioCallback, endedEarlyCallback, params) {
19756
+ var _this_clearInitializationListeners, _this;
19757
+ null == (_this_clearInitializationListeners = (_this = this).clearInitializationListeners) || _this_clearInitializationListeners.call(_this);
19667
19758
  this.stop(localMediaStream, {
19668
19759
  aboutToInitialize: true,
19669
- switchingFacingMode
19760
+ preserveRecordingState: Boolean((null == params ? void 0 : params.switchingFacingMode) || (null == params ? void 0 : params.recovering))
19670
19761
  });
19762
+ const initializationId = ++this.initializationId;
19671
19763
  this.onPlayReached = false;
19672
19764
  this.onLoadedMetaDataReached = false;
19673
19765
  this.playingPromiseReached = false;
@@ -19681,6 +19773,12 @@ var __webpack_exports__ = {};
19681
19773
  null == (_this_rawVisualUserMedia = this.rawVisualUserMedia) || _this_rawVisualUserMedia.removeEventListener("play", onPlay);
19682
19774
  null == (_this_rawVisualUserMedia1 = this.rawVisualUserMedia) || _this_rawVisualUserMedia1.removeEventListener("loadedmetadata", onLoadedMetaData);
19683
19775
  };
19776
+ this.clearInitializationListeners = ()=>{
19777
+ var _this_rawVisualUserMedia, _this_rawVisualUserMedia1;
19778
+ null == (_this_rawVisualUserMedia = this.rawVisualUserMedia) || _this_rawVisualUserMedia.removeEventListener("play", onPlay);
19779
+ null == (_this_rawVisualUserMedia1 = this.rawVisualUserMedia) || _this_rawVisualUserMedia1.removeEventListener("loadedmetadata", onLoadedMetaData);
19780
+ this.clearInitializationListeners = void 0;
19781
+ };
19684
19782
  const play = ()=>{
19685
19783
  try {
19686
19784
  var _this_rawVisualUserMedia, _this_rawVisualUserMedia1;
@@ -19688,12 +19786,14 @@ var __webpack_exports__ = {};
19688
19786
  if (null == (_this_rawVisualUserMedia1 = this.rawVisualUserMedia) ? void 0 : _this_rawVisualUserMedia1.paused) {
19689
19787
  this.options.logger.debug(`UserMedia: play(): media.readyState=${this.rawVisualUserMedia.readyState}, media.paused=${this.rawVisualUserMedia.paused}, media.ended=${this.rawVisualUserMedia.ended}, media.played=${string_pretty(this.rawVisualUserMedia.played)}`);
19690
19788
  this.rawVisualUserMedia.play().then(()=>{
19789
+ if (initializationId !== this.initializationId) return;
19691
19790
  if (!this.playingPromiseReached) {
19692
19791
  this.options.logger.debug("UserMedia: play promise successful. Playing now.");
19693
19792
  this.playingPromiseReached = true;
19694
19793
  }
19695
19794
  }).catch((exc)=>{
19696
- if (exc instanceof Error) this.options.logger.warn(`Caught pending user media promise exception: ${exc.toString()}`);
19795
+ if (initializationId !== this.initializationId) return;
19796
+ if (exc instanceof Error && !(null == params ? void 0 : params.recovering)) this.options.logger.warn(`Caught pending user media promise exception: ${exc.toString()}`);
19697
19797
  else {
19698
19798
  unloadAllEventListeners();
19699
19799
  endedEarlyCallback(error_createError({
@@ -19715,16 +19815,30 @@ var __webpack_exports__ = {};
19715
19815
  this.options.logger.debug(`UserMedia: fireCallbacks(readyState=${readyState}, onPlayReached=${this.onPlayReached}, onLoadedMetaDataReached=${this.onLoadedMetaDataReached})`);
19716
19816
  if (this.onPlayReached && this.onLoadedMetaDataReached) if (this.audioRecorder) try {
19717
19817
  this.audioRecorder.init(localMediaStream);
19718
- this.on("SENDING_FIRST_FRAME", ()=>{
19719
- this.audioRecord(audioCallback);
19720
- });
19721
- videoCallback();
19818
+ const onAudioReady = ()=>{
19819
+ var _this_clearInitializationListeners, _this;
19820
+ if (initializationId !== this.initializationId || this.currentVisualStream !== localMediaStream) return;
19821
+ if (this.recording) this.audioRecord(audioCallback);
19822
+ else this.on("SENDING_FIRST_FRAME", ()=>{
19823
+ this.audioRecord(audioCallback);
19824
+ });
19825
+ null == (_this_clearInitializationListeners = (_this = this).clearInitializationListeners) || _this_clearInitializationListeners.call(_this);
19826
+ videoCallback();
19827
+ };
19828
+ if (null == params ? void 0 : params.recovering) this.audioRecorder.resume().then(onAudioReady).catch(endedEarlyCallback);
19829
+ else onAudioReady();
19722
19830
  } catch (exc) {
19723
19831
  unloadAllEventListeners();
19724
- this.stop();
19832
+ this.stop(void 0, {
19833
+ preserveRecordingState: Boolean(null == params ? void 0 : params.recovering)
19834
+ });
19725
19835
  endedEarlyCallback(exc);
19726
19836
  }
19727
- else videoCallback();
19837
+ else {
19838
+ var _this_clearInitializationListeners, _this;
19839
+ null == (_this_clearInitializationListeners = (_this = this).clearInitializationListeners) || _this_clearInitializationListeners.call(_this);
19840
+ videoCallback();
19841
+ }
19728
19842
  };
19729
19843
  const onPlay = ()=>{
19730
19844
  try {
@@ -19797,9 +19911,8 @@ var __webpack_exports__ = {};
19797
19911
  this.setVisualStream(localMediaStream);
19798
19912
  play();
19799
19913
  } catch (exc) {
19800
- this.emit("ERROR", {
19801
- exc
19802
- });
19914
+ unloadAllEventListeners();
19915
+ endedEarlyCallback(exc);
19803
19916
  }
19804
19917
  }
19805
19918
  getVideoTrackLabel() {
@@ -19813,7 +19926,9 @@ var __webpack_exports__ = {};
19813
19926
  try {
19814
19927
  let chosenStream = visualStream;
19815
19928
  if (!(null == params ? void 0 : params.aboutToInitialize)) {
19816
- var _this_audioRecorder;
19929
+ var _this_clearInitializationListeners, _this, _this_audioRecorder;
19930
+ this.initializationId++;
19931
+ null == (_this_clearInitializationListeners = (_this = this).clearInitializationListeners) || _this_clearInitializationListeners.call(_this);
19817
19932
  null != chosenStream || (chosenStream = this.currentVisualStream);
19818
19933
  const tracks = null == chosenStream ? void 0 : chosenStream.getTracks();
19819
19934
  if (tracks) tracks.forEach((track)=>{
@@ -19823,7 +19938,7 @@ var __webpack_exports__ = {};
19823
19938
  null == (_this_audioRecorder = this.audioRecorder) || _this_audioRecorder.stop();
19824
19939
  this.audioRecorder = void 0;
19825
19940
  }
19826
- if (!(null == params ? void 0 : params.switchingFacingMode)) this.paused = this.recording = false;
19941
+ if (!(null == params ? void 0 : params.preserveRecordingState)) this.paused = this.recording = false;
19827
19942
  } catch (exc) {
19828
19943
  this.emit("ERROR", {
19829
19944
  exc
@@ -19911,7 +20026,7 @@ var __webpack_exports__ = {};
19911
20026
  };
19912
20027
  }
19913
20028
  constructor(recorder, options){
19914
- super("UserMedia", options), userMedia_define_property(this, "recorder", void 0), userMedia_define_property(this, "rawVisualUserMedia", void 0), userMedia_define_property(this, "paused", false), userMedia_define_property(this, "recording", false), userMedia_define_property(this, "audioRecorder", void 0), userMedia_define_property(this, "currentVisualStream", void 0), userMedia_define_property(this, "onPlayReached", false), userMedia_define_property(this, "onLoadedMetaDataReached", false), userMedia_define_property(this, "playingPromiseReached", false), userMedia_define_property(this, "videoTrackLabel", void 0), userMedia_define_property(this, "outputEvent", (e)=>{
20029
+ super("UserMedia", options), userMedia_define_property(this, "recorder", void 0), userMedia_define_property(this, "rawVisualUserMedia", void 0), userMedia_define_property(this, "paused", false), userMedia_define_property(this, "recording", false), userMedia_define_property(this, "audioRecorder", void 0), userMedia_define_property(this, "currentVisualStream", void 0), userMedia_define_property(this, "onPlayReached", false), userMedia_define_property(this, "onLoadedMetaDataReached", false), userMedia_define_property(this, "playingPromiseReached", false), userMedia_define_property(this, "videoTrackLabel", void 0), userMedia_define_property(this, "clearInitializationListeners", void 0), userMedia_define_property(this, "initializationId", 0), userMedia_define_property(this, "outputEvent", (e)=>{
19915
20030
  var _this_rawVisualUserMedia, _this_rawVisualUserMedia1;
19916
20031
  this.logEvent(e.type, {
19917
20032
  readyState: null == (_this_rawVisualUserMedia = this.rawVisualUserMedia) ? void 0 : _this_rawVisualUserMedia.readyState
@@ -20193,7 +20308,10 @@ var __webpack_exports__ = {};
20193
20308
  this.pingInterval = void 0;
20194
20309
  }
20195
20310
  onAudioSample(audioSample) {
20196
- if (this.recordingTransportFailed) return;
20311
+ var _this_userMedia;
20312
+ if (this.recordingTransportFailed || this.cameraRecovery) return;
20313
+ const sampleRate = null == (_this_userMedia = this.userMedia) ? void 0 : _this_userMedia.getAudioSampleRate();
20314
+ if (sampleRate && sampleRate > 0) null != this.recordingAudioSampleRate || (this.recordingAudioSampleRate = sampleRate);
20197
20315
  this.samplesCount++;
20198
20316
  this.mediaTransmissionStarted = true;
20199
20317
  const audioBuffer = audioSample.toBuffer();
@@ -20206,19 +20324,27 @@ var __webpack_exports__ = {};
20206
20324
  try {
20207
20325
  this.options.logger.debug(`Recorder: onUserMediaReady(${params ? string_pretty(params) : ""})`);
20208
20326
  const switchingFacingMode = null == params ? void 0 : params.switchingFacingMode;
20327
+ if (null == params ? void 0 : params.recovering) {
20328
+ var _this_userMedia;
20329
+ if (!(null == (_this_userMedia = this.userMedia) ? void 0 : _this_userMedia.hasLiveStream())) return void this.failCameraRecovery(new Error("The restored camera has no live tracks."));
20330
+ if (void 0 !== this.recordingAudioSampleRate && this.userMedia.getAudioSampleRate() !== this.recordingAudioSampleRate) return void this.failCameraRecovery(new Error("The audio sample rate changed during recovery."));
20331
+ }
20209
20332
  this.userMediaLoading = this.blocking = this.unloaded = this.submitting = false;
20210
20333
  this.userMediaLoaded = true;
20211
20334
  this.clearUserMediaTimeout();
20212
- if (!switchingFacingMode) this.loop = this.createLoop();
20335
+ if (!switchingFacingMode && !(null == params ? void 0 : params.recovering)) this.loop = this.createLoop();
20213
20336
  this.show();
20214
20337
  if (null == params ? void 0 : params.recordWhenReady) this.record();
20215
20338
  this.emit("USER_MEDIA_READY", {
20216
20339
  switchingFacingMode: null == params ? void 0 : params.switchingFacingMode,
20340
+ recovering: null == params ? void 0 : params.recovering,
20217
20341
  paused: this.isPaused(),
20218
20342
  recordWhenReady: null == params ? void 0 : params.recordWhenReady
20219
20343
  });
20344
+ if (null == params ? void 0 : params.recovering) this.finishCameraRecovery(true);
20220
20345
  } catch (exc) {
20221
- this.emit("ERROR", {
20346
+ if (null == params ? void 0 : params.recovering) this.failCameraRecovery(exc);
20347
+ else this.emit("ERROR", {
20222
20348
  exc
20223
20349
  });
20224
20350
  }
@@ -20593,6 +20719,7 @@ var __webpack_exports__ = {};
20593
20719
  }
20594
20720
  userMediaErrorCallback(err, usedConstraints) {
20595
20721
  var _this_userMedia;
20722
+ if (this.cameraRecovery) return void this.failCameraRecovery(err);
20596
20723
  if (this.unloaded) return void this.options.logger.debug(`Recorder: already unloaded. Not going to throw error ${string_pretty(err)}`);
20597
20724
  this.userMediaLoading = false;
20598
20725
  this.clearUserMediaTimeout();
@@ -20624,7 +20751,7 @@ var __webpack_exports__ = {};
20624
20751
  });
20625
20752
  }
20626
20753
  }
20627
- getUserMediaCallback(localStream, params) {
20754
+ getUserMediaCallback(localStream, params, requestId = this.mediaRequestId) {
20628
20755
  if (!this.userMedia) {
20629
20756
  localStream.getTracks().forEach((track)=>{
20630
20757
  track.stop();
@@ -20637,20 +20764,20 @@ var __webpack_exports__ = {};
20637
20764
  this.options.logger.debug(`Recorder: getUserMediaCallback(${params ? string_pretty(params) : ""})`);
20638
20765
  if (this.showUserMedia()) try {
20639
20766
  this.userMedia.init(localStream, ()=>{
20640
- if (!this.unloaded) this.onUserMediaReady(params);
20767
+ if (!this.unloaded && requestId === this.mediaRequestId) this.onUserMediaReady(params);
20641
20768
  }, this.onAudioSample.bind(this), (err)=>{
20642
- if (!this.unloaded) this.userMediaErrorCallback(err, {
20769
+ if (!this.unloaded && requestId === this.mediaRequestId) this.userMediaErrorCallback(err, {
20643
20770
  audio: isAudioEnabled(this.options)
20644
20771
  });
20645
- }, null == params ? void 0 : params.switchingFacingMode);
20772
+ }, params);
20646
20773
  } catch (exc) {
20647
20774
  localStream.getTracks().forEach((track)=>{
20648
20775
  track.stop();
20649
20776
  });
20650
20777
  this.userMediaLoading = false;
20651
20778
  this.clearUserMediaTimeout();
20652
- this.emit("ERROR", {
20653
- exc
20779
+ this.userMediaErrorCallback(exc, {
20780
+ audio: isAudioEnabled(this.options)
20654
20781
  });
20655
20782
  }
20656
20783
  else {
@@ -20659,12 +20786,14 @@ var __webpack_exports__ = {};
20659
20786
  });
20660
20787
  this.userMediaLoading = false;
20661
20788
  this.clearUserMediaTimeout();
20789
+ this.cancelCameraRecovery();
20662
20790
  }
20663
20791
  }
20664
20792
  loadGenuineUserMedia(params) {
20665
20793
  this.options.logger.debug(`Recorder: loadGenuineUserMedia(${params ? string_pretty(params) : ""})`);
20666
20794
  this.emit("ASKING_WEBCAM_PERMISSION");
20667
20795
  this.userMediaLoading = true;
20796
+ const requestId = ++this.mediaRequestId;
20668
20797
  const constraints = {
20669
20798
  video: {
20670
20799
  frameRate: {
@@ -20678,18 +20807,18 @@ var __webpack_exports__ = {};
20678
20807
  this.options.logger.debug(string_summarize("Recorder: available webcam constraints are:", navigator.mediaDevices.getSupportedConstraints()));
20679
20808
  const streamPromise = navigator.mediaDevices.getUserMedia(constraints);
20680
20809
  streamPromise.then((localStream)=>{
20681
- if (this.unloaded) return void localStream.getTracks().forEach((track)=>{
20810
+ if (this.unloaded || requestId !== this.mediaRequestId) return void localStream.getTracks().forEach((track)=>{
20682
20811
  track.stop();
20683
20812
  });
20684
- this.getUserMediaCallback(localStream, params);
20813
+ this.getUserMediaCallback(localStream, params, requestId);
20685
20814
  }).catch((reason)=>{
20686
- if (!this.unloaded) this.userMediaErrorCallback(reason, constraints);
20815
+ if (!this.unloaded && requestId === this.mediaRequestId) this.userMediaErrorCallback(reason, constraints);
20687
20816
  });
20688
20817
  }
20689
20818
  configureVideoConstraints(constraints, params) {
20690
20819
  const videoConstraints = "object" == typeof constraints.video ? constraints.video : void 0;
20691
20820
  if (!videoConstraints) return;
20692
- if (null == params ? void 0 : params.switchingFacingMode) videoConstraints.facingMode = params.switchingFacingMode;
20821
+ if ((null == params ? void 0 : params.switchingFacingMode) || (null == params ? void 0 : params.recovering)) videoConstraints.facingMode = params.switchingFacingMode || this.facingMode;
20693
20822
  if (this.options.video.width) videoConstraints.width = {
20694
20823
  ideal: this.options.video.width
20695
20824
  };
@@ -20717,8 +20846,8 @@ var __webpack_exports__ = {};
20717
20846
  if (!this.userMediaLoaded) {
20718
20847
  this.userMediaLoading = false;
20719
20848
  const err = util_getBrowser(this.options).getNoAccessIssue();
20720
- this.emit("ERROR", {
20721
- err
20849
+ this.userMediaErrorCallback(err, {
20850
+ audio: isAudioEnabled(this.options)
20722
20851
  });
20723
20852
  }
20724
20853
  }, this.options.timeouts.userMedia);
@@ -20728,6 +20857,7 @@ var __webpack_exports__ = {};
20728
20857
  this.clearUserMediaTimeout();
20729
20858
  this.options.logger.debug("Recorder: failed to load genuine user media");
20730
20859
  this.userMediaLoading = false;
20860
+ if (this.cameraRecovery) return void this.failCameraRecovery(exc);
20731
20861
  const errorListeners = this.getListeners("ERROR");
20732
20862
  if (null == errorListeners ? void 0 : errorListeners.length) this.emit("ERROR", {
20733
20863
  exc
@@ -20855,11 +20985,13 @@ var __webpack_exports__ = {};
20855
20985
  return this.recordingStats;
20856
20986
  }
20857
20987
  getAudioSampleRate() {
20988
+ var _this_recordingAudioSampleRate;
20858
20989
  var _this_userMedia;
20859
- return null == (_this_userMedia = this.userMedia) ? void 0 : _this_userMedia.getAudioSampleRate();
20990
+ return null != (_this_recordingAudioSampleRate = this.recordingAudioSampleRate) ? _this_recordingAudioSampleRate : null == (_this_userMedia = this.userMedia) ? void 0 : _this_userMedia.getAudioSampleRate();
20860
20991
  }
20861
20992
  stop(params) {
20862
20993
  var _this_loop;
20994
+ this.cancelCameraRecovery();
20863
20995
  if (!this.userMedia) throw new Error("No user media defined, unable to stop");
20864
20996
  this.options.logger.debug(`Recorder: stop(${params ? string_pretty(params) : ""})`);
20865
20997
  this.recordingActive = false;
@@ -20884,8 +21016,9 @@ var __webpack_exports__ = {};
20884
21016
  };
20885
21017
  if (this.userMedia) this.recordingStats.videoTrackLabel = this.userMedia.getVideoTrackLabel();
20886
21018
  if (isAudioEnabled(this.options) && this.userMedia) {
21019
+ var _this_recordingAudioSampleRate;
20887
21020
  this.recordingStats.samplesCount = this.samplesCount;
20888
- this.recordingStats.sampleRate = this.userMedia.getAudioSampleRate();
21021
+ this.recordingStats.sampleRate = null != (_this_recordingAudioSampleRate = this.recordingAudioSampleRate) ? _this_recordingAudioSampleRate : this.userMedia.getAudioSampleRate();
20889
21022
  }
20890
21023
  this.writeCommand("stop", this.recordingStats, ()=>{
20891
21024
  this.emit("STOPPED", {
@@ -20941,6 +21074,7 @@ var __webpack_exports__ = {};
20941
21074
  this.built = this.connecting = this.connected = false;
20942
21075
  }
20943
21076
  reset() {
21077
+ this.cancelCameraRecovery();
20944
21078
  if (!this.unloaded) {
20945
21079
  var _this_userMedia;
20946
21080
  this.options.logger.debug("Recorder: reset()");
@@ -20970,8 +21104,72 @@ var __webpack_exports__ = {};
20970
21104
  var _this_userMedia;
20971
21105
  return null == (_this_userMedia = this.userMedia) ? void 0 : _this_userMedia.isReady();
20972
21106
  }
21107
+ finishCameraRecovery(restored) {
21108
+ this.clearUserMediaTimeout();
21109
+ const resolve = this.resolveCameraRecovery;
21110
+ const resumeRequested = restored && this.resumeAfterCameraRecovery;
21111
+ this.cameraRecovery = void 0;
21112
+ this.resolveCameraRecovery = void 0;
21113
+ this.resumeAfterCameraRecovery = false;
21114
+ null == resolve || resolve(restored);
21115
+ if (resumeRequested && this.isPaused()) this.resume();
21116
+ }
21117
+ cancelCameraRecovery() {
21118
+ var _this_userMedia;
21119
+ if (!this.cameraRecovery) return;
21120
+ this.mediaRequestId++;
21121
+ this.userMediaLoading = false;
21122
+ this.userMediaLoaded = false;
21123
+ this.clearUserMediaTimeout();
21124
+ null == (_this_userMedia = this.userMedia) || _this_userMedia.stop(void 0, {
21125
+ preserveRecordingState: true
21126
+ });
21127
+ this.finishCameraRecovery(false);
21128
+ }
21129
+ failCameraRecovery(exc) {
21130
+ this.cancelCameraRecovery();
21131
+ const err = error_createError({
21132
+ message: "Camera recovery failed",
21133
+ explanation: "Your recording is still paused. Check camera permissions, then try Resume again or stop to keep the recorded part.",
21134
+ exc,
21135
+ options: this.options
21136
+ });
21137
+ this.emit("CAMERA_RECOVERY_FAILED", {
21138
+ err
21139
+ });
21140
+ }
21141
+ recoverCamera() {
21142
+ if (this.cameraRecovery) return this.cameraRecovery;
21143
+ if (!this.built || this.unloaded || !this.userMedia || this.userMediaLoading || this.submitting || this.key || void 0 !== this.stopTimeout || this.recordingTransportFailed) return Promise.resolve(false);
21144
+ const liveStream = this.userMedia.hasLiveStream();
21145
+ if (liveStream && this.isRecording()) return Promise.resolve(true);
21146
+ if (!liveStream && this.recordingActive && !this.isPaused()) this.pause();
21147
+ const recovery = new Promise((resolve)=>{
21148
+ this.resolveCameraRecovery = resolve;
21149
+ });
21150
+ this.cameraRecovery = recovery;
21151
+ this.emit("CAMERA_RECOVERING");
21152
+ if (liveStream) {
21153
+ this.userMediaTimeout = window.setTimeout(()=>{
21154
+ this.failCameraRecovery(new Error("Camera playback recovery timed out."));
21155
+ }, this.options.timeouts.userMedia);
21156
+ this.userMedia.restorePlayback().then(()=>{
21157
+ if (this.cameraRecovery === recovery) this.finishCameraRecovery(true);
21158
+ }).catch((exc)=>{
21159
+ if (this.cameraRecovery === recovery) this.failCameraRecovery(exc);
21160
+ });
21161
+ } else {
21162
+ this.userMediaLoaded = false;
21163
+ this.loadUserMedia({
21164
+ recovering: true
21165
+ });
21166
+ }
21167
+ return recovery;
21168
+ }
20973
21169
  pause(params) {
20974
21170
  var _this_userMedia;
21171
+ this.cancelCameraRecovery();
21172
+ this.resumeAfterDrain = false;
20975
21173
  if (params) this.options.logger.debug(`pause() at frame ${this.framesCount} with ${string_pretty(params)}`);
20976
21174
  else this.options.logger.debug(`pause() at frame ${this.framesCount}`);
20977
21175
  null == (_this_userMedia = this.userMedia) || _this_userMedia.pause();
@@ -20981,10 +21179,15 @@ var __webpack_exports__ = {};
20981
21179
  }
20982
21180
  resume() {
20983
21181
  var _this_userMedia;
21182
+ if (this.cameraRecovery || !(null == (_this_userMedia = this.userMedia) ? void 0 : _this_userMedia.hasLiveStream())) {
21183
+ this.recoverCamera();
21184
+ this.resumeAfterCameraRecovery = Boolean(this.cameraRecovery);
21185
+ return;
21186
+ }
20984
21187
  this.options.logger.debug(`Recorder: resume() with frame ${this.framesCount}`);
20985
21188
  this.stopPings();
20986
21189
  this.emit("RESUMING");
20987
- null == (_this_userMedia = this.userMedia) || _this_userMedia.resume();
21190
+ this.userMedia.resume();
20988
21191
  if (this.streamBackpressured) this.resumeAfterDrain = true;
20989
21192
  else this.loop.start();
20990
21193
  }
@@ -21040,7 +21243,7 @@ var __webpack_exports__ = {};
21040
21243
  return newLoop;
21041
21244
  }
21042
21245
  record() {
21043
- if (this.unloaded) return;
21246
+ if (this.unloaded || this.cameraRecovery) return;
21044
21247
  if (!this.connected) {
21045
21248
  this.options.logger.debug("Recorder: reconnecting before recording …");
21046
21249
  this.initSocket(()=>{
@@ -21113,6 +21316,7 @@ var __webpack_exports__ = {};
21113
21316
  this.recordingActive = true;
21114
21317
  this.recordingTransportFailed = false;
21115
21318
  this.mediaTransmissionStarted = false;
21319
+ this.recordingAudioSampleRate = void 0;
21116
21320
  this.userMedia.record();
21117
21321
  this.emit("RECORDING", {
21118
21322
  framesCount: this.framesCount
@@ -21174,7 +21378,7 @@ var __webpack_exports__ = {};
21174
21378
  }
21175
21379
  }
21176
21380
  switchFacingMode() {
21177
- if (!util_getBrowser(this.options).isMobile()) return;
21381
+ if (this.cameraRecovery || !util_getBrowser(this.options).isMobile()) return;
21178
21382
  if ("user" === this.facingMode) this.facingMode = "environment";
21179
21383
  else if ("environment" === this.facingMode) this.facingMode = "user";
21180
21384
  else this.options.logger.warn(`Recorder: unsupported facing mode ${string_pretty(this.facingMode)}`);
@@ -21185,12 +21389,14 @@ var __webpack_exports__ = {};
21185
21389
  initEvents() {
21186
21390
  this.options.logger.debug("Recorder: initEvents()");
21187
21391
  this.on("SUBMITTING", ()=>{
21392
+ this.cancelCameraRecovery();
21188
21393
  this.submitting = true;
21189
21394
  });
21190
21395
  this.on("SUBMITTED", ()=>{
21191
21396
  this.submitting = false;
21192
21397
  });
21193
21398
  this.on("BLOCKING", ()=>{
21399
+ this.cancelCameraRecovery();
21194
21400
  this.blocking = true;
21195
21401
  this.clearUserMediaTimeout();
21196
21402
  });
@@ -21366,7 +21572,7 @@ var __webpack_exports__ = {};
21366
21572
  return this.userMediaLoaded;
21367
21573
  }
21368
21574
  constructor(visuals, replay, options){
21369
- super("Recorder", options), recorder_define_property(this, "visuals", void 0), recorder_define_property(this, "replay", void 0), recorder_define_property(this, "pendingWrites", new boundedWriteQueue()), recorder_define_property(this, "loop", void 0), recorder_define_property(this, "originalAnimationFrameObject", void 0), recorder_define_property(this, "samplesCount", 0), recorder_define_property(this, "framesCount", 0), recorder_define_property(this, "recordingStats", void 0), recorder_define_property(this, "confirmedFrameNumber", 0), recorder_define_property(this, "confirmedSampleNumber", 0), recorder_define_property(this, "recorderElement", void 0), recorder_define_property(this, "userMedia", void 0), recorder_define_property(this, "userMediaTimeout", void 0), recorder_define_property(this, "retryTimeout", void 0), recorder_define_property(this, "reconnectTimeout", void 0), recorder_define_property(this, "connectionTimeout", void 0), recorder_define_property(this, "backpressureTimeout", void 0), recorder_define_property(this, "stopTimeout", void 0), recorder_define_property(this, "frameProgress", void 0), recorder_define_property(this, "sampleProgress", void 0), recorder_define_property(this, "canvas", void 0), recorder_define_property(this, "recordingDimensions", void 0), recorder_define_property(this, "ctx", void 0), recorder_define_property(this, "userMediaLoaded", void 0), recorder_define_property(this, "userMediaLoading", false), recorder_define_property(this, "submitting", false), recorder_define_property(this, "unloaded", void 0), recorder_define_property(this, "stopTime", void 0), recorder_define_property(this, "stream", void 0), recorder_define_property(this, "streamBackpressured", false), recorder_define_property(this, "resumeAfterDrain", false), recorder_define_property(this, "mediaTransmissionStarted", false), recorder_define_property(this, "recordingActive", false), recorder_define_property(this, "recordingTransportFailed", false), recorder_define_property(this, "connecting", false), recorder_define_property(this, "connected", false), recorder_define_property(this, "connectionFailed", false), recorder_define_property(this, "reconnecting", false), recorder_define_property(this, "reconnectAttempts", 0), recorder_define_property(this, "blocking", false), recorder_define_property(this, "built", false), recorder_define_property(this, "key", void 0), recorder_define_property(this, "waitingTime", void 0), recorder_define_property(this, "connectingStartedAt", void 0), recorder_define_property(this, "lastCloseEvent", void 0), recorder_define_property(this, "lastSocketError", void 0), recorder_define_property(this, "pingInterval", void 0), recorder_define_property(this, "frame", void 0), recorder_define_property(this, "recordingBuffer", void 0), recorder_define_property(this, "facingMode", void 0);
21575
+ super("Recorder", options), recorder_define_property(this, "visuals", void 0), recorder_define_property(this, "replay", void 0), recorder_define_property(this, "pendingWrites", new boundedWriteQueue()), recorder_define_property(this, "loop", void 0), recorder_define_property(this, "originalAnimationFrameObject", void 0), recorder_define_property(this, "samplesCount", 0), recorder_define_property(this, "framesCount", 0), recorder_define_property(this, "recordingAudioSampleRate", void 0), recorder_define_property(this, "recordingStats", void 0), recorder_define_property(this, "confirmedFrameNumber", 0), recorder_define_property(this, "confirmedSampleNumber", 0), recorder_define_property(this, "recorderElement", void 0), recorder_define_property(this, "userMedia", void 0), recorder_define_property(this, "userMediaTimeout", void 0), recorder_define_property(this, "retryTimeout", void 0), recorder_define_property(this, "reconnectTimeout", void 0), recorder_define_property(this, "connectionTimeout", void 0), recorder_define_property(this, "backpressureTimeout", void 0), recorder_define_property(this, "stopTimeout", void 0), recorder_define_property(this, "frameProgress", void 0), recorder_define_property(this, "sampleProgress", void 0), recorder_define_property(this, "canvas", void 0), recorder_define_property(this, "recordingDimensions", void 0), recorder_define_property(this, "ctx", void 0), recorder_define_property(this, "userMediaLoaded", void 0), recorder_define_property(this, "userMediaLoading", false), recorder_define_property(this, "mediaRequestId", 0), recorder_define_property(this, "cameraRecovery", void 0), recorder_define_property(this, "resolveCameraRecovery", void 0), recorder_define_property(this, "resumeAfterCameraRecovery", false), recorder_define_property(this, "submitting", false), recorder_define_property(this, "unloaded", void 0), recorder_define_property(this, "stopTime", void 0), recorder_define_property(this, "stream", void 0), recorder_define_property(this, "streamBackpressured", false), recorder_define_property(this, "resumeAfterDrain", false), recorder_define_property(this, "mediaTransmissionStarted", false), recorder_define_property(this, "recordingActive", false), recorder_define_property(this, "recordingTransportFailed", false), recorder_define_property(this, "connecting", false), recorder_define_property(this, "connected", false), recorder_define_property(this, "connectionFailed", false), recorder_define_property(this, "reconnecting", false), recorder_define_property(this, "reconnectAttempts", 0), recorder_define_property(this, "blocking", false), recorder_define_property(this, "built", false), recorder_define_property(this, "key", void 0), recorder_define_property(this, "waitingTime", void 0), recorder_define_property(this, "connectingStartedAt", void 0), recorder_define_property(this, "lastCloseEvent", void 0), recorder_define_property(this, "lastSocketError", void 0), recorder_define_property(this, "pingInterval", void 0), recorder_define_property(this, "frame", void 0), recorder_define_property(this, "recordingBuffer", void 0), recorder_define_property(this, "facingMode", void 0);
21370
21576
  this.visuals = visuals;
21371
21577
  this.replay = replay;
21372
21578
  this.facingMode = options.video.facingMode;
@@ -21678,6 +21884,17 @@ var __webpack_exports__ = {};
21678
21884
  this.endWaiting();
21679
21885
  this.container.enableForm(false);
21680
21886
  });
21887
+ this.on("CAMERA_RECOVERING", ()=>{
21888
+ this.clearCameraRecoveryNotice();
21889
+ });
21890
+ this.on("CAMERA_RECOVERY_FAILED", ({ err })=>{
21891
+ this.cameraRecoveryFailed = true;
21892
+ this.options.logger.warn(err);
21893
+ if (this.options.displayErrors) this.notifier.notify(err.message, err.explanation, {
21894
+ problem: true
21895
+ });
21896
+ this.endWaiting();
21897
+ });
21681
21898
  this.on("PREVIEW", ()=>{
21682
21899
  this.endWaiting();
21683
21900
  });
@@ -21758,6 +21975,7 @@ var __webpack_exports__ = {};
21758
21975
  child.remove();
21759
21976
  }
21760
21977
  reset() {
21978
+ this.clearCameraRecoveryNotice();
21761
21979
  this.endWaiting();
21762
21980
  this.recorder.reset();
21763
21981
  }
@@ -21768,11 +21986,13 @@ var __webpack_exports__ = {};
21768
21986
  this.container.endWaiting();
21769
21987
  }
21770
21988
  stop(params) {
21989
+ this.clearCameraRecoveryNotice();
21771
21990
  this.recorder.stop(params);
21772
21991
  this.recorderInsides.hidePause();
21773
21992
  }
21774
21993
  back(keepHidden = false, cb) {
21775
21994
  this.options.logger.debug(`Visuals: back(keepHidden = ${keepHidden})`);
21995
+ this.cameraRecoveryFailed = false;
21776
21996
  this.replay.hide();
21777
21997
  this.notifier.hide();
21778
21998
  if (keepHidden) {
@@ -21794,6 +22014,7 @@ var __webpack_exports__ = {};
21794
22014
  if (!this.built) return;
21795
22015
  const e = null == params ? void 0 : params.e;
21796
22016
  this.options.logger.debug(`Visuals: unload(${e ? string_pretty(e) : ""})`);
22017
+ this.cameraRecoveryFailed = false;
21797
22018
  this.recorder.unload(params);
21798
22019
  this.recorderInsides.unload();
21799
22020
  this.replay.unload(params);
@@ -21807,13 +22028,31 @@ var __webpack_exports__ = {};
21807
22028
  this.recorder.pause(params);
21808
22029
  this.recorderInsides.showPause();
21809
22030
  }
22031
+ clearCameraRecoveryNotice() {
22032
+ if (this.cameraRecoveryFailed) {
22033
+ this.notifier.hide();
22034
+ this.recorder.show();
22035
+ this.cameraRecoveryFailed = false;
22036
+ }
22037
+ }
22038
+ recoverCamera() {
22039
+ if (this.replay.isShown() || this.isNotifying() && !this.cameraRecoveryFailed) return Promise.resolve(false);
22040
+ this.clearCameraRecoveryNotice();
22041
+ return this.recorder.recoverCamera();
22042
+ }
21810
22043
  resume() {
21811
- if (this.recorderInsides.isCountingDown()) this.recorderInsides.resumeCountdown();
21812
- else this.recorder.resume();
21813
- this.recorderInsides.hidePause();
22044
+ this.clearCameraRecoveryNotice();
22045
+ if (this.recorderInsides.isCountingDown()) {
22046
+ this.recorderInsides.resumeCountdown();
22047
+ this.recorderInsides.hidePause();
22048
+ } else {
22049
+ this.recorder.resume();
22050
+ if (!this.recorder.isPaused()) this.recorderInsides.hidePause();
22051
+ }
21814
22052
  }
21815
22053
  pauseOrResume() {
21816
- if (this.isRecordable()) {
22054
+ if (this.cameraRecoveryFailed && this.recorder.isPaused()) this.resume();
22055
+ else if (this.isRecordable()) {
21817
22056
  if (this.isRecording()) this.pause();
21818
22057
  else if (this.recorder.isPaused()) this.resume();
21819
22058
  else if (this.recorder.isReady()) this.recorder.record();
@@ -21936,7 +22175,7 @@ var __webpack_exports__ = {};
21936
22175
  return this.visualsElement;
21937
22176
  }
21938
22177
  constructor(container, options){
21939
- super("Visuals", options), visuals_define_property(this, "container", void 0), visuals_define_property(this, "replay", void 0), visuals_define_property(this, "recorder", void 0), visuals_define_property(this, "recorderInsides", void 0), visuals_define_property(this, "notifier", void 0), visuals_define_property(this, "visualsElement", void 0), visuals_define_property(this, "built", false);
22178
+ super("Visuals", options), visuals_define_property(this, "container", void 0), visuals_define_property(this, "replay", void 0), visuals_define_property(this, "recorder", void 0), visuals_define_property(this, "recorderInsides", void 0), visuals_define_property(this, "notifier", void 0), visuals_define_property(this, "visualsElement", void 0), visuals_define_property(this, "built", false), visuals_define_property(this, "cameraRecoveryFailed", false);
21940
22179
  this.container = container;
21941
22180
  this.replay = new visuals_replay(this, options);
21942
22181
  this.recorder = new visuals_recorder(this, this.replay, options);
@@ -22080,10 +22319,10 @@ var __webpack_exports__ = {};
22080
22319
  });
22081
22320
  if (!playerOnly) this.stopListeningToVisibility = this.visibility.onChange((visible)=>{
22082
22321
  if (this.built) if (visible) {
22083
- if (isAutoPauseEnabled(this.options) && this.isCountingDown()) this.resume();
22322
+ if (isAutoPauseEnabled(this.options)) this.recoverCamera();
22084
22323
  this.emit("VISIBLE");
22085
22324
  } else {
22086
- if (isAutoPauseEnabled(this.options) && (this.isCountingDown() || this.isRecording())) this.pause();
22325
+ if (isAutoPauseEnabled(this.options)) this.suspend();
22087
22326
  this.emit("INVISIBLE");
22088
22327
  }
22089
22328
  });
@@ -22277,6 +22516,13 @@ var __webpack_exports__ = {};
22277
22516
  pause(params) {
22278
22517
  this.visuals.pause(params);
22279
22518
  }
22519
+ suspend() {
22520
+ if (this.built && (this.isCountingDown() || this.isRecording() || this.isPaused())) this.pause();
22521
+ }
22522
+ recoverCamera() {
22523
+ if (!this.built || this.hasError || this.submitted) return Promise.resolve(false);
22524
+ return this.visuals.recoverCamera();
22525
+ }
22280
22526
  validate(event, force = false) {
22281
22527
  let runValidation = true;
22282
22528
  let valid = true;
@@ -22664,6 +22910,12 @@ var __webpack_exports__ = {};
22664
22910
  record() {
22665
22911
  this.container.record();
22666
22912
  }
22913
+ pause() {
22914
+ this.container.suspend();
22915
+ }
22916
+ recoverCamera() {
22917
+ return this.container.recoverCamera();
22918
+ }
22667
22919
  getLogLines() {
22668
22920
  if (this.options.logger.getLines) return this.options.logger.getLines();
22669
22921
  }