videomail-client 15.8.3 → 15.9.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/cjs/index.cjs +138 -54
- package/dist/esm/index.js +138 -54
- package/dist/esm/wrappers/visuals/recorder.d.ts +7 -0
- package/dist/umd/index.js +140 -53
- package/package.json +4 -4
package/dist/cjs/index.cjs
CHANGED
|
@@ -10972,7 +10972,7 @@ var __webpack_exports__ = {};
|
|
|
10972
10972
|
var client = __webpack_require__("Q");
|
|
10973
10973
|
var client_default = /*#__PURE__*/ __webpack_require__.n(client);
|
|
10974
10974
|
var package_namespaceObject = {
|
|
10975
|
-
rE: "15.
|
|
10975
|
+
rE: "15.9.0"
|
|
10976
10976
|
};
|
|
10977
10977
|
function isAudioEnabled(options) {
|
|
10978
10978
|
return Boolean(options.audio.enabled);
|
|
@@ -19188,7 +19188,7 @@ var __webpack_exports__ = {};
|
|
|
19188
19188
|
}
|
|
19189
19189
|
let { bufferSize } = this.options.audio;
|
|
19190
19190
|
if ("auto" === bufferSize) bufferSize = util_getBrowser(this.options).isFirefox() ? 512 : 2048;
|
|
19191
|
-
if (!is_power_of_two_default()(bufferSize)) throw error_createError({
|
|
19191
|
+
if (void 0 === bufferSize || !is_power_of_two_default()(bufferSize)) throw error_createError({
|
|
19192
19192
|
message: `Audio buffer size must be a power of two. The current buffer size is ${bufferSize}.`,
|
|
19193
19193
|
options: this.options
|
|
19194
19194
|
});
|
|
@@ -19267,9 +19267,14 @@ var __webpack_exports__ = {};
|
|
|
19267
19267
|
const EVENT_ASCII = "|—O—|";
|
|
19268
19268
|
class UserMedia extends util_Despot {
|
|
19269
19269
|
attachMediaStream(stream) {
|
|
19270
|
-
this.
|
|
19271
|
-
|
|
19272
|
-
|
|
19270
|
+
if (this.rawVisualUserMedia) {
|
|
19271
|
+
this.rawVisualUserMedia.srcObject = stream;
|
|
19272
|
+
const previousStream = this.currentVisualStream;
|
|
19273
|
+
this.currentVisualStream = stream;
|
|
19274
|
+
if (previousStream && previousStream !== stream) previousStream.getTracks().forEach((track)=>{
|
|
19275
|
+
track.stop();
|
|
19276
|
+
});
|
|
19277
|
+
} else throw error_createError({
|
|
19273
19278
|
message: "Error attaching stream to element.",
|
|
19274
19279
|
explanation: "Contact the developer about this",
|
|
19275
19280
|
options: this.options
|
|
@@ -19343,11 +19348,14 @@ var __webpack_exports__ = {};
|
|
|
19343
19348
|
}
|
|
19344
19349
|
}).catch((exc)=>{
|
|
19345
19350
|
if (exc instanceof Error) this.options.logger.warn(`Caught pending user media promise exception: ${exc.toString()}`);
|
|
19346
|
-
else
|
|
19347
|
-
|
|
19348
|
-
|
|
19349
|
-
|
|
19350
|
-
|
|
19351
|
+
else {
|
|
19352
|
+
unloadAllEventListeners();
|
|
19353
|
+
endedEarlyCallback(error_createError({
|
|
19354
|
+
message: "Failed to play user media upon play event.",
|
|
19355
|
+
exc,
|
|
19356
|
+
options: this.options
|
|
19357
|
+
}));
|
|
19358
|
+
}
|
|
19351
19359
|
});
|
|
19352
19360
|
}
|
|
19353
19361
|
} catch (exc) {
|
|
@@ -19359,18 +19367,18 @@ var __webpack_exports__ = {};
|
|
|
19359
19367
|
var _this_rawVisualUserMedia;
|
|
19360
19368
|
const readyState = null == (_this_rawVisualUserMedia = this.rawVisualUserMedia) ? void 0 : _this_rawVisualUserMedia.readyState;
|
|
19361
19369
|
this.options.logger.debug(`UserMedia: fireCallbacks(readyState=${readyState}, onPlayReached=${this.onPlayReached}, onLoadedMetaDataReached=${this.onLoadedMetaDataReached})`);
|
|
19362
|
-
if (this.onPlayReached && this.onLoadedMetaDataReached) {
|
|
19370
|
+
if (this.onPlayReached && this.onLoadedMetaDataReached) if (this.audioRecorder) try {
|
|
19371
|
+
this.audioRecorder.init(localMediaStream);
|
|
19372
|
+
this.on("SENDING_FIRST_FRAME", ()=>{
|
|
19373
|
+
this.audioRecord(audioCallback);
|
|
19374
|
+
});
|
|
19363
19375
|
videoCallback();
|
|
19364
|
-
|
|
19365
|
-
|
|
19366
|
-
|
|
19367
|
-
|
|
19368
|
-
});
|
|
19369
|
-
} catch (exc) {
|
|
19370
|
-
unloadAllEventListeners();
|
|
19371
|
-
endedEarlyCallback(exc);
|
|
19372
|
-
}
|
|
19376
|
+
} catch (exc) {
|
|
19377
|
+
unloadAllEventListeners();
|
|
19378
|
+
this.stop();
|
|
19379
|
+
endedEarlyCallback(exc);
|
|
19373
19380
|
}
|
|
19381
|
+
else videoCallback();
|
|
19374
19382
|
};
|
|
19375
19383
|
const onPlay = ()=>{
|
|
19376
19384
|
try {
|
|
@@ -19684,6 +19692,37 @@ var __webpack_exports__ = {};
|
|
|
19684
19692
|
window.clearTimeout(this.connectionTimeout);
|
|
19685
19693
|
this.connectionTimeout = void 0;
|
|
19686
19694
|
}
|
|
19695
|
+
clearReconnectTimeout() {
|
|
19696
|
+
if (void 0 === this.reconnectTimeout) return;
|
|
19697
|
+
this.options.logger.debug("Recorder: clearReconnectTimeout()");
|
|
19698
|
+
window.clearTimeout(this.reconnectTimeout);
|
|
19699
|
+
this.reconnectTimeout = void 0;
|
|
19700
|
+
}
|
|
19701
|
+
handleConnectionFailure(params) {
|
|
19702
|
+
if (this.retryConnection(params)) return;
|
|
19703
|
+
this.failConnection(params);
|
|
19704
|
+
}
|
|
19705
|
+
retryConnection(params) {
|
|
19706
|
+
if (!this.reconnecting || !this.userMediaLoaded || !this.isOnline() || this.unloaded || this.blocking) return false;
|
|
19707
|
+
if (void 0 !== this.reconnectTimeout) return true;
|
|
19708
|
+
const delayMs = Math.min(500 * Math.pow(2, this.reconnectAttempts), 10000);
|
|
19709
|
+
this.reconnectAttempts++;
|
|
19710
|
+
this.connecting = false;
|
|
19711
|
+
this.clearConnectionTimeout();
|
|
19712
|
+
this.discardSocket();
|
|
19713
|
+
this.options.logger.debug(`Recorder: WebSocket reconnect failed (${params.cause}); retrying in ${delayMs}ms.`);
|
|
19714
|
+
this.reconnectTimeout = window.setTimeout(()=>{
|
|
19715
|
+
this.reconnectTimeout = void 0;
|
|
19716
|
+
if (this.reconnecting && !this.unloaded && !this.blocking) this.initSocket();
|
|
19717
|
+
}, delayMs);
|
|
19718
|
+
return true;
|
|
19719
|
+
}
|
|
19720
|
+
discardSocket() {
|
|
19721
|
+
this.options.logger.debug("Recorder: discarding socket stream ...");
|
|
19722
|
+
const stream = this.stream;
|
|
19723
|
+
this.stream = void 0;
|
|
19724
|
+
if (stream && !stream.destroyed) stream.destroy();
|
|
19725
|
+
}
|
|
19687
19726
|
isOnline() {
|
|
19688
19727
|
return navigator.onLine;
|
|
19689
19728
|
}
|
|
@@ -19692,6 +19731,9 @@ var __webpack_exports__ = {};
|
|
|
19692
19731
|
if (this.connectionFailed || this.connected || this.unloaded) return;
|
|
19693
19732
|
this.connectionFailed = true;
|
|
19694
19733
|
this.connecting = false;
|
|
19734
|
+
this.reconnecting = false;
|
|
19735
|
+
this.reconnectAttempts = 0;
|
|
19736
|
+
this.clearReconnectTimeout();
|
|
19695
19737
|
this.clearConnectionTimeout();
|
|
19696
19738
|
const { url2Connect, cause } = params;
|
|
19697
19739
|
const online = this.isOnline();
|
|
@@ -19726,10 +19768,7 @@ var __webpack_exports__ = {};
|
|
|
19726
19768
|
explanation = `Connection to ${url2Connect} is closed${closeSuffix}. Please check your internet connection and try again. If the problem persists, contact us.`;
|
|
19727
19769
|
}
|
|
19728
19770
|
else explanation = "Your device appears to be offline. Please check your internet connection and try again.";
|
|
19729
|
-
|
|
19730
|
-
this.stream.destroy();
|
|
19731
|
-
this.stream = void 0;
|
|
19732
|
-
}
|
|
19771
|
+
this.discardSocket();
|
|
19733
19772
|
const err = error_createError({
|
|
19734
19773
|
message: "Unable to connect to the server",
|
|
19735
19774
|
explanation,
|
|
@@ -19813,8 +19852,13 @@ var __webpack_exports__ = {};
|
|
|
19813
19852
|
this.recordingStats.waitingTime = this.waitingTime;
|
|
19814
19853
|
}
|
|
19815
19854
|
initSocket(cb) {
|
|
19816
|
-
if (this.connected)
|
|
19817
|
-
|
|
19855
|
+
if (this.connected) {
|
|
19856
|
+
this.options.logger.debug("Recorder: already **connected**. Not going to initialize a new WebSocket connection.");
|
|
19857
|
+
null == cb || cb();
|
|
19858
|
+
return;
|
|
19859
|
+
}
|
|
19860
|
+
if (this.connecting) return void this.options.logger.debug("Recorder: already **connecting**. Not going to initialize a new WebSocket connection.");
|
|
19861
|
+
this.clearReconnectTimeout();
|
|
19818
19862
|
if (util_isAutomatedUserAgent()) {
|
|
19819
19863
|
this.connecting = false;
|
|
19820
19864
|
this.options.logger.debug("Recorder: skipping web socket connection for an automated crawler");
|
|
@@ -19893,8 +19937,12 @@ var __webpack_exports__ = {};
|
|
|
19893
19937
|
this.connectionTimeout = window.setTimeout(()=>{
|
|
19894
19938
|
if (this.isOnline() && this.isUserMediaLoaded()) {
|
|
19895
19939
|
this.options.logger.debug(`${PIPE_SYMBOL}Reconnecting due to connection timeout.`);
|
|
19896
|
-
this.
|
|
19897
|
-
|
|
19940
|
+
this.reconnecting = true;
|
|
19941
|
+
this.handleConnectionFailure({
|
|
19942
|
+
url2Connect,
|
|
19943
|
+
cause: "timeout"
|
|
19944
|
+
});
|
|
19945
|
+
} else this.handleConnectionFailure({
|
|
19898
19946
|
url2Connect,
|
|
19899
19947
|
cause: "timeout"
|
|
19900
19948
|
});
|
|
@@ -19909,9 +19957,11 @@ var __webpack_exports__ = {};
|
|
|
19909
19957
|
this.options.logger.debug(debugLine);
|
|
19910
19958
|
const tryReconnect = this.connected && this.userMediaLoaded;
|
|
19911
19959
|
this.connected = false;
|
|
19912
|
-
if (tryReconnect)
|
|
19913
|
-
|
|
19914
|
-
this.
|
|
19960
|
+
if (tryReconnect) {
|
|
19961
|
+
this.reconnecting = true;
|
|
19962
|
+
this.initSocket();
|
|
19963
|
+
} else if (!this.connecting && !this.blocking) window.setTimeout(()=>{
|
|
19964
|
+
this.handleConnectionFailure({
|
|
19915
19965
|
url2Connect,
|
|
19916
19966
|
cause: "closed"
|
|
19917
19967
|
});
|
|
@@ -19925,6 +19975,9 @@ var __webpack_exports__ = {};
|
|
|
19925
19975
|
if (!this.connected && !isClosing && !this.unloaded) {
|
|
19926
19976
|
this.connected = true;
|
|
19927
19977
|
this.connecting = this.unloaded = false;
|
|
19978
|
+
this.reconnecting = false;
|
|
19979
|
+
this.reconnectAttempts = 0;
|
|
19980
|
+
this.clearReconnectTimeout();
|
|
19928
19981
|
this.emit("CONNECTED");
|
|
19929
19982
|
null == cb || cb();
|
|
19930
19983
|
}
|
|
@@ -19955,7 +20008,7 @@ var __webpack_exports__ = {};
|
|
|
19955
20008
|
error: serializeError(err)
|
|
19956
20009
|
});
|
|
19957
20010
|
this.options.logger.debug(debugLine);
|
|
19958
|
-
if (!this.connected) return void this.
|
|
20011
|
+
if (!this.connected) return void this.handleConnectionFailure({
|
|
19959
20012
|
url2Connect,
|
|
19960
20013
|
cause: "error"
|
|
19961
20014
|
});
|
|
@@ -20016,6 +20069,7 @@ var __webpack_exports__ = {};
|
|
|
20016
20069
|
}
|
|
20017
20070
|
userMediaErrorCallback(err, usedConstraints) {
|
|
20018
20071
|
var _this_userMedia;
|
|
20072
|
+
if (this.unloaded) return void this.options.logger.debug(`Recorder: already unloaded. Not going to throw error ${util_pretty(err)}`);
|
|
20019
20073
|
this.userMediaLoading = false;
|
|
20020
20074
|
this.clearUserMediaTimeout();
|
|
20021
20075
|
const characteristics = null == (_this_userMedia = this.userMedia) ? void 0 : _this_userMedia.getCharacteristics();
|
|
@@ -20034,10 +20088,9 @@ var __webpack_exports__ = {};
|
|
|
20034
20088
|
this.options.logger.debug(`Recorder: ignore user media error ${util_pretty(err)}`);
|
|
20035
20089
|
this.retryTimeout = window.setTimeout(()=>{
|
|
20036
20090
|
this.retryTimeout = void 0;
|
|
20037
|
-
this.loadUserMedia();
|
|
20091
|
+
if (!this.unloaded) this.loadUserMedia();
|
|
20038
20092
|
}, this.options.timeouts.userMedia);
|
|
20039
20093
|
}
|
|
20040
|
-
else if (this.unloaded) this.options.logger.debug(`Recorder: already unloaded. Not going to throw error ${util_pretty(err)}`);
|
|
20041
20094
|
else {
|
|
20042
20095
|
this.options.logger.debug(`Recorder: no error listeners attached but throwing error ${util_pretty(err)}`);
|
|
20043
20096
|
throw error_createError({
|
|
@@ -20048,26 +20101,46 @@ var __webpack_exports__ = {};
|
|
|
20048
20101
|
}
|
|
20049
20102
|
}
|
|
20050
20103
|
getUserMediaCallback(localStream, params) {
|
|
20051
|
-
if (!this.userMedia)
|
|
20104
|
+
if (!this.userMedia) {
|
|
20105
|
+
localStream.getTracks().forEach((track)=>{
|
|
20106
|
+
track.stop();
|
|
20107
|
+
});
|
|
20108
|
+
throw error_createError({
|
|
20109
|
+
message: "No user media is defined",
|
|
20110
|
+
options: this.options
|
|
20111
|
+
});
|
|
20112
|
+
}
|
|
20052
20113
|
this.options.logger.debug(`Recorder: getUserMediaCallback(${params ? util_pretty(params) : ""})`);
|
|
20053
20114
|
if (this.showUserMedia()) try {
|
|
20054
|
-
this.clearUserMediaTimeout();
|
|
20055
20115
|
this.userMedia.init(localStream, ()=>{
|
|
20056
|
-
this.onUserMediaReady(params);
|
|
20116
|
+
if (!this.unloaded) this.onUserMediaReady(params);
|
|
20057
20117
|
}, this.onAudioSample.bind(this), (err)=>{
|
|
20058
|
-
this.
|
|
20059
|
-
|
|
20118
|
+
if (!this.unloaded) this.userMediaErrorCallback(err, {
|
|
20119
|
+
audio: isAudioEnabled(this.options)
|
|
20060
20120
|
});
|
|
20061
20121
|
}, null == params ? void 0 : params.switchingFacingMode);
|
|
20062
20122
|
} catch (exc) {
|
|
20123
|
+
localStream.getTracks().forEach((track)=>{
|
|
20124
|
+
track.stop();
|
|
20125
|
+
});
|
|
20126
|
+
this.userMediaLoading = false;
|
|
20127
|
+
this.clearUserMediaTimeout();
|
|
20063
20128
|
this.emit("ERROR", {
|
|
20064
20129
|
exc
|
|
20065
20130
|
});
|
|
20066
20131
|
}
|
|
20132
|
+
else {
|
|
20133
|
+
localStream.getTracks().forEach((track)=>{
|
|
20134
|
+
track.stop();
|
|
20135
|
+
});
|
|
20136
|
+
this.userMediaLoading = false;
|
|
20137
|
+
this.clearUserMediaTimeout();
|
|
20138
|
+
}
|
|
20067
20139
|
}
|
|
20068
20140
|
loadGenuineUserMedia(params) {
|
|
20069
20141
|
this.options.logger.debug(`Recorder: loadGenuineUserMedia(${params ? util_pretty(params) : ""})`);
|
|
20070
20142
|
this.emit("ASKING_WEBCAM_PERMISSION");
|
|
20143
|
+
this.userMediaLoading = true;
|
|
20071
20144
|
const constraints = {
|
|
20072
20145
|
video: {
|
|
20073
20146
|
frameRate: {
|
|
@@ -20098,9 +20171,12 @@ var __webpack_exports__ = {};
|
|
|
20098
20171
|
this.options.logger.debug(util_summarize("Recorder: available webcam constraints are:", navigator.mediaDevices.getSupportedConstraints()));
|
|
20099
20172
|
const streamPromise = navigator.mediaDevices.getUserMedia(constraints);
|
|
20100
20173
|
streamPromise.then((localStream)=>{
|
|
20174
|
+
if (this.unloaded) return void localStream.getTracks().forEach((track)=>{
|
|
20175
|
+
track.stop();
|
|
20176
|
+
});
|
|
20101
20177
|
this.getUserMediaCallback(localStream, params);
|
|
20102
20178
|
}).catch((reason)=>{
|
|
20103
|
-
this.userMediaErrorCallback(reason, constraints);
|
|
20179
|
+
if (!this.unloaded) this.userMediaErrorCallback(reason, constraints);
|
|
20104
20180
|
});
|
|
20105
20181
|
}
|
|
20106
20182
|
loadUserMedia(params) {
|
|
@@ -20114,7 +20190,8 @@ var __webpack_exports__ = {};
|
|
|
20114
20190
|
try {
|
|
20115
20191
|
if (!navigator.mediaDevices) throw new Error("No media devices are available.");
|
|
20116
20192
|
this.userMediaTimeout = window.setTimeout(()=>{
|
|
20117
|
-
if (!this.
|
|
20193
|
+
if (!this.userMediaLoaded) {
|
|
20194
|
+
this.userMediaLoading = false;
|
|
20118
20195
|
const err = util_getBrowser(this.options).getNoAccessIssue();
|
|
20119
20196
|
this.emit("ERROR", {
|
|
20120
20197
|
err
|
|
@@ -20214,16 +20291,16 @@ var __webpack_exports__ = {};
|
|
|
20214
20291
|
command,
|
|
20215
20292
|
args
|
|
20216
20293
|
};
|
|
20217
|
-
this.writeStream(Buffer.from(JSON.stringify(commandObj))
|
|
20218
|
-
|
|
20219
|
-
|
|
20220
|
-
|
|
20294
|
+
this.writeStream(Buffer.from(JSON.stringify(commandObj)), cb ? {
|
|
20295
|
+
onFlushedCallback: ()=>{
|
|
20296
|
+
queueMicrotask(cb);
|
|
20297
|
+
}
|
|
20298
|
+
} : void 0);
|
|
20221
20299
|
}
|
|
20222
20300
|
} else {
|
|
20223
20301
|
this.options.logger.debug(`Reconnecting for the command ${command} …`);
|
|
20224
20302
|
this.initSocket(()=>{
|
|
20225
|
-
this.writeCommand(command, args);
|
|
20226
|
-
null == cb || cb();
|
|
20303
|
+
this.writeCommand(command, args, cb);
|
|
20227
20304
|
});
|
|
20228
20305
|
}
|
|
20229
20306
|
}
|
|
@@ -20298,6 +20375,7 @@ var __webpack_exports__ = {};
|
|
|
20298
20375
|
var _this_userMedia;
|
|
20299
20376
|
this.options.logger.debug("Recorder: reInitializeAudio()");
|
|
20300
20377
|
this.clearUserMediaTimeout();
|
|
20378
|
+
this.userMediaLoading = false;
|
|
20301
20379
|
null == (_this_userMedia = this.userMedia) || _this_userMedia.stop();
|
|
20302
20380
|
this.userMediaLoaded = this.key = this.canvas = this.ctx = void 0;
|
|
20303
20381
|
this.loadUserMedia();
|
|
@@ -20312,17 +20390,17 @@ var __webpack_exports__ = {};
|
|
|
20312
20390
|
this.reset();
|
|
20313
20391
|
this.clearUserMediaTimeout();
|
|
20314
20392
|
this.clearConnectionTimeout();
|
|
20393
|
+
this.clearReconnectTimeout();
|
|
20315
20394
|
this.clearRetryTimeout();
|
|
20316
20395
|
this.clearStopTimeout();
|
|
20317
20396
|
this.stopPings();
|
|
20397
|
+
this.userMediaLoading = false;
|
|
20318
20398
|
this.connecting = false;
|
|
20399
|
+
this.reconnecting = false;
|
|
20400
|
+
this.reconnectAttempts = 0;
|
|
20319
20401
|
if (this.userMedia) this.userMedia.unloadRemainingEventListeners();
|
|
20320
20402
|
if (this.submitting) ;
|
|
20321
|
-
else if (this.stream)
|
|
20322
|
-
this.options.logger.debug("Recorder: destroying stream ...");
|
|
20323
|
-
this.stream.destroy();
|
|
20324
|
-
this.stream = void 0;
|
|
20325
|
-
}
|
|
20403
|
+
else if (this.stream) this.discardSocket();
|
|
20326
20404
|
this.unloaded = true;
|
|
20327
20405
|
this.built = this.connecting = this.connected = false;
|
|
20328
20406
|
}
|
|
@@ -20427,7 +20505,13 @@ var __webpack_exports__ = {};
|
|
|
20427
20505
|
if (!this.connected) {
|
|
20428
20506
|
this.options.logger.debug("Recorder: reconnecting before recording …");
|
|
20429
20507
|
this.initSocket(()=>{
|
|
20430
|
-
this.once("
|
|
20508
|
+
this.once("SERVER_READY", ()=>{
|
|
20509
|
+
if (this.unloaded) return;
|
|
20510
|
+
if (this.userMediaLoaded || this.options.loadUserMediaOnRecord) this.record();
|
|
20511
|
+
else this.once("USER_MEDIA_READY", ()=>{
|
|
20512
|
+
if (!this.unloaded) this.record();
|
|
20513
|
+
});
|
|
20514
|
+
});
|
|
20431
20515
|
});
|
|
20432
20516
|
return;
|
|
20433
20517
|
}
|
|
@@ -20732,7 +20816,7 @@ var __webpack_exports__ = {};
|
|
|
20732
20816
|
return this.userMediaLoaded;
|
|
20733
20817
|
}
|
|
20734
20818
|
constructor(visuals, replay, options){
|
|
20735
|
-
super("Recorder", options), recorder_define_property(this, "visuals", void 0), recorder_define_property(this, "replay", void 0), 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, "connectionTimeout", 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, "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, "connecting", false), recorder_define_property(this, "connected", false), recorder_define_property(this, "connectionFailed", false), 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);
|
|
20819
|
+
super("Recorder", options), recorder_define_property(this, "visuals", void 0), recorder_define_property(this, "replay", void 0), 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, "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, "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, "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);
|
|
20736
20820
|
this.visuals = visuals;
|
|
20737
20821
|
this.replay = replay;
|
|
20738
20822
|
this.facingMode = options.video.facingMode;
|
package/dist/esm/index.js
CHANGED
|
@@ -3620,7 +3620,7 @@ const constants = {
|
|
|
3620
3620
|
}
|
|
3621
3621
|
};
|
|
3622
3622
|
var package_namespaceObject = {
|
|
3623
|
-
rE: "15.
|
|
3623
|
+
rE: "15.9.0"
|
|
3624
3624
|
};
|
|
3625
3625
|
function isAudioEnabled(options) {
|
|
3626
3626
|
return Boolean(options.audio.enabled);
|
|
@@ -6232,7 +6232,7 @@ class AudioRecorder {
|
|
|
6232
6232
|
}
|
|
6233
6233
|
let { bufferSize } = this.options.audio;
|
|
6234
6234
|
if ("auto" === bufferSize) bufferSize = util_getBrowser(this.options).isFirefox() ? 512 : 2048;
|
|
6235
|
-
if (!is_power_of_two(bufferSize)) throw error_createError({
|
|
6235
|
+
if (void 0 === bufferSize || !is_power_of_two(bufferSize)) throw error_createError({
|
|
6236
6236
|
message: `Audio buffer size must be a power of two. The current buffer size is ${bufferSize}.`,
|
|
6237
6237
|
options: this.options
|
|
6238
6238
|
});
|
|
@@ -6311,9 +6311,14 @@ function userMedia_define_property(obj, key, value) {
|
|
|
6311
6311
|
const EVENT_ASCII = "|—O—|";
|
|
6312
6312
|
class UserMedia extends util_Despot {
|
|
6313
6313
|
attachMediaStream(stream) {
|
|
6314
|
-
this.
|
|
6315
|
-
|
|
6316
|
-
|
|
6314
|
+
if (this.rawVisualUserMedia) {
|
|
6315
|
+
this.rawVisualUserMedia.srcObject = stream;
|
|
6316
|
+
const previousStream = this.currentVisualStream;
|
|
6317
|
+
this.currentVisualStream = stream;
|
|
6318
|
+
if (previousStream && previousStream !== stream) previousStream.getTracks().forEach((track)=>{
|
|
6319
|
+
track.stop();
|
|
6320
|
+
});
|
|
6321
|
+
} else throw error_createError({
|
|
6317
6322
|
message: "Error attaching stream to element.",
|
|
6318
6323
|
explanation: "Contact the developer about this",
|
|
6319
6324
|
options: this.options
|
|
@@ -6381,11 +6386,14 @@ class UserMedia extends util_Despot {
|
|
|
6381
6386
|
}
|
|
6382
6387
|
}).catch((exc)=>{
|
|
6383
6388
|
if (exc instanceof Error) this.options.logger.warn(`Caught pending user media promise exception: ${exc.toString()}`);
|
|
6384
|
-
else
|
|
6385
|
-
|
|
6386
|
-
|
|
6387
|
-
|
|
6388
|
-
|
|
6389
|
+
else {
|
|
6390
|
+
unloadAllEventListeners();
|
|
6391
|
+
endedEarlyCallback(error_createError({
|
|
6392
|
+
message: "Failed to play user media upon play event.",
|
|
6393
|
+
exc,
|
|
6394
|
+
options: this.options
|
|
6395
|
+
}));
|
|
6396
|
+
}
|
|
6389
6397
|
});
|
|
6390
6398
|
}
|
|
6391
6399
|
} catch (exc) {
|
|
@@ -6396,18 +6404,18 @@ class UserMedia extends util_Despot {
|
|
|
6396
6404
|
const fireCallbacks = ()=>{
|
|
6397
6405
|
const readyState = this.rawVisualUserMedia?.readyState;
|
|
6398
6406
|
this.options.logger.debug(`UserMedia: fireCallbacks(readyState=${readyState}, onPlayReached=${this.onPlayReached}, onLoadedMetaDataReached=${this.onLoadedMetaDataReached})`);
|
|
6399
|
-
if (this.onPlayReached && this.onLoadedMetaDataReached) {
|
|
6407
|
+
if (this.onPlayReached && this.onLoadedMetaDataReached) if (this.audioRecorder) try {
|
|
6408
|
+
this.audioRecorder.init(localMediaStream);
|
|
6409
|
+
this.on("SENDING_FIRST_FRAME", ()=>{
|
|
6410
|
+
this.audioRecord(audioCallback);
|
|
6411
|
+
});
|
|
6400
6412
|
videoCallback();
|
|
6401
|
-
|
|
6402
|
-
|
|
6403
|
-
|
|
6404
|
-
|
|
6405
|
-
});
|
|
6406
|
-
} catch (exc) {
|
|
6407
|
-
unloadAllEventListeners();
|
|
6408
|
-
endedEarlyCallback(exc);
|
|
6409
|
-
}
|
|
6413
|
+
} catch (exc) {
|
|
6414
|
+
unloadAllEventListeners();
|
|
6415
|
+
this.stop();
|
|
6416
|
+
endedEarlyCallback(exc);
|
|
6410
6417
|
}
|
|
6418
|
+
else videoCallback();
|
|
6411
6419
|
};
|
|
6412
6420
|
const onPlay = ()=>{
|
|
6413
6421
|
try {
|
|
@@ -6713,6 +6721,37 @@ class Recorder extends util_Despot {
|
|
|
6713
6721
|
window.clearTimeout(this.connectionTimeout);
|
|
6714
6722
|
this.connectionTimeout = void 0;
|
|
6715
6723
|
}
|
|
6724
|
+
clearReconnectTimeout() {
|
|
6725
|
+
if (void 0 === this.reconnectTimeout) return;
|
|
6726
|
+
this.options.logger.debug("Recorder: clearReconnectTimeout()");
|
|
6727
|
+
window.clearTimeout(this.reconnectTimeout);
|
|
6728
|
+
this.reconnectTimeout = void 0;
|
|
6729
|
+
}
|
|
6730
|
+
handleConnectionFailure(params) {
|
|
6731
|
+
if (this.retryConnection(params)) return;
|
|
6732
|
+
this.failConnection(params);
|
|
6733
|
+
}
|
|
6734
|
+
retryConnection(params) {
|
|
6735
|
+
if (!this.reconnecting || !this.userMediaLoaded || !this.isOnline() || this.unloaded || this.blocking) return false;
|
|
6736
|
+
if (void 0 !== this.reconnectTimeout) return true;
|
|
6737
|
+
const delayMs = Math.min(500 * 2 ** this.reconnectAttempts, 10000);
|
|
6738
|
+
this.reconnectAttempts++;
|
|
6739
|
+
this.connecting = false;
|
|
6740
|
+
this.clearConnectionTimeout();
|
|
6741
|
+
this.discardSocket();
|
|
6742
|
+
this.options.logger.debug(`Recorder: WebSocket reconnect failed (${params.cause}); retrying in ${delayMs}ms.`);
|
|
6743
|
+
this.reconnectTimeout = window.setTimeout(()=>{
|
|
6744
|
+
this.reconnectTimeout = void 0;
|
|
6745
|
+
if (this.reconnecting && !this.unloaded && !this.blocking) this.initSocket();
|
|
6746
|
+
}, delayMs);
|
|
6747
|
+
return true;
|
|
6748
|
+
}
|
|
6749
|
+
discardSocket() {
|
|
6750
|
+
this.options.logger.debug("Recorder: discarding socket stream ...");
|
|
6751
|
+
const stream = this.stream;
|
|
6752
|
+
this.stream = void 0;
|
|
6753
|
+
if (stream && !stream.destroyed) stream.destroy();
|
|
6754
|
+
}
|
|
6716
6755
|
isOnline() {
|
|
6717
6756
|
return navigator.onLine;
|
|
6718
6757
|
}
|
|
@@ -6720,6 +6759,9 @@ class Recorder extends util_Despot {
|
|
|
6720
6759
|
if (this.connectionFailed || this.connected || this.unloaded) return;
|
|
6721
6760
|
this.connectionFailed = true;
|
|
6722
6761
|
this.connecting = false;
|
|
6762
|
+
this.reconnecting = false;
|
|
6763
|
+
this.reconnectAttempts = 0;
|
|
6764
|
+
this.clearReconnectTimeout();
|
|
6723
6765
|
this.clearConnectionTimeout();
|
|
6724
6766
|
const { url2Connect, cause } = params;
|
|
6725
6767
|
const online = this.isOnline();
|
|
@@ -6754,10 +6796,7 @@ class Recorder extends util_Despot {
|
|
|
6754
6796
|
explanation = `Connection to ${url2Connect} is closed${closeSuffix}. Please check your internet connection and try again. If the problem persists, contact us.`;
|
|
6755
6797
|
}
|
|
6756
6798
|
else explanation = "Your device appears to be offline. Please check your internet connection and try again.";
|
|
6757
|
-
|
|
6758
|
-
this.stream.destroy();
|
|
6759
|
-
this.stream = void 0;
|
|
6760
|
-
}
|
|
6799
|
+
this.discardSocket();
|
|
6761
6800
|
const err = error_createError({
|
|
6762
6801
|
message: "Unable to connect to the server",
|
|
6763
6802
|
explanation,
|
|
@@ -6840,8 +6879,13 @@ class Recorder extends util_Despot {
|
|
|
6840
6879
|
this.recordingStats.waitingTime = this.waitingTime;
|
|
6841
6880
|
}
|
|
6842
6881
|
initSocket(cb) {
|
|
6843
|
-
if (this.connected)
|
|
6844
|
-
|
|
6882
|
+
if (this.connected) {
|
|
6883
|
+
this.options.logger.debug("Recorder: already **connected**. Not going to initialize a new WebSocket connection.");
|
|
6884
|
+
cb?.();
|
|
6885
|
+
return;
|
|
6886
|
+
}
|
|
6887
|
+
if (this.connecting) return void this.options.logger.debug("Recorder: already **connecting**. Not going to initialize a new WebSocket connection.");
|
|
6888
|
+
this.clearReconnectTimeout();
|
|
6845
6889
|
if (util_isAutomatedUserAgent()) {
|
|
6846
6890
|
this.connecting = false;
|
|
6847
6891
|
this.options.logger.debug("Recorder: skipping web socket connection for an automated crawler");
|
|
@@ -6920,8 +6964,12 @@ class Recorder extends util_Despot {
|
|
|
6920
6964
|
this.connectionTimeout = window.setTimeout(()=>{
|
|
6921
6965
|
if (this.isOnline() && this.isUserMediaLoaded()) {
|
|
6922
6966
|
this.options.logger.debug(`${PIPE_SYMBOL}Reconnecting due to connection timeout.`);
|
|
6923
|
-
this.
|
|
6924
|
-
|
|
6967
|
+
this.reconnecting = true;
|
|
6968
|
+
this.handleConnectionFailure({
|
|
6969
|
+
url2Connect,
|
|
6970
|
+
cause: "timeout"
|
|
6971
|
+
});
|
|
6972
|
+
} else this.handleConnectionFailure({
|
|
6925
6973
|
url2Connect,
|
|
6926
6974
|
cause: "timeout"
|
|
6927
6975
|
});
|
|
@@ -6936,9 +6984,11 @@ class Recorder extends util_Despot {
|
|
|
6936
6984
|
this.options.logger.debug(debugLine);
|
|
6937
6985
|
const tryReconnect = this.connected && this.userMediaLoaded;
|
|
6938
6986
|
this.connected = false;
|
|
6939
|
-
if (tryReconnect)
|
|
6940
|
-
|
|
6941
|
-
this.
|
|
6987
|
+
if (tryReconnect) {
|
|
6988
|
+
this.reconnecting = true;
|
|
6989
|
+
this.initSocket();
|
|
6990
|
+
} else if (!this.connecting && !this.blocking) window.setTimeout(()=>{
|
|
6991
|
+
this.handleConnectionFailure({
|
|
6942
6992
|
url2Connect,
|
|
6943
6993
|
cause: "closed"
|
|
6944
6994
|
});
|
|
@@ -6951,6 +7001,9 @@ class Recorder extends util_Despot {
|
|
|
6951
7001
|
if (!this.connected && !isClosing && !this.unloaded) {
|
|
6952
7002
|
this.connected = true;
|
|
6953
7003
|
this.connecting = this.unloaded = false;
|
|
7004
|
+
this.reconnecting = false;
|
|
7005
|
+
this.reconnectAttempts = 0;
|
|
7006
|
+
this.clearReconnectTimeout();
|
|
6954
7007
|
this.emit("CONNECTED");
|
|
6955
7008
|
cb?.();
|
|
6956
7009
|
}
|
|
@@ -6980,7 +7033,7 @@ class Recorder extends util_Despot {
|
|
|
6980
7033
|
error: serializeError(err)
|
|
6981
7034
|
});
|
|
6982
7035
|
this.options.logger.debug(debugLine);
|
|
6983
|
-
if (!this.connected) return void this.
|
|
7036
|
+
if (!this.connected) return void this.handleConnectionFailure({
|
|
6984
7037
|
url2Connect,
|
|
6985
7038
|
cause: "error"
|
|
6986
7039
|
});
|
|
@@ -7040,6 +7093,7 @@ class Recorder extends util_Despot {
|
|
|
7040
7093
|
return this.blocking;
|
|
7041
7094
|
}
|
|
7042
7095
|
userMediaErrorCallback(err, usedConstraints) {
|
|
7096
|
+
if (this.unloaded) return void this.options.logger.debug(`Recorder: already unloaded. Not going to throw error ${util_pretty(err)}`);
|
|
7043
7097
|
this.userMediaLoading = false;
|
|
7044
7098
|
this.clearUserMediaTimeout();
|
|
7045
7099
|
const characteristics = this.userMedia?.getCharacteristics();
|
|
@@ -7058,10 +7112,9 @@ class Recorder extends util_Despot {
|
|
|
7058
7112
|
this.options.logger.debug(`Recorder: ignore user media error ${util_pretty(err)}`);
|
|
7059
7113
|
this.retryTimeout = window.setTimeout(()=>{
|
|
7060
7114
|
this.retryTimeout = void 0;
|
|
7061
|
-
this.loadUserMedia();
|
|
7115
|
+
if (!this.unloaded) this.loadUserMedia();
|
|
7062
7116
|
}, this.options.timeouts.userMedia);
|
|
7063
7117
|
}
|
|
7064
|
-
else if (this.unloaded) this.options.logger.debug(`Recorder: already unloaded. Not going to throw error ${util_pretty(err)}`);
|
|
7065
7118
|
else {
|
|
7066
7119
|
this.options.logger.debug(`Recorder: no error listeners attached but throwing error ${util_pretty(err)}`);
|
|
7067
7120
|
throw error_createError({
|
|
@@ -7072,26 +7125,46 @@ class Recorder extends util_Despot {
|
|
|
7072
7125
|
}
|
|
7073
7126
|
}
|
|
7074
7127
|
getUserMediaCallback(localStream, params) {
|
|
7075
|
-
if (!this.userMedia)
|
|
7128
|
+
if (!this.userMedia) {
|
|
7129
|
+
localStream.getTracks().forEach((track)=>{
|
|
7130
|
+
track.stop();
|
|
7131
|
+
});
|
|
7132
|
+
throw error_createError({
|
|
7133
|
+
message: "No user media is defined",
|
|
7134
|
+
options: this.options
|
|
7135
|
+
});
|
|
7136
|
+
}
|
|
7076
7137
|
this.options.logger.debug(`Recorder: getUserMediaCallback(${params ? util_pretty(params) : ""})`);
|
|
7077
7138
|
if (this.showUserMedia()) try {
|
|
7078
|
-
this.clearUserMediaTimeout();
|
|
7079
7139
|
this.userMedia.init(localStream, ()=>{
|
|
7080
|
-
this.onUserMediaReady(params);
|
|
7140
|
+
if (!this.unloaded) this.onUserMediaReady(params);
|
|
7081
7141
|
}, this.onAudioSample.bind(this), (err)=>{
|
|
7082
|
-
this.
|
|
7083
|
-
|
|
7142
|
+
if (!this.unloaded) this.userMediaErrorCallback(err, {
|
|
7143
|
+
audio: isAudioEnabled(this.options)
|
|
7084
7144
|
});
|
|
7085
7145
|
}, params?.switchingFacingMode);
|
|
7086
7146
|
} catch (exc) {
|
|
7147
|
+
localStream.getTracks().forEach((track)=>{
|
|
7148
|
+
track.stop();
|
|
7149
|
+
});
|
|
7150
|
+
this.userMediaLoading = false;
|
|
7151
|
+
this.clearUserMediaTimeout();
|
|
7087
7152
|
this.emit("ERROR", {
|
|
7088
7153
|
exc
|
|
7089
7154
|
});
|
|
7090
7155
|
}
|
|
7156
|
+
else {
|
|
7157
|
+
localStream.getTracks().forEach((track)=>{
|
|
7158
|
+
track.stop();
|
|
7159
|
+
});
|
|
7160
|
+
this.userMediaLoading = false;
|
|
7161
|
+
this.clearUserMediaTimeout();
|
|
7162
|
+
}
|
|
7091
7163
|
}
|
|
7092
7164
|
loadGenuineUserMedia(params) {
|
|
7093
7165
|
this.options.logger.debug(`Recorder: loadGenuineUserMedia(${params ? util_pretty(params) : ""})`);
|
|
7094
7166
|
this.emit("ASKING_WEBCAM_PERMISSION");
|
|
7167
|
+
this.userMediaLoading = true;
|
|
7095
7168
|
const constraints = {
|
|
7096
7169
|
video: {
|
|
7097
7170
|
frameRate: {
|
|
@@ -7122,9 +7195,12 @@ class Recorder extends util_Despot {
|
|
|
7122
7195
|
this.options.logger.debug(util_summarize("Recorder: available webcam constraints are:", navigator.mediaDevices.getSupportedConstraints()));
|
|
7123
7196
|
const streamPromise = navigator.mediaDevices.getUserMedia(constraints);
|
|
7124
7197
|
streamPromise.then((localStream)=>{
|
|
7198
|
+
if (this.unloaded) return void localStream.getTracks().forEach((track)=>{
|
|
7199
|
+
track.stop();
|
|
7200
|
+
});
|
|
7125
7201
|
this.getUserMediaCallback(localStream, params);
|
|
7126
7202
|
}).catch((reason)=>{
|
|
7127
|
-
this.userMediaErrorCallback(reason, constraints);
|
|
7203
|
+
if (!this.unloaded) this.userMediaErrorCallback(reason, constraints);
|
|
7128
7204
|
});
|
|
7129
7205
|
}
|
|
7130
7206
|
loadUserMedia(params) {
|
|
@@ -7138,7 +7214,8 @@ class Recorder extends util_Despot {
|
|
|
7138
7214
|
try {
|
|
7139
7215
|
if (!navigator.mediaDevices) throw new Error("No media devices are available.");
|
|
7140
7216
|
this.userMediaTimeout = window.setTimeout(()=>{
|
|
7141
|
-
if (!this.
|
|
7217
|
+
if (!this.userMediaLoaded) {
|
|
7218
|
+
this.userMediaLoading = false;
|
|
7142
7219
|
const err = util_getBrowser(this.options).getNoAccessIssue();
|
|
7143
7220
|
this.emit("ERROR", {
|
|
7144
7221
|
err
|
|
@@ -7237,16 +7314,16 @@ class Recorder extends util_Despot {
|
|
|
7237
7314
|
command,
|
|
7238
7315
|
args
|
|
7239
7316
|
};
|
|
7240
|
-
this.writeStream(Buffer.from(JSON.stringify(commandObj))
|
|
7241
|
-
|
|
7242
|
-
|
|
7243
|
-
|
|
7317
|
+
this.writeStream(Buffer.from(JSON.stringify(commandObj)), cb ? {
|
|
7318
|
+
onFlushedCallback: ()=>{
|
|
7319
|
+
queueMicrotask(cb);
|
|
7320
|
+
}
|
|
7321
|
+
} : void 0);
|
|
7244
7322
|
}
|
|
7245
7323
|
} else {
|
|
7246
7324
|
this.options.logger.debug(`Reconnecting for the command ${command} …`);
|
|
7247
7325
|
this.initSocket(()=>{
|
|
7248
|
-
this.writeCommand(command, args);
|
|
7249
|
-
cb?.();
|
|
7326
|
+
this.writeCommand(command, args, cb);
|
|
7250
7327
|
});
|
|
7251
7328
|
}
|
|
7252
7329
|
}
|
|
@@ -7317,6 +7394,7 @@ class Recorder extends util_Despot {
|
|
|
7317
7394
|
reInitializeAudio() {
|
|
7318
7395
|
this.options.logger.debug("Recorder: reInitializeAudio()");
|
|
7319
7396
|
this.clearUserMediaTimeout();
|
|
7397
|
+
this.userMediaLoading = false;
|
|
7320
7398
|
this.userMedia?.stop();
|
|
7321
7399
|
this.userMediaLoaded = this.key = this.canvas = this.ctx = void 0;
|
|
7322
7400
|
this.loadUserMedia();
|
|
@@ -7331,17 +7409,17 @@ class Recorder extends util_Despot {
|
|
|
7331
7409
|
this.reset();
|
|
7332
7410
|
this.clearUserMediaTimeout();
|
|
7333
7411
|
this.clearConnectionTimeout();
|
|
7412
|
+
this.clearReconnectTimeout();
|
|
7334
7413
|
this.clearRetryTimeout();
|
|
7335
7414
|
this.clearStopTimeout();
|
|
7336
7415
|
this.stopPings();
|
|
7416
|
+
this.userMediaLoading = false;
|
|
7337
7417
|
this.connecting = false;
|
|
7418
|
+
this.reconnecting = false;
|
|
7419
|
+
this.reconnectAttempts = 0;
|
|
7338
7420
|
if (this.userMedia) this.userMedia.unloadRemainingEventListeners();
|
|
7339
7421
|
if (this.submitting) ;
|
|
7340
|
-
else if (this.stream)
|
|
7341
|
-
this.options.logger.debug("Recorder: destroying stream ...");
|
|
7342
|
-
this.stream.destroy();
|
|
7343
|
-
this.stream = void 0;
|
|
7344
|
-
}
|
|
7422
|
+
else if (this.stream) this.discardSocket();
|
|
7345
7423
|
this.unloaded = true;
|
|
7346
7424
|
this.built = this.connecting = this.connected = false;
|
|
7347
7425
|
}
|
|
@@ -7441,7 +7519,13 @@ class Recorder extends util_Despot {
|
|
|
7441
7519
|
if (!this.connected) {
|
|
7442
7520
|
this.options.logger.debug("Recorder: reconnecting before recording …");
|
|
7443
7521
|
this.initSocket(()=>{
|
|
7444
|
-
this.once("
|
|
7522
|
+
this.once("SERVER_READY", ()=>{
|
|
7523
|
+
if (this.unloaded) return;
|
|
7524
|
+
if (this.userMediaLoaded || this.options.loadUserMediaOnRecord) this.record();
|
|
7525
|
+
else this.once("USER_MEDIA_READY", ()=>{
|
|
7526
|
+
if (!this.unloaded) this.record();
|
|
7527
|
+
});
|
|
7528
|
+
});
|
|
7445
7529
|
});
|
|
7446
7530
|
return;
|
|
7447
7531
|
}
|
|
@@ -7742,7 +7826,7 @@ class Recorder extends util_Despot {
|
|
|
7742
7826
|
return this.userMediaLoaded;
|
|
7743
7827
|
}
|
|
7744
7828
|
constructor(visuals, replay, options){
|
|
7745
|
-
super("Recorder", options), recorder_define_property(this, "visuals", void 0), recorder_define_property(this, "replay", void 0), 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, "connectionTimeout", 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, "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, "connecting", false), recorder_define_property(this, "connected", false), recorder_define_property(this, "connectionFailed", false), 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);
|
|
7829
|
+
super("Recorder", options), recorder_define_property(this, "visuals", void 0), recorder_define_property(this, "replay", void 0), 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, "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, "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, "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);
|
|
7746
7830
|
this.visuals = visuals;
|
|
7747
7831
|
this.replay = replay;
|
|
7748
7832
|
this.facingMode = options.video.facingMode;
|
|
@@ -25,6 +25,7 @@ declare class Recorder extends Despot {
|
|
|
25
25
|
private userMedia?;
|
|
26
26
|
private userMediaTimeout?;
|
|
27
27
|
private retryTimeout?;
|
|
28
|
+
private reconnectTimeout?;
|
|
28
29
|
private connectionTimeout?;
|
|
29
30
|
private stopTimeout?;
|
|
30
31
|
private frameProgress?;
|
|
@@ -40,6 +41,8 @@ declare class Recorder extends Despot {
|
|
|
40
41
|
private connecting;
|
|
41
42
|
private connected;
|
|
42
43
|
private connectionFailed;
|
|
44
|
+
private reconnecting;
|
|
45
|
+
private reconnectAttempts;
|
|
43
46
|
private blocking;
|
|
44
47
|
private built;
|
|
45
48
|
private key?;
|
|
@@ -60,6 +63,10 @@ declare class Recorder extends Despot {
|
|
|
60
63
|
private onUserMediaReady;
|
|
61
64
|
private clearRetryTimeout;
|
|
62
65
|
private clearConnectionTimeout;
|
|
66
|
+
private clearReconnectTimeout;
|
|
67
|
+
private handleConnectionFailure;
|
|
68
|
+
private retryConnection;
|
|
69
|
+
private discardSocket;
|
|
63
70
|
private isOnline;
|
|
64
71
|
private failConnection;
|
|
65
72
|
private calculateFrameProgress;
|
package/dist/umd/index.js
CHANGED
|
@@ -10978,7 +10978,7 @@
|
|
|
10978
10978
|
var client = __webpack_require__("Q");
|
|
10979
10979
|
var client_default = /*#__PURE__*/ __webpack_require__.n(client);
|
|
10980
10980
|
var package_namespaceObject = {
|
|
10981
|
-
rE: "15.
|
|
10981
|
+
rE: "15.9.0"
|
|
10982
10982
|
};
|
|
10983
10983
|
function isAudioEnabled(options) {
|
|
10984
10984
|
return Boolean(options.audio.enabled);
|
|
@@ -18953,7 +18953,7 @@
|
|
|
18953
18953
|
}
|
|
18954
18954
|
let { bufferSize } = this.options.audio;
|
|
18955
18955
|
if ("auto" === bufferSize) bufferSize = util_getBrowser(this.options).isFirefox() ? 512 : 2048;
|
|
18956
|
-
if (!is_power_of_two_default()(bufferSize)) throw error_createError({
|
|
18956
|
+
if (void 0 === bufferSize || !is_power_of_two_default()(bufferSize)) throw error_createError({
|
|
18957
18957
|
message: `Audio buffer size must be a power of two. The current buffer size is ${bufferSize}.`,
|
|
18958
18958
|
options: this.options
|
|
18959
18959
|
});
|
|
@@ -19040,9 +19040,14 @@
|
|
|
19040
19040
|
});
|
|
19041
19041
|
}
|
|
19042
19042
|
attachMediaStream(stream) {
|
|
19043
|
-
this.
|
|
19044
|
-
|
|
19045
|
-
|
|
19043
|
+
if (this.rawVisualUserMedia) {
|
|
19044
|
+
this.rawVisualUserMedia.srcObject = stream;
|
|
19045
|
+
const previousStream = this.currentVisualStream;
|
|
19046
|
+
this.currentVisualStream = stream;
|
|
19047
|
+
if (previousStream && previousStream !== stream) previousStream.getTracks().forEach((track)=>{
|
|
19048
|
+
track.stop();
|
|
19049
|
+
});
|
|
19050
|
+
} else throw error_createError({
|
|
19046
19051
|
message: "Error attaching stream to element.",
|
|
19047
19052
|
explanation: "Contact the developer about this",
|
|
19048
19053
|
options: this.options
|
|
@@ -19110,11 +19115,14 @@
|
|
|
19110
19115
|
}
|
|
19111
19116
|
}).catch((exc)=>{
|
|
19112
19117
|
if (exc instanceof Error) this.options.logger.warn(`Caught pending user media promise exception: ${exc.toString()}`);
|
|
19113
|
-
else
|
|
19114
|
-
|
|
19115
|
-
|
|
19116
|
-
|
|
19117
|
-
|
|
19118
|
+
else {
|
|
19119
|
+
unloadAllEventListeners();
|
|
19120
|
+
endedEarlyCallback(error_createError({
|
|
19121
|
+
message: "Failed to play user media upon play event.",
|
|
19122
|
+
exc,
|
|
19123
|
+
options: this.options
|
|
19124
|
+
}));
|
|
19125
|
+
}
|
|
19118
19126
|
});
|
|
19119
19127
|
}
|
|
19120
19128
|
} catch (exc) {
|
|
@@ -19125,18 +19133,18 @@
|
|
|
19125
19133
|
const fireCallbacks = ()=>{
|
|
19126
19134
|
const readyState = this.rawVisualUserMedia?.readyState;
|
|
19127
19135
|
this.options.logger.debug(`UserMedia: fireCallbacks(readyState=${readyState}, onPlayReached=${this.onPlayReached}, onLoadedMetaDataReached=${this.onLoadedMetaDataReached})`);
|
|
19128
|
-
if (this.onPlayReached && this.onLoadedMetaDataReached) {
|
|
19136
|
+
if (this.onPlayReached && this.onLoadedMetaDataReached) if (this.audioRecorder) try {
|
|
19137
|
+
this.audioRecorder.init(localMediaStream);
|
|
19138
|
+
this.on("SENDING_FIRST_FRAME", ()=>{
|
|
19139
|
+
this.audioRecord(audioCallback);
|
|
19140
|
+
});
|
|
19129
19141
|
videoCallback();
|
|
19130
|
-
|
|
19131
|
-
|
|
19132
|
-
|
|
19133
|
-
|
|
19134
|
-
});
|
|
19135
|
-
} catch (exc) {
|
|
19136
|
-
unloadAllEventListeners();
|
|
19137
|
-
endedEarlyCallback(exc);
|
|
19138
|
-
}
|
|
19142
|
+
} catch (exc) {
|
|
19143
|
+
unloadAllEventListeners();
|
|
19144
|
+
this.stop();
|
|
19145
|
+
endedEarlyCallback(exc);
|
|
19139
19146
|
}
|
|
19147
|
+
else videoCallback();
|
|
19140
19148
|
};
|
|
19141
19149
|
const onPlay = ()=>{
|
|
19142
19150
|
try {
|
|
@@ -19334,6 +19342,7 @@
|
|
|
19334
19342
|
userMedia;
|
|
19335
19343
|
userMediaTimeout;
|
|
19336
19344
|
retryTimeout;
|
|
19345
|
+
reconnectTimeout;
|
|
19337
19346
|
connectionTimeout;
|
|
19338
19347
|
stopTimeout;
|
|
19339
19348
|
frameProgress;
|
|
@@ -19349,6 +19358,8 @@
|
|
|
19349
19358
|
connecting = false;
|
|
19350
19359
|
connected = false;
|
|
19351
19360
|
connectionFailed = false;
|
|
19361
|
+
reconnecting = false;
|
|
19362
|
+
reconnectAttempts = 0;
|
|
19352
19363
|
blocking = false;
|
|
19353
19364
|
built = false;
|
|
19354
19365
|
key;
|
|
@@ -19462,6 +19473,37 @@
|
|
|
19462
19473
|
window.clearTimeout(this.connectionTimeout);
|
|
19463
19474
|
this.connectionTimeout = void 0;
|
|
19464
19475
|
}
|
|
19476
|
+
clearReconnectTimeout() {
|
|
19477
|
+
if (void 0 === this.reconnectTimeout) return;
|
|
19478
|
+
this.options.logger.debug("Recorder: clearReconnectTimeout()");
|
|
19479
|
+
window.clearTimeout(this.reconnectTimeout);
|
|
19480
|
+
this.reconnectTimeout = void 0;
|
|
19481
|
+
}
|
|
19482
|
+
handleConnectionFailure(params) {
|
|
19483
|
+
if (this.retryConnection(params)) return;
|
|
19484
|
+
this.failConnection(params);
|
|
19485
|
+
}
|
|
19486
|
+
retryConnection(params) {
|
|
19487
|
+
if (!this.reconnecting || !this.userMediaLoaded || !this.isOnline() || this.unloaded || this.blocking) return false;
|
|
19488
|
+
if (void 0 !== this.reconnectTimeout) return true;
|
|
19489
|
+
const delayMs = Math.min(500 * 2 ** this.reconnectAttempts, 10000);
|
|
19490
|
+
this.reconnectAttempts++;
|
|
19491
|
+
this.connecting = false;
|
|
19492
|
+
this.clearConnectionTimeout();
|
|
19493
|
+
this.discardSocket();
|
|
19494
|
+
this.options.logger.debug(`Recorder: WebSocket reconnect failed (${params.cause}); retrying in ${delayMs}ms.`);
|
|
19495
|
+
this.reconnectTimeout = window.setTimeout(()=>{
|
|
19496
|
+
this.reconnectTimeout = void 0;
|
|
19497
|
+
if (this.reconnecting && !this.unloaded && !this.blocking) this.initSocket();
|
|
19498
|
+
}, delayMs);
|
|
19499
|
+
return true;
|
|
19500
|
+
}
|
|
19501
|
+
discardSocket() {
|
|
19502
|
+
this.options.logger.debug("Recorder: discarding socket stream ...");
|
|
19503
|
+
const stream = this.stream;
|
|
19504
|
+
this.stream = void 0;
|
|
19505
|
+
if (stream && !stream.destroyed) stream.destroy();
|
|
19506
|
+
}
|
|
19465
19507
|
isOnline() {
|
|
19466
19508
|
return navigator.onLine;
|
|
19467
19509
|
}
|
|
@@ -19469,6 +19511,9 @@
|
|
|
19469
19511
|
if (this.connectionFailed || this.connected || this.unloaded) return;
|
|
19470
19512
|
this.connectionFailed = true;
|
|
19471
19513
|
this.connecting = false;
|
|
19514
|
+
this.reconnecting = false;
|
|
19515
|
+
this.reconnectAttempts = 0;
|
|
19516
|
+
this.clearReconnectTimeout();
|
|
19472
19517
|
this.clearConnectionTimeout();
|
|
19473
19518
|
const { url2Connect, cause } = params;
|
|
19474
19519
|
const online = this.isOnline();
|
|
@@ -19503,10 +19548,7 @@
|
|
|
19503
19548
|
explanation = `Connection to ${url2Connect} is closed${closeSuffix}. Please check your internet connection and try again. If the problem persists, contact us.`;
|
|
19504
19549
|
}
|
|
19505
19550
|
else explanation = "Your device appears to be offline. Please check your internet connection and try again.";
|
|
19506
|
-
|
|
19507
|
-
this.stream.destroy();
|
|
19508
|
-
this.stream = void 0;
|
|
19509
|
-
}
|
|
19551
|
+
this.discardSocket();
|
|
19510
19552
|
const err = error_createError({
|
|
19511
19553
|
message: "Unable to connect to the server",
|
|
19512
19554
|
explanation,
|
|
@@ -19589,8 +19631,13 @@
|
|
|
19589
19631
|
this.recordingStats.waitingTime = this.waitingTime;
|
|
19590
19632
|
}
|
|
19591
19633
|
initSocket(cb) {
|
|
19592
|
-
if (this.connected)
|
|
19593
|
-
|
|
19634
|
+
if (this.connected) {
|
|
19635
|
+
this.options.logger.debug("Recorder: already **connected**. Not going to initialize a new WebSocket connection.");
|
|
19636
|
+
cb?.();
|
|
19637
|
+
return;
|
|
19638
|
+
}
|
|
19639
|
+
if (this.connecting) return void this.options.logger.debug("Recorder: already **connecting**. Not going to initialize a new WebSocket connection.");
|
|
19640
|
+
this.clearReconnectTimeout();
|
|
19594
19641
|
if (util_isAutomatedUserAgent()) {
|
|
19595
19642
|
this.connecting = false;
|
|
19596
19643
|
this.options.logger.debug("Recorder: skipping web socket connection for an automated crawler");
|
|
@@ -19669,8 +19716,12 @@
|
|
|
19669
19716
|
this.connectionTimeout = window.setTimeout(()=>{
|
|
19670
19717
|
if (this.isOnline() && this.isUserMediaLoaded()) {
|
|
19671
19718
|
this.options.logger.debug(`${PIPE_SYMBOL}Reconnecting due to connection timeout.`);
|
|
19672
|
-
this.
|
|
19673
|
-
|
|
19719
|
+
this.reconnecting = true;
|
|
19720
|
+
this.handleConnectionFailure({
|
|
19721
|
+
url2Connect,
|
|
19722
|
+
cause: "timeout"
|
|
19723
|
+
});
|
|
19724
|
+
} else this.handleConnectionFailure({
|
|
19674
19725
|
url2Connect,
|
|
19675
19726
|
cause: "timeout"
|
|
19676
19727
|
});
|
|
@@ -19685,9 +19736,11 @@
|
|
|
19685
19736
|
this.options.logger.debug(debugLine);
|
|
19686
19737
|
const tryReconnect = this.connected && this.userMediaLoaded;
|
|
19687
19738
|
this.connected = false;
|
|
19688
|
-
if (tryReconnect)
|
|
19689
|
-
|
|
19690
|
-
this.
|
|
19739
|
+
if (tryReconnect) {
|
|
19740
|
+
this.reconnecting = true;
|
|
19741
|
+
this.initSocket();
|
|
19742
|
+
} else if (!this.connecting && !this.blocking) window.setTimeout(()=>{
|
|
19743
|
+
this.handleConnectionFailure({
|
|
19691
19744
|
url2Connect,
|
|
19692
19745
|
cause: "closed"
|
|
19693
19746
|
});
|
|
@@ -19700,6 +19753,9 @@
|
|
|
19700
19753
|
if (!this.connected && !isClosing && !this.unloaded) {
|
|
19701
19754
|
this.connected = true;
|
|
19702
19755
|
this.connecting = this.unloaded = false;
|
|
19756
|
+
this.reconnecting = false;
|
|
19757
|
+
this.reconnectAttempts = 0;
|
|
19758
|
+
this.clearReconnectTimeout();
|
|
19703
19759
|
this.emit("CONNECTED");
|
|
19704
19760
|
cb?.();
|
|
19705
19761
|
}
|
|
@@ -19729,7 +19785,7 @@
|
|
|
19729
19785
|
error: serializeError(err)
|
|
19730
19786
|
});
|
|
19731
19787
|
this.options.logger.debug(debugLine);
|
|
19732
|
-
if (!this.connected) return void this.
|
|
19788
|
+
if (!this.connected) return void this.handleConnectionFailure({
|
|
19733
19789
|
url2Connect,
|
|
19734
19790
|
cause: "error"
|
|
19735
19791
|
});
|
|
@@ -19789,6 +19845,7 @@
|
|
|
19789
19845
|
return this.blocking;
|
|
19790
19846
|
}
|
|
19791
19847
|
userMediaErrorCallback(err, usedConstraints) {
|
|
19848
|
+
if (this.unloaded) return void this.options.logger.debug(`Recorder: already unloaded. Not going to throw error ${util_pretty(err)}`);
|
|
19792
19849
|
this.userMediaLoading = false;
|
|
19793
19850
|
this.clearUserMediaTimeout();
|
|
19794
19851
|
const characteristics = this.userMedia?.getCharacteristics();
|
|
@@ -19807,10 +19864,9 @@
|
|
|
19807
19864
|
this.options.logger.debug(`Recorder: ignore user media error ${util_pretty(err)}`);
|
|
19808
19865
|
this.retryTimeout = window.setTimeout(()=>{
|
|
19809
19866
|
this.retryTimeout = void 0;
|
|
19810
|
-
this.loadUserMedia();
|
|
19867
|
+
if (!this.unloaded) this.loadUserMedia();
|
|
19811
19868
|
}, this.options.timeouts.userMedia);
|
|
19812
19869
|
}
|
|
19813
|
-
else if (this.unloaded) this.options.logger.debug(`Recorder: already unloaded. Not going to throw error ${util_pretty(err)}`);
|
|
19814
19870
|
else {
|
|
19815
19871
|
this.options.logger.debug(`Recorder: no error listeners attached but throwing error ${util_pretty(err)}`);
|
|
19816
19872
|
throw error_createError({
|
|
@@ -19821,26 +19877,46 @@
|
|
|
19821
19877
|
}
|
|
19822
19878
|
}
|
|
19823
19879
|
getUserMediaCallback(localStream, params) {
|
|
19824
|
-
if (!this.userMedia)
|
|
19880
|
+
if (!this.userMedia) {
|
|
19881
|
+
localStream.getTracks().forEach((track)=>{
|
|
19882
|
+
track.stop();
|
|
19883
|
+
});
|
|
19884
|
+
throw error_createError({
|
|
19885
|
+
message: "No user media is defined",
|
|
19886
|
+
options: this.options
|
|
19887
|
+
});
|
|
19888
|
+
}
|
|
19825
19889
|
this.options.logger.debug(`Recorder: getUserMediaCallback(${params ? util_pretty(params) : ""})`);
|
|
19826
19890
|
if (this.showUserMedia()) try {
|
|
19827
|
-
this.clearUserMediaTimeout();
|
|
19828
19891
|
this.userMedia.init(localStream, ()=>{
|
|
19829
|
-
this.onUserMediaReady(params);
|
|
19892
|
+
if (!this.unloaded) this.onUserMediaReady(params);
|
|
19830
19893
|
}, this.onAudioSample.bind(this), (err)=>{
|
|
19831
|
-
this.
|
|
19832
|
-
|
|
19894
|
+
if (!this.unloaded) this.userMediaErrorCallback(err, {
|
|
19895
|
+
audio: isAudioEnabled(this.options)
|
|
19833
19896
|
});
|
|
19834
19897
|
}, params?.switchingFacingMode);
|
|
19835
19898
|
} catch (exc) {
|
|
19899
|
+
localStream.getTracks().forEach((track)=>{
|
|
19900
|
+
track.stop();
|
|
19901
|
+
});
|
|
19902
|
+
this.userMediaLoading = false;
|
|
19903
|
+
this.clearUserMediaTimeout();
|
|
19836
19904
|
this.emit("ERROR", {
|
|
19837
19905
|
exc
|
|
19838
19906
|
});
|
|
19839
19907
|
}
|
|
19908
|
+
else {
|
|
19909
|
+
localStream.getTracks().forEach((track)=>{
|
|
19910
|
+
track.stop();
|
|
19911
|
+
});
|
|
19912
|
+
this.userMediaLoading = false;
|
|
19913
|
+
this.clearUserMediaTimeout();
|
|
19914
|
+
}
|
|
19840
19915
|
}
|
|
19841
19916
|
loadGenuineUserMedia(params) {
|
|
19842
19917
|
this.options.logger.debug(`Recorder: loadGenuineUserMedia(${params ? util_pretty(params) : ""})`);
|
|
19843
19918
|
this.emit("ASKING_WEBCAM_PERMISSION");
|
|
19919
|
+
this.userMediaLoading = true;
|
|
19844
19920
|
const constraints = {
|
|
19845
19921
|
video: {
|
|
19846
19922
|
frameRate: {
|
|
@@ -19871,9 +19947,12 @@
|
|
|
19871
19947
|
this.options.logger.debug(util_summarize("Recorder: available webcam constraints are:", navigator.mediaDevices.getSupportedConstraints()));
|
|
19872
19948
|
const streamPromise = navigator.mediaDevices.getUserMedia(constraints);
|
|
19873
19949
|
streamPromise.then((localStream)=>{
|
|
19950
|
+
if (this.unloaded) return void localStream.getTracks().forEach((track)=>{
|
|
19951
|
+
track.stop();
|
|
19952
|
+
});
|
|
19874
19953
|
this.getUserMediaCallback(localStream, params);
|
|
19875
19954
|
}).catch((reason)=>{
|
|
19876
|
-
this.userMediaErrorCallback(reason, constraints);
|
|
19955
|
+
if (!this.unloaded) this.userMediaErrorCallback(reason, constraints);
|
|
19877
19956
|
});
|
|
19878
19957
|
}
|
|
19879
19958
|
loadUserMedia(params) {
|
|
@@ -19887,7 +19966,8 @@
|
|
|
19887
19966
|
try {
|
|
19888
19967
|
if (!navigator.mediaDevices) throw new Error("No media devices are available.");
|
|
19889
19968
|
this.userMediaTimeout = window.setTimeout(()=>{
|
|
19890
|
-
if (!this.
|
|
19969
|
+
if (!this.userMediaLoaded) {
|
|
19970
|
+
this.userMediaLoading = false;
|
|
19891
19971
|
const err = util_getBrowser(this.options).getNoAccessIssue();
|
|
19892
19972
|
this.emit("ERROR", {
|
|
19893
19973
|
err
|
|
@@ -19986,16 +20066,16 @@
|
|
|
19986
20066
|
command,
|
|
19987
20067
|
args
|
|
19988
20068
|
};
|
|
19989
|
-
this.writeStream(Buffer.from(JSON.stringify(commandObj))
|
|
19990
|
-
|
|
19991
|
-
|
|
19992
|
-
|
|
20069
|
+
this.writeStream(Buffer.from(JSON.stringify(commandObj)), cb ? {
|
|
20070
|
+
onFlushedCallback: ()=>{
|
|
20071
|
+
queueMicrotask(cb);
|
|
20072
|
+
}
|
|
20073
|
+
} : void 0);
|
|
19993
20074
|
}
|
|
19994
20075
|
} else {
|
|
19995
20076
|
this.options.logger.debug(`Reconnecting for the command ${command} …`);
|
|
19996
20077
|
this.initSocket(()=>{
|
|
19997
|
-
this.writeCommand(command, args);
|
|
19998
|
-
cb?.();
|
|
20078
|
+
this.writeCommand(command, args, cb);
|
|
19999
20079
|
});
|
|
20000
20080
|
}
|
|
20001
20081
|
}
|
|
@@ -20066,6 +20146,7 @@
|
|
|
20066
20146
|
reInitializeAudio() {
|
|
20067
20147
|
this.options.logger.debug("Recorder: reInitializeAudio()");
|
|
20068
20148
|
this.clearUserMediaTimeout();
|
|
20149
|
+
this.userMediaLoading = false;
|
|
20069
20150
|
this.userMedia?.stop();
|
|
20070
20151
|
this.userMediaLoaded = this.key = this.canvas = this.ctx = void 0;
|
|
20071
20152
|
this.loadUserMedia();
|
|
@@ -20080,17 +20161,17 @@
|
|
|
20080
20161
|
this.reset();
|
|
20081
20162
|
this.clearUserMediaTimeout();
|
|
20082
20163
|
this.clearConnectionTimeout();
|
|
20164
|
+
this.clearReconnectTimeout();
|
|
20083
20165
|
this.clearRetryTimeout();
|
|
20084
20166
|
this.clearStopTimeout();
|
|
20085
20167
|
this.stopPings();
|
|
20168
|
+
this.userMediaLoading = false;
|
|
20086
20169
|
this.connecting = false;
|
|
20170
|
+
this.reconnecting = false;
|
|
20171
|
+
this.reconnectAttempts = 0;
|
|
20087
20172
|
if (this.userMedia) this.userMedia.unloadRemainingEventListeners();
|
|
20088
20173
|
if (this.submitting) ;
|
|
20089
|
-
else if (this.stream)
|
|
20090
|
-
this.options.logger.debug("Recorder: destroying stream ...");
|
|
20091
|
-
this.stream.destroy();
|
|
20092
|
-
this.stream = void 0;
|
|
20093
|
-
}
|
|
20174
|
+
else if (this.stream) this.discardSocket();
|
|
20094
20175
|
this.unloaded = true;
|
|
20095
20176
|
this.built = this.connecting = this.connected = false;
|
|
20096
20177
|
}
|
|
@@ -20190,7 +20271,13 @@
|
|
|
20190
20271
|
if (!this.connected) {
|
|
20191
20272
|
this.options.logger.debug("Recorder: reconnecting before recording …");
|
|
20192
20273
|
this.initSocket(()=>{
|
|
20193
|
-
this.once("
|
|
20274
|
+
this.once("SERVER_READY", ()=>{
|
|
20275
|
+
if (this.unloaded) return;
|
|
20276
|
+
if (this.userMediaLoaded || this.options.loadUserMediaOnRecord) this.record();
|
|
20277
|
+
else this.once("USER_MEDIA_READY", ()=>{
|
|
20278
|
+
if (!this.unloaded) this.record();
|
|
20279
|
+
});
|
|
20280
|
+
});
|
|
20194
20281
|
});
|
|
20195
20282
|
return;
|
|
20196
20283
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "videomail-client",
|
|
3
|
-
"version": "15.
|
|
3
|
+
"version": "15.9.0",
|
|
4
4
|
"description": "A wicked npm package to record videos directly in the browser, for Deaf and Sign Language!",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"webcam",
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
"@types/ua-parser-js": "0.7.39",
|
|
102
102
|
"@vitest/eslint-plugin": "1.6.27",
|
|
103
103
|
"audit-ci": "7.1.0",
|
|
104
|
-
"chromatic": "18.
|
|
104
|
+
"chromatic": "18.11.0",
|
|
105
105
|
"cross-env": "10.1.0",
|
|
106
106
|
"eslint": "10.12.0",
|
|
107
107
|
"eslint-import-resolver-typescript": "4.4.5",
|
|
@@ -112,7 +112,7 @@
|
|
|
112
112
|
"eslint-plugin-regexp": "3.3.1",
|
|
113
113
|
"eslint-plugin-simple-import-sort": "14.0.0",
|
|
114
114
|
"globals": "17.13.0",
|
|
115
|
-
"jsdom": "30.1.
|
|
115
|
+
"jsdom": "30.1.2",
|
|
116
116
|
"msw": "2.15.0",
|
|
117
117
|
"msw-storybook-addon": "3.0.3",
|
|
118
118
|
"prettier": "3.9.9",
|
|
@@ -125,7 +125,7 @@
|
|
|
125
125
|
"storybook-html-rsbuild": "3.6.0",
|
|
126
126
|
"type-fest": "5.10.0",
|
|
127
127
|
"typescript": "6.0.3",
|
|
128
|
-
"typescript-eslint": "8.71.
|
|
128
|
+
"typescript-eslint": "8.71.1",
|
|
129
129
|
"vitest": "5.0.3"
|
|
130
130
|
},
|
|
131
131
|
"engines": {
|