easyproctor-hml 2.7.14 → 2.8.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/esm/index.js +353 -205
- package/extension/extensionEasyCatcher.d.ts +11 -0
- package/extension/{extension.d.ts → extensionEasyProctor.d.ts} +1 -1
- package/index.js +353 -205
- package/new-flow/checkers/DeviceCheckerUI.d.ts +11 -0
- package/new-flow/chunk/ChunkStorageService.d.ts +1 -1
- package/new-flow/proctoring/ProctoringUploader.d.ts +1 -0
- package/new-flow/recorders/CameraRecorder.d.ts +0 -3
- package/package.json +1 -1
- package/plugins/recorder.d.ts +1 -5
- package/proctoring/options/ProctoringOptions.d.ts +1 -0
- package/proctoring/proctoring.d.ts +5 -0
- package/proctoring/useProctoring.d.ts +2 -0
- package/unpkg/easyproctor.min.js +39 -39
package/esm/index.js
CHANGED
|
@@ -9340,6 +9340,9 @@ var FaceDetection = class extends BaseDetection {
|
|
|
9340
9340
|
if (this.emmitedFaceAlert) {
|
|
9341
9341
|
this.handleOk("face_stop", "face_detection_on_stream");
|
|
9342
9342
|
}
|
|
9343
|
+
this.numFacesSent = -1;
|
|
9344
|
+
this.emmitedPositionAlert = false;
|
|
9345
|
+
this.emmitedFaceAlert = false;
|
|
9343
9346
|
}
|
|
9344
9347
|
// displayVideoDetections(result: { detections: any; }) {
|
|
9345
9348
|
// // console.log(result);
|
|
@@ -12699,7 +12702,8 @@ var getDefaultProctoringOptions = {
|
|
|
12699
12702
|
useSpyScan: false,
|
|
12700
12703
|
useExternalCamera: false,
|
|
12701
12704
|
useChallenge: false,
|
|
12702
|
-
screenRecorderOptions: { width: 1280, height: 720 }
|
|
12705
|
+
screenRecorderOptions: { width: 1280, height: 720 },
|
|
12706
|
+
auto: false
|
|
12703
12707
|
};
|
|
12704
12708
|
|
|
12705
12709
|
// src/proctoring/options/ProctoringVideoOptions.ts
|
|
@@ -12767,7 +12771,7 @@ var proctoringId;
|
|
|
12767
12771
|
function setRecorderProctoringId(id) {
|
|
12768
12772
|
proctoringId = id;
|
|
12769
12773
|
}
|
|
12770
|
-
function recorder(stream, buffer, onBufferSizeError = false, onBufferSizeErrorCallback, audio = false
|
|
12774
|
+
function recorder(stream, buffer, onBufferSizeError = false, onBufferSizeErrorCallback, audio = false) {
|
|
12771
12775
|
let resolvePromise;
|
|
12772
12776
|
let onBufferSizeInterval;
|
|
12773
12777
|
let lastEvent;
|
|
@@ -12775,7 +12779,6 @@ function recorder(stream, buffer, onBufferSizeError = false, onBufferSizeErrorCa
|
|
|
12775
12779
|
bufferSize = 0;
|
|
12776
12780
|
let startTime;
|
|
12777
12781
|
let duration = 0;
|
|
12778
|
-
let chunkIndex = 0;
|
|
12779
12782
|
let recorderOptions = {
|
|
12780
12783
|
// eslint-disable-next-line no-useless-escape
|
|
12781
12784
|
mimeType: "video/webm",
|
|
@@ -12810,10 +12813,6 @@ function recorder(stream, buffer, onBufferSizeError = false, onBufferSizeErrorCa
|
|
|
12810
12813
|
mediaRecorder2.ondataavailable = (e3) => {
|
|
12811
12814
|
bufferSize = bufferSize + e3.data.size;
|
|
12812
12815
|
if (e3.data.size > 0) {
|
|
12813
|
-
if (recorderOpts == null ? void 0 : recorderOpts.onChunkAvailable) {
|
|
12814
|
-
recorderOpts.onChunkAvailable(e3.data, chunkIndex);
|
|
12815
|
-
chunkIndex++;
|
|
12816
|
-
}
|
|
12817
12816
|
buffer.push(e3.data);
|
|
12818
12817
|
}
|
|
12819
12818
|
};
|
|
@@ -12845,13 +12844,7 @@ function recorder(stream, buffer, onBufferSizeError = false, onBufferSizeErrorCa
|
|
|
12845
12844
|
};
|
|
12846
12845
|
try {
|
|
12847
12846
|
console.log("State antes do start:", recorder2.state);
|
|
12848
|
-
|
|
12849
|
-
if ((recorderOpts == null ? void 0 : recorderOpts.timeslice) && (recorderOpts == null ? void 0 : recorderOpts.timeslice) > 0) {
|
|
12850
|
-
recorder2.start(recorderOpts.timeslice);
|
|
12851
|
-
} else {
|
|
12852
|
-
recorder2.start(1e4);
|
|
12853
|
-
}
|
|
12854
|
-
bufferSize = 0;
|
|
12847
|
+
recorder2.start(1e4);
|
|
12855
12848
|
startTime = new Date(Date.now());
|
|
12856
12849
|
} catch (e3) {
|
|
12857
12850
|
console.error("Recorder erro ao chamar start event:", e3);
|
|
@@ -12905,6 +12898,9 @@ function recorder(stream, buffer, onBufferSizeError = false, onBufferSizeErrorCa
|
|
|
12905
12898
|
console.log("stopRecording Recorder n\xE3o est\xE1 em estado recording");
|
|
12906
12899
|
resolve();
|
|
12907
12900
|
}
|
|
12901
|
+
stream.getTracks().forEach((el) => {
|
|
12902
|
+
el.stop();
|
|
12903
|
+
});
|
|
12908
12904
|
});
|
|
12909
12905
|
}
|
|
12910
12906
|
function pauseRecording() {
|
|
@@ -13262,55 +13258,8 @@ var ObjectDetection = class extends BaseDetection {
|
|
|
13262
13258
|
}
|
|
13263
13259
|
};
|
|
13264
13260
|
|
|
13265
|
-
// src/new-flow/recorders/
|
|
13266
|
-
var
|
|
13267
|
-
constructor(stream) {
|
|
13268
|
-
this.volume = null;
|
|
13269
|
-
this.animationFrameId = null;
|
|
13270
|
-
this.stream = stream;
|
|
13271
|
-
}
|
|
13272
|
-
async start(options = {}) {
|
|
13273
|
-
return new Promise((resolve, reject) => {
|
|
13274
|
-
try {
|
|
13275
|
-
this.audioContext = new AudioContext();
|
|
13276
|
-
this.analyser = this.audioContext.createAnalyser();
|
|
13277
|
-
this.microphone = this.audioContext.createMediaStreamSource(this.stream);
|
|
13278
|
-
this.analyser.smoothingTimeConstant = 0.8;
|
|
13279
|
-
this.analyser.fftSize = 1024;
|
|
13280
|
-
this.microphone.connect(this.analyser);
|
|
13281
|
-
const processAudio = () => {
|
|
13282
|
-
const array = new Uint8Array(this.analyser.frequencyBinCount);
|
|
13283
|
-
this.analyser.getByteFrequencyData(array);
|
|
13284
|
-
const arraySum = array.reduce((a3, value) => a3 + value, 0);
|
|
13285
|
-
const average = arraySum / array.length;
|
|
13286
|
-
this.setVolume(average);
|
|
13287
|
-
options.setVolume && options.setVolume(average);
|
|
13288
|
-
this.animationFrameId = requestAnimationFrame(processAudio);
|
|
13289
|
-
};
|
|
13290
|
-
this.animationFrameId = requestAnimationFrame(processAudio);
|
|
13291
|
-
resolve(true);
|
|
13292
|
-
} catch (error) {
|
|
13293
|
-
this.stop();
|
|
13294
|
-
reject(`Error: ${error}`);
|
|
13295
|
-
}
|
|
13296
|
-
});
|
|
13297
|
-
}
|
|
13298
|
-
stop() {
|
|
13299
|
-
var _a2, _b, _c2;
|
|
13300
|
-
if (this.animationFrameId !== null) {
|
|
13301
|
-
cancelAnimationFrame(this.animationFrameId);
|
|
13302
|
-
}
|
|
13303
|
-
(_a2 = this.audioContext) == null ? void 0 : _a2.close();
|
|
13304
|
-
(_b = this.microphone) == null ? void 0 : _b.disconnect();
|
|
13305
|
-
(_c2 = this.analyser) == null ? void 0 : _c2.disconnect();
|
|
13306
|
-
}
|
|
13307
|
-
getVolume() {
|
|
13308
|
-
return this.volume;
|
|
13309
|
-
}
|
|
13310
|
-
setVolume(value) {
|
|
13311
|
-
this.volume = value;
|
|
13312
|
-
}
|
|
13313
|
-
};
|
|
13261
|
+
// src/new-flow/recorders/CameraRecorder.ts
|
|
13262
|
+
var import_jszip_min = __toESM(require_jszip_min());
|
|
13314
13263
|
|
|
13315
13264
|
// src/new-flow/chunk/ChunkStorageService.ts
|
|
13316
13265
|
var _ChunkStorageService = class _ChunkStorageService {
|
|
@@ -13328,13 +13277,7 @@ var _ChunkStorageService = class _ChunkStorageService {
|
|
|
13328
13277
|
_ChunkStorageService.DB_VERSION
|
|
13329
13278
|
);
|
|
13330
13279
|
request.onerror = () => {
|
|
13331
|
-
|
|
13332
|
-
console.error("IndexedDB error:", request.error);
|
|
13333
|
-
reject(
|
|
13334
|
-
new Error(
|
|
13335
|
-
`N\xE3o foi poss\xEDvel conectar ao IndexedDB para chunks: ${(_a2 = request.error) == null ? void 0 : _a2.name} - ${(_b = request.error) == null ? void 0 : _b.message}`
|
|
13336
|
-
)
|
|
13337
|
-
);
|
|
13280
|
+
reject(new Error("N\xE3o foi poss\xEDvel conectar ao IndexedDB para chunks."));
|
|
13338
13281
|
};
|
|
13339
13282
|
request.onupgradeneeded = () => {
|
|
13340
13283
|
const db = request.result;
|
|
@@ -13557,8 +13500,8 @@ var _ChunkStorageService = class _ChunkStorageService {
|
|
|
13557
13500
|
}
|
|
13558
13501
|
};
|
|
13559
13502
|
_ChunkStorageService.DB_NAME = "EasyProctorChunksDb";
|
|
13560
|
-
/**
|
|
13561
|
-
_ChunkStorageService.DB_VERSION =
|
|
13503
|
+
/** v2: índices uploaded numéricos; v3: campo arrayBuffer em vez de blob */
|
|
13504
|
+
_ChunkStorageService.DB_VERSION = 3;
|
|
13562
13505
|
_ChunkStorageService.STORE_NAME = "chunks";
|
|
13563
13506
|
var ChunkStorageService = _ChunkStorageService;
|
|
13564
13507
|
|
|
@@ -13741,8 +13684,9 @@ var BackgroundUploadService = class _BackgroundUploadService {
|
|
|
13741
13684
|
let virtualStart = this.totalBytesPurged;
|
|
13742
13685
|
const chunksWithMeta = allChunks.map((c3) => {
|
|
13743
13686
|
const start = virtualStart;
|
|
13744
|
-
const
|
|
13745
|
-
|
|
13687
|
+
const byteLength = c3.arrayBuffer.byteLength;
|
|
13688
|
+
const end = start + byteLength - 1;
|
|
13689
|
+
virtualStart += byteLength;
|
|
13746
13690
|
return { chunk: c3, start, end };
|
|
13747
13691
|
});
|
|
13748
13692
|
let combinedBlobParts = [];
|
|
@@ -13752,8 +13696,8 @@ var BackgroundUploadService = class _BackgroundUploadService {
|
|
|
13752
13696
|
for (const meta of chunksWithMeta) {
|
|
13753
13697
|
if (this.currentOffset > meta.end) continue;
|
|
13754
13698
|
const sliceStart = Math.max(0, this.currentOffset - meta.start);
|
|
13755
|
-
const
|
|
13756
|
-
combinedBlobParts.push(
|
|
13699
|
+
const sliceBuf = meta.chunk.arrayBuffer.slice(sliceStart);
|
|
13700
|
+
combinedBlobParts.push(new Blob([sliceBuf]));
|
|
13757
13701
|
lastProcessedChunkId = meta.chunk.id;
|
|
13758
13702
|
finalChunkIndex = meta.chunk.chunkIndex;
|
|
13759
13703
|
}
|
|
@@ -13787,7 +13731,10 @@ var BackgroundUploadService = class _BackgroundUploadService {
|
|
|
13787
13731
|
}
|
|
13788
13732
|
if (this.config.cleanAfterUpload) {
|
|
13789
13733
|
const chunksToClear = chunksWithMeta.filter((meta) => meta.chunk.uploaded === 1 || meta.chunk.uploaded === 0 && meta.end < this.currentOffset);
|
|
13790
|
-
const sizePurged = chunksToClear.reduce(
|
|
13734
|
+
const sizePurged = chunksToClear.reduce(
|
|
13735
|
+
(acc, meta) => acc + meta.chunk.arrayBuffer.byteLength,
|
|
13736
|
+
0
|
|
13737
|
+
);
|
|
13791
13738
|
await this.chunkStorage.clearUploadedChunks(this.proctoringId);
|
|
13792
13739
|
if (sizePurged > 0) {
|
|
13793
13740
|
this.totalBytesPurged += sizePurged;
|
|
@@ -13925,7 +13872,6 @@ var BackgroundUploadService = class _BackgroundUploadService {
|
|
|
13925
13872
|
};
|
|
13926
13873
|
|
|
13927
13874
|
// src/new-flow/recorders/CameraRecorder.ts
|
|
13928
|
-
var import_jszip_min = __toESM(require_jszip_min());
|
|
13929
13875
|
var pkg = require_fix_webm_duration();
|
|
13930
13876
|
var fixWebmDuration = pkg.default || pkg;
|
|
13931
13877
|
var _CameraRecorder = class _CameraRecorder {
|
|
@@ -13991,7 +13937,6 @@ var _CameraRecorder = class _CameraRecorder {
|
|
|
13991
13937
|
this.currentRetries = 0;
|
|
13992
13938
|
this.packageCount = 0;
|
|
13993
13939
|
this.failedUploads = 0;
|
|
13994
|
-
this.noiseWait = 20;
|
|
13995
13940
|
this.options = options;
|
|
13996
13941
|
this.videoOptions = videoOptions;
|
|
13997
13942
|
this.backend = backend;
|
|
@@ -13999,11 +13944,11 @@ var _CameraRecorder = class _CameraRecorder {
|
|
|
13999
13944
|
paramsConfig && (this.paramsConfig = paramsConfig);
|
|
14000
13945
|
}
|
|
14001
13946
|
/**
|
|
14002
|
-
|
|
14003
|
-
|
|
14004
|
-
|
|
14005
|
-
|
|
14006
|
-
|
|
13947
|
+
* Determina se o fluxo de chunks e lifecycle deve estar ativo.
|
|
13948
|
+
* Retorna true se:
|
|
13949
|
+
* 1. O proctoringId já foi definido (ou seja, estamos em uma sessão real, NÃO no checkDevices)
|
|
13950
|
+
* 2. E (`useChunkRecording` foi explicitamente setado como true OU o dispositivo é mobile)
|
|
13951
|
+
*/
|
|
14007
13952
|
get isChunkEnabled() {
|
|
14008
13953
|
return !!this.proctoringId && this.options.proctoringType === "REALTIME" && !isSafeBrowser();
|
|
14009
13954
|
}
|
|
@@ -14266,15 +14211,9 @@ Setting: ${JSON.stringify(settings, null, 2)}`
|
|
|
14266
14211
|
await new Promise((r3) => setTimeout(r3, 300));
|
|
14267
14212
|
}
|
|
14268
14213
|
async startRecording() {
|
|
14269
|
-
var _a2, _b, _c2, _d, _e3, _f, _g
|
|
14214
|
+
var _a2, _b, _c2, _d, _e3, _f, _g;
|
|
14270
14215
|
await this.startStream();
|
|
14271
14216
|
await this.attachAndWarmup(this.cameraStream);
|
|
14272
|
-
const recorderOpts = this.isChunkEnabled ? {
|
|
14273
|
-
timeslice: _CameraRecorder.CHUNK_TIMESLICE_MS,
|
|
14274
|
-
onChunkAvailable: (blob, idx) => {
|
|
14275
|
-
this.handleNewChunk(blob, idx);
|
|
14276
|
-
}
|
|
14277
|
-
} : {};
|
|
14278
14217
|
const {
|
|
14279
14218
|
startRecording,
|
|
14280
14219
|
stopRecording,
|
|
@@ -14290,8 +14229,7 @@ Setting: ${JSON.stringify(settings, null, 2)}`
|
|
|
14290
14229
|
this.blobs,
|
|
14291
14230
|
this.options.onBufferSizeError,
|
|
14292
14231
|
(e3) => this.bufferError(e3),
|
|
14293
|
-
false
|
|
14294
|
-
recorderOpts
|
|
14232
|
+
false
|
|
14295
14233
|
);
|
|
14296
14234
|
this.recordingStart = startRecording;
|
|
14297
14235
|
this.recordingStop = stopRecording;
|
|
@@ -14301,18 +14239,13 @@ Setting: ${JSON.stringify(settings, null, 2)}`
|
|
|
14301
14239
|
this.getBufferSize = getBufferSize;
|
|
14302
14240
|
this.getStartTime = getStartTime;
|
|
14303
14241
|
this.getDuration = getDuration;
|
|
14304
|
-
this.chunkIndex = 0;
|
|
14305
|
-
if (this.isChunkEnabled) {
|
|
14306
|
-
(_a2 = this.backgroundUpload) == null ? void 0 : _a2.start();
|
|
14307
|
-
this.setupLifecycleListeners();
|
|
14308
|
-
}
|
|
14309
14242
|
try {
|
|
14310
14243
|
await new Promise((r3) => setTimeout(r3, 500));
|
|
14311
14244
|
await this.recordingStart();
|
|
14312
14245
|
} catch (error) {
|
|
14313
14246
|
console.log("Camera Recorder error", error);
|
|
14314
14247
|
this.stopRecording();
|
|
14315
|
-
const maxRetries = ((
|
|
14248
|
+
const maxRetries = ((_a2 = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _a2.maxRetries) || 3;
|
|
14316
14249
|
if (this.currentRetries < maxRetries) {
|
|
14317
14250
|
console.log("Camera Recorder retry", this.currentRetries);
|
|
14318
14251
|
this.currentRetries++;
|
|
@@ -14322,13 +14255,13 @@ Setting: ${JSON.stringify(settings, null, 2)}`
|
|
|
14322
14255
|
}
|
|
14323
14256
|
}
|
|
14324
14257
|
this.stopped = false;
|
|
14325
|
-
if (((
|
|
14258
|
+
if (((_b = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _b.detectPerson) || ((_c2 = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _c2.detectCellPhone) || ((_d = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _d.detectFace)) {
|
|
14326
14259
|
await this.initializeDetectors();
|
|
14327
14260
|
}
|
|
14328
|
-
if ((
|
|
14261
|
+
if ((_e3 = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _e3.detectFace) {
|
|
14329
14262
|
await this.faceDetection.enableCam(this.cameraStream);
|
|
14330
14263
|
}
|
|
14331
|
-
if (((
|
|
14264
|
+
if (((_f = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _f.detectPerson) || ((_g = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _g.detectCellPhone)) {
|
|
14332
14265
|
await this.objectDetection.enableCam(this.cameraStream);
|
|
14333
14266
|
}
|
|
14334
14267
|
this.filesToUpload = [];
|
|
@@ -14413,10 +14346,11 @@ Setting: ${JSON.stringify(settings, null, 2)}`
|
|
|
14413
14346
|
const savePromise = (async () => {
|
|
14414
14347
|
var _a2;
|
|
14415
14348
|
try {
|
|
14349
|
+
const arrayBuffer = await blob.arrayBuffer();
|
|
14416
14350
|
await this.chunkStorage.saveChunk({
|
|
14417
14351
|
proctoringId: this.proctoringId,
|
|
14418
14352
|
chunkIndex: this.chunkIndex,
|
|
14419
|
-
|
|
14353
|
+
arrayBuffer,
|
|
14420
14354
|
timestamp: Date.now(),
|
|
14421
14355
|
uploaded: 0,
|
|
14422
14356
|
mimeType: ((_a2 = this.recorderOptions) == null ? void 0 : _a2.mimeType) || "video/webm"
|
|
@@ -14566,40 +14500,41 @@ Setting: ${JSON.stringify(settings, null, 2)}`
|
|
|
14566
14500
|
if (this.blobs != null)
|
|
14567
14501
|
trackers.registerSaveOnSession(
|
|
14568
14502
|
this.proctoringId,
|
|
14569
|
-
`Blobs Length: ${this.blobs.length} Buffer Size: ${this.getBufferSize()}
|
|
14503
|
+
`Blobs Length: ${this.blobs.length} Buffer Size: ${this.getBufferSize()} `
|
|
14570
14504
|
);
|
|
14571
14505
|
const settings = this.cameraStream.getVideoTracks()[0].getSettings();
|
|
14572
14506
|
const settingsAudio = this.cameraStream.getAudioTracks()[0].getSettings();
|
|
14573
14507
|
if (this.options.proctoringType == "VIDEO" || this.options.proctoringType == "REALTIME" || this.options.proctoringType == "IMAGE" && ((_a2 = this.paramsConfig.imageBehaviourParameters) == null ? void 0 : _a2.saveVideo)) {
|
|
14508
|
+
let isUploaded = false;
|
|
14574
14509
|
if (this.isChunkEnabled) {
|
|
14575
|
-
|
|
14576
|
-
|
|
14577
|
-
|
|
14578
|
-
|
|
14579
|
-
|
|
14580
|
-
const objectName = `${this.proctoringId}/${fileName}`;
|
|
14581
|
-
const isUploaded = await this.backend.checkUpload(this.backendToken, objectName, "video/webm");
|
|
14582
|
-
if (isUploaded) {
|
|
14583
|
-
this.chunkStorage && await this.chunkStorage.clearAllChunks(session.id);
|
|
14584
|
-
return;
|
|
14585
|
-
}
|
|
14586
|
-
}
|
|
14510
|
+
if (this.backend && this.backendToken && this.proctoringId) {
|
|
14511
|
+
const fileName = `EP_${this.proctoringId}_camera_0.webm`;
|
|
14512
|
+
const objectName = `${this.proctoringId}/${fileName}`;
|
|
14513
|
+
isUploaded = await this.backend.checkUpload(this.backendToken, objectName, "video/webm");
|
|
14514
|
+
this.chunkStorage && await this.chunkStorage.clearAllChunks(session.id);
|
|
14587
14515
|
}
|
|
14588
14516
|
}
|
|
14589
|
-
|
|
14590
|
-
|
|
14591
|
-
|
|
14592
|
-
|
|
14593
|
-
|
|
14594
|
-
|
|
14517
|
+
if (!isUploaded) {
|
|
14518
|
+
const rawBlob = new Blob(this.blobs, {
|
|
14519
|
+
type: ((_b = this.recorderOptions) == null ? void 0 : _b.mimeType) || "video/webm"
|
|
14520
|
+
});
|
|
14521
|
+
let finalBlob = rawBlob;
|
|
14522
|
+
if (typeof fixWebmDuration === "function") {
|
|
14523
|
+
finalBlob = await fixWebmDuration(rawBlob, this.duration);
|
|
14524
|
+
} else {
|
|
14525
|
+
console.warn("fixWebmDuration n\xE3o dispon\xEDvel");
|
|
14526
|
+
}
|
|
14527
|
+
session.addRecording({
|
|
14528
|
+
device: `Audio
|
|
14595
14529
|
Sample Rate: ${settingsAudio.sampleRate}
|
|
14596
14530
|
Sample Size: ${settingsAudio.sampleSize}
|
|
14597
14531
|
|
|
14598
14532
|
Video:
|
|
14599
14533
|
${JSON.stringify(this.recorderOptions)}`,
|
|
14600
|
-
|
|
14601
|
-
|
|
14602
|
-
|
|
14534
|
+
arrayBuffer: await finalBlob.arrayBuffer(),
|
|
14535
|
+
origin: "Camera" /* Camera */
|
|
14536
|
+
});
|
|
14537
|
+
}
|
|
14603
14538
|
}
|
|
14604
14539
|
}
|
|
14605
14540
|
async getFile(file, name, type) {
|
|
@@ -14612,51 +14547,6 @@ Setting: ${JSON.stringify(settings, null, 2)}`
|
|
|
14612
14547
|
});
|
|
14613
14548
|
});
|
|
14614
14549
|
}
|
|
14615
|
-
/**
|
|
14616
|
-
* Verifica se a internet está estável para realizar o upload do vídeo na íntegra.
|
|
14617
|
-
*/
|
|
14618
|
-
async checkInternetStability() {
|
|
14619
|
-
var _a2;
|
|
14620
|
-
if (!navigator.onLine) return false;
|
|
14621
|
-
try {
|
|
14622
|
-
const controller = new AbortController();
|
|
14623
|
-
const timeoutId = setTimeout(() => controller.abort(), 5e3);
|
|
14624
|
-
const baseUrl = (_a2 = this.backend) == null ? void 0 : _a2.getBaseUrl();
|
|
14625
|
-
if (!baseUrl) return true;
|
|
14626
|
-
const response = await fetch(`${baseUrl}/Client/health`, {
|
|
14627
|
-
method: "GET",
|
|
14628
|
-
signal: controller.signal
|
|
14629
|
-
});
|
|
14630
|
-
clearTimeout(timeoutId);
|
|
14631
|
-
return response.status < 500;
|
|
14632
|
-
} catch (e3) {
|
|
14633
|
-
console.warn("[CameraRecorder] Internet inst\xE1vel ou lenta detectada para upload integral.");
|
|
14634
|
-
return false;
|
|
14635
|
-
}
|
|
14636
|
-
}
|
|
14637
|
-
onNoiseDetected() {
|
|
14638
|
-
var _a2, _b, _c2;
|
|
14639
|
-
if (this.options.proctoringType === "REALTIME") return;
|
|
14640
|
-
if (!this.volumeMeter && this.cameraStream) {
|
|
14641
|
-
this.volumeMeter = new VolumeMeter(this.cameraStream);
|
|
14642
|
-
this.volumeMeter.start().catch((e3) => {
|
|
14643
|
-
console.log(e3);
|
|
14644
|
-
this.volumeMeter = void 0;
|
|
14645
|
-
});
|
|
14646
|
-
}
|
|
14647
|
-
const volume = (_b = (_a2 = this.volumeMeter) == null ? void 0 : _a2.getVolume()) != null ? _b : 0;
|
|
14648
|
-
if (volume >= (((_c2 = this.paramsConfig.audioBehaviourParameters) == null ? void 0 : _c2.noiseLimit) || 40)) {
|
|
14649
|
-
if (this.noiseWait >= 20) {
|
|
14650
|
-
this.options.onRealtimeAlertsCallback({
|
|
14651
|
-
status: "ALERT",
|
|
14652
|
-
description: "Barulho detectado",
|
|
14653
|
-
type: "audio_detection_on_stream"
|
|
14654
|
-
});
|
|
14655
|
-
this.noiseWait = 0;
|
|
14656
|
-
}
|
|
14657
|
-
}
|
|
14658
|
-
this.noiseWait++;
|
|
14659
|
-
}
|
|
14660
14550
|
};
|
|
14661
14551
|
// ========================
|
|
14662
14552
|
// Chunk & Lifecycle
|
|
@@ -14667,10 +14557,62 @@ _CameraRecorder.CHUNK_TIMESLICE_MS = 6e4;
|
|
|
14667
14557
|
_CameraRecorder.LS_SESSION_KEY = "ep_proctoring_session";
|
|
14668
14558
|
var CameraRecorder = _CameraRecorder;
|
|
14669
14559
|
|
|
14560
|
+
// src/new-flow/recorders/VolumeMeter.ts
|
|
14561
|
+
var VolumeMeter = class {
|
|
14562
|
+
constructor(stream) {
|
|
14563
|
+
this.volume = null;
|
|
14564
|
+
this.animationFrameId = null;
|
|
14565
|
+
this.stream = stream;
|
|
14566
|
+
}
|
|
14567
|
+
async start(options = {}) {
|
|
14568
|
+
return new Promise((resolve, reject) => {
|
|
14569
|
+
try {
|
|
14570
|
+
this.audioContext = new AudioContext();
|
|
14571
|
+
this.analyser = this.audioContext.createAnalyser();
|
|
14572
|
+
this.microphone = this.audioContext.createMediaStreamSource(this.stream);
|
|
14573
|
+
this.analyser.smoothingTimeConstant = 0.8;
|
|
14574
|
+
this.analyser.fftSize = 1024;
|
|
14575
|
+
this.microphone.connect(this.analyser);
|
|
14576
|
+
const processAudio = () => {
|
|
14577
|
+
const array = new Uint8Array(this.analyser.frequencyBinCount);
|
|
14578
|
+
this.analyser.getByteFrequencyData(array);
|
|
14579
|
+
const arraySum = array.reduce((a3, value) => a3 + value, 0);
|
|
14580
|
+
const average = arraySum / array.length;
|
|
14581
|
+
this.setVolume(average);
|
|
14582
|
+
options.setVolume && options.setVolume(average);
|
|
14583
|
+
this.animationFrameId = requestAnimationFrame(processAudio);
|
|
14584
|
+
};
|
|
14585
|
+
this.animationFrameId = requestAnimationFrame(processAudio);
|
|
14586
|
+
resolve(true);
|
|
14587
|
+
} catch (error) {
|
|
14588
|
+
this.stop();
|
|
14589
|
+
reject(`Error: ${error}`);
|
|
14590
|
+
}
|
|
14591
|
+
});
|
|
14592
|
+
}
|
|
14593
|
+
stop() {
|
|
14594
|
+
var _a2, _b, _c2;
|
|
14595
|
+
if (this.animationFrameId !== null) {
|
|
14596
|
+
cancelAnimationFrame(this.animationFrameId);
|
|
14597
|
+
}
|
|
14598
|
+
(_a2 = this.audioContext) == null ? void 0 : _a2.close();
|
|
14599
|
+
(_b = this.microphone) == null ? void 0 : _b.disconnect();
|
|
14600
|
+
(_c2 = this.analyser) == null ? void 0 : _c2.disconnect();
|
|
14601
|
+
}
|
|
14602
|
+
getVolume() {
|
|
14603
|
+
return this.volume;
|
|
14604
|
+
}
|
|
14605
|
+
setVolume(value) {
|
|
14606
|
+
this.volume = value;
|
|
14607
|
+
}
|
|
14608
|
+
};
|
|
14609
|
+
|
|
14670
14610
|
// src/new-flow/checkers/DeviceCheckerUI.ts
|
|
14671
14611
|
var DeviceCheckerUI = class {
|
|
14672
14612
|
constructor(options = getDefaultProctoringOptions, _videoOptions) {
|
|
14673
14613
|
this.videoOptions = { width: 1080, height: 720, minWidth: 0, minHeight: 0 };
|
|
14614
|
+
this.autoConfirmTimer = null;
|
|
14615
|
+
this.autoConfirmSeconds = 5;
|
|
14674
14616
|
this.options = {
|
|
14675
14617
|
...getDefaultProctoringOptions,
|
|
14676
14618
|
...options,
|
|
@@ -15436,9 +15378,53 @@ var DeviceCheckerUI = class {
|
|
|
15436
15378
|
}));
|
|
15437
15379
|
}
|
|
15438
15380
|
closeModal() {
|
|
15381
|
+
this.stopAutoConfirm();
|
|
15439
15382
|
const checkDevices = document.querySelector("#checkDevices");
|
|
15440
15383
|
checkDevices == null ? void 0 : checkDevices.remove();
|
|
15441
15384
|
}
|
|
15385
|
+
verifyAutoConfirm(status) {
|
|
15386
|
+
var _a2;
|
|
15387
|
+
if (!((_a2 = this.options) == null ? void 0 : _a2.auto)) return;
|
|
15388
|
+
let isAllGreen = status.allowedResolution && status.allowedPositionFace && status.allowedAmbient && status.allowedMicrophone;
|
|
15389
|
+
if (this.options.useSpyScan) {
|
|
15390
|
+
isAllGreen = isAllGreen && status.allowedSpyScan === true;
|
|
15391
|
+
}
|
|
15392
|
+
if (isAllGreen) {
|
|
15393
|
+
if (!this.autoConfirmTimer) {
|
|
15394
|
+
this.startAutoConfirm();
|
|
15395
|
+
}
|
|
15396
|
+
} else {
|
|
15397
|
+
if (this.autoConfirmTimer) {
|
|
15398
|
+
this.stopAutoConfirm();
|
|
15399
|
+
}
|
|
15400
|
+
}
|
|
15401
|
+
}
|
|
15402
|
+
startAutoConfirm() {
|
|
15403
|
+
this.autoConfirmSeconds = 5;
|
|
15404
|
+
const btn = document.getElementById("confirmBtn");
|
|
15405
|
+
if (btn && !btn.disabled) {
|
|
15406
|
+
btn.innerText = `Continuando em ${this.autoConfirmSeconds}s...`;
|
|
15407
|
+
this.autoConfirmTimer = setInterval(() => {
|
|
15408
|
+
this.autoConfirmSeconds--;
|
|
15409
|
+
if (this.autoConfirmSeconds <= 0) {
|
|
15410
|
+
this.stopAutoConfirm();
|
|
15411
|
+
btn.click();
|
|
15412
|
+
} else {
|
|
15413
|
+
btn.innerText = `Continuando em ${this.autoConfirmSeconds}s...`;
|
|
15414
|
+
}
|
|
15415
|
+
}, 1e3);
|
|
15416
|
+
}
|
|
15417
|
+
}
|
|
15418
|
+
stopAutoConfirm() {
|
|
15419
|
+
if (this.autoConfirmTimer) {
|
|
15420
|
+
clearInterval(this.autoConfirmTimer);
|
|
15421
|
+
this.autoConfirmTimer = null;
|
|
15422
|
+
}
|
|
15423
|
+
const btn = document.getElementById("confirmBtn");
|
|
15424
|
+
if (btn) {
|
|
15425
|
+
btn.innerText = "Continuar";
|
|
15426
|
+
}
|
|
15427
|
+
}
|
|
15442
15428
|
modalActions(closeCheckDevices) {
|
|
15443
15429
|
const cancelBtn = document.getElementById("cancelBtn");
|
|
15444
15430
|
const confirmBtn = document.getElementById("confirmBtn");
|
|
@@ -15805,6 +15791,7 @@ var _DeviceCheckerService = class _DeviceCheckerService {
|
|
|
15805
15791
|
}
|
|
15806
15792
|
}
|
|
15807
15793
|
onUpdateCallback() {
|
|
15794
|
+
var _a2;
|
|
15808
15795
|
if (typeof this.onUpdateCb === "function") {
|
|
15809
15796
|
this.onUpdateCb({
|
|
15810
15797
|
allowedResolution: this.allowedResolution,
|
|
@@ -15815,6 +15802,15 @@ var _DeviceCheckerService = class _DeviceCheckerService {
|
|
|
15815
15802
|
faceDetectionAlerts: this.faceDetectionAlerts
|
|
15816
15803
|
});
|
|
15817
15804
|
}
|
|
15805
|
+
if (((_a2 = this.options) == null ? void 0 : _a2.auto) && this.DeviceCheckerUI) {
|
|
15806
|
+
this.DeviceCheckerUI.verifyAutoConfirm({
|
|
15807
|
+
allowedResolution: this.allowedResolution,
|
|
15808
|
+
allowedPositionFace: this.allowedPositionFace,
|
|
15809
|
+
allowedAmbient: this.allowedAmbient,
|
|
15810
|
+
allowedMicrophone: this.allowedMicrophone,
|
|
15811
|
+
allowedSpyScan: this.allowedSpyScan
|
|
15812
|
+
});
|
|
15813
|
+
}
|
|
15818
15814
|
}
|
|
15819
15815
|
async checkDevices(options = getDefaultProctoringOptions, _videoOptions = getDefaultProctoringVideoOptions) {
|
|
15820
15816
|
var _a2;
|
|
@@ -16021,16 +16017,19 @@ var _DeviceCheckerService = class _DeviceCheckerService {
|
|
|
16021
16017
|
}).finally(() => {
|
|
16022
16018
|
this.DeviceCheckerUI && this.DeviceCheckerUI.waitingSpyDevices(false);
|
|
16023
16019
|
this.DeviceCheckerUI && this.allowedSpyScan != null && this.DeviceCheckerUI.isSpyDevicesUI(this.allowedSpyScan);
|
|
16020
|
+
this.onUpdateCallback();
|
|
16024
16021
|
});
|
|
16025
16022
|
} else {
|
|
16026
16023
|
this.allowedSpyScan = false;
|
|
16027
16024
|
this.DeviceCheckerUI && this.DeviceCheckerUI.waitingSpyDevices(false);
|
|
16028
16025
|
this.DeviceCheckerUI && this.DeviceCheckerUI.isSpyDevicesUI(this.allowedSpyScan);
|
|
16026
|
+
this.onUpdateCallback();
|
|
16029
16027
|
}
|
|
16030
16028
|
} catch (error) {
|
|
16031
16029
|
this.allowedSpyScan = false;
|
|
16032
16030
|
this.DeviceCheckerUI && this.DeviceCheckerUI.waitingSpyDevices(false);
|
|
16033
16031
|
this.DeviceCheckerUI && this.DeviceCheckerUI.isSpyDevicesUI(this.allowedSpyScan);
|
|
16032
|
+
this.onUpdateCallback();
|
|
16034
16033
|
console.log(error);
|
|
16035
16034
|
}
|
|
16036
16035
|
}
|
|
@@ -16350,8 +16349,8 @@ var CapturePhoto = class {
|
|
|
16350
16349
|
}
|
|
16351
16350
|
};
|
|
16352
16351
|
|
|
16353
|
-
// src/extension/
|
|
16354
|
-
var
|
|
16352
|
+
// src/extension/extensionEasyProctor.ts
|
|
16353
|
+
var ExtensionEasyProctor = class {
|
|
16355
16354
|
constructor() {
|
|
16356
16355
|
this.hasExtension = false;
|
|
16357
16356
|
this.tryes = 0;
|
|
@@ -16396,6 +16395,89 @@ var Extension = class {
|
|
|
16396
16395
|
}
|
|
16397
16396
|
};
|
|
16398
16397
|
|
|
16398
|
+
// src/extension/extensionEasyCatcher.ts
|
|
16399
|
+
var ExtensionEasyCatcher = class {
|
|
16400
|
+
constructor(options) {
|
|
16401
|
+
this.hasExtension = false;
|
|
16402
|
+
this.tryes = 0;
|
|
16403
|
+
this.responseStart = false;
|
|
16404
|
+
this.options = options || {};
|
|
16405
|
+
}
|
|
16406
|
+
/**
|
|
16407
|
+
* Verifica se a extensão está instalada e ativa.
|
|
16408
|
+
* Retorna o número da versão se encontrada, ou lança erro após timeout.
|
|
16409
|
+
*/
|
|
16410
|
+
checkExtensionInstalled(timeoutMs = 2e3) {
|
|
16411
|
+
return new Promise((resolve, reject) => {
|
|
16412
|
+
let handled = false;
|
|
16413
|
+
const handler = (event) => {
|
|
16414
|
+
if (event.source === window && event.data.sender === "easyproctor-extension" && event.data.message_name === "version") {
|
|
16415
|
+
handled = true;
|
|
16416
|
+
window.removeEventListener("message", handler);
|
|
16417
|
+
resolve(event.data.message);
|
|
16418
|
+
}
|
|
16419
|
+
};
|
|
16420
|
+
window.addEventListener("message", handler);
|
|
16421
|
+
window.postMessage({
|
|
16422
|
+
type: "easycatcher",
|
|
16423
|
+
func: "verifyExtensionEasycatcher"
|
|
16424
|
+
}, "*");
|
|
16425
|
+
setTimeout(() => {
|
|
16426
|
+
if (!handled) {
|
|
16427
|
+
window.removeEventListener("message", handler);
|
|
16428
|
+
reject(new Error("Extens\xE3o n\xE3o detectada ou n\xE3o respondeu."));
|
|
16429
|
+
}
|
|
16430
|
+
}, timeoutMs);
|
|
16431
|
+
});
|
|
16432
|
+
}
|
|
16433
|
+
/**
|
|
16434
|
+
* Solicita o JSON da sessão atual capturado pela extensão.
|
|
16435
|
+
*/
|
|
16436
|
+
getSessionData(timeoutMs = 5e3) {
|
|
16437
|
+
return new Promise((resolve, reject) => {
|
|
16438
|
+
let handled = false;
|
|
16439
|
+
const handler = (event) => {
|
|
16440
|
+
if (event.source === window && event.data.sender === "easyproctor-extension" && event.data.message_name === "data_response") {
|
|
16441
|
+
handled = true;
|
|
16442
|
+
window.removeEventListener("message", handler);
|
|
16443
|
+
resolve(event.data.payload);
|
|
16444
|
+
}
|
|
16445
|
+
};
|
|
16446
|
+
window.addEventListener("message", handler);
|
|
16447
|
+
window.postMessage({
|
|
16448
|
+
type: "easycatcher",
|
|
16449
|
+
func: "getDataExtensionEasycatcher"
|
|
16450
|
+
}, "*");
|
|
16451
|
+
setTimeout(() => {
|
|
16452
|
+
if (!handled) {
|
|
16453
|
+
window.removeEventListener("message", handler);
|
|
16454
|
+
reject(new Error("Timeout ao aguardar dados da extens\xE3o."));
|
|
16455
|
+
}
|
|
16456
|
+
}, timeoutMs);
|
|
16457
|
+
});
|
|
16458
|
+
}
|
|
16459
|
+
start() {
|
|
16460
|
+
return new Promise((resolve, reject) => {
|
|
16461
|
+
let handled = false;
|
|
16462
|
+
const handler = (event) => {
|
|
16463
|
+
if (event.source === window && event.data.sender === "easyproctor-extension" && event.data.message_name === "started_confirmed") {
|
|
16464
|
+
handled = true;
|
|
16465
|
+
window.removeEventListener("message", handler);
|
|
16466
|
+
resolve(true);
|
|
16467
|
+
}
|
|
16468
|
+
};
|
|
16469
|
+
window.addEventListener("message", handler);
|
|
16470
|
+
window.postMessage({ type: "easycatcher", func: "startExtensionEasycatcher" }, "*");
|
|
16471
|
+
setTimeout(() => {
|
|
16472
|
+
if (!handled) {
|
|
16473
|
+
window.removeEventListener("message", handler);
|
|
16474
|
+
reject(new Error("Timeout: Extens\xE3o n\xE3o confirmou o in\xEDcio."));
|
|
16475
|
+
}
|
|
16476
|
+
}, 3e3);
|
|
16477
|
+
});
|
|
16478
|
+
}
|
|
16479
|
+
};
|
|
16480
|
+
|
|
16399
16481
|
// src/modules/onChangeDevices.ts
|
|
16400
16482
|
var onChangeDevices = class {
|
|
16401
16483
|
constructor(repositoryDevices, proctoringId2, sessionOptions, allRecorders) {
|
|
@@ -16584,9 +16666,19 @@ var ProctoringUploader = class {
|
|
|
16584
16666
|
}
|
|
16585
16667
|
toFile(rec) {
|
|
16586
16668
|
const suffix = rec.origin === "Screen" /* Screen */ ? "screen" : rec.origin === "Camera" /* Camera */ ? "camera" : "audio";
|
|
16587
|
-
const name = `EP_${this.
|
|
16669
|
+
const name = `EP_${this.proctoringId}_${suffix}_0.webm`;
|
|
16588
16670
|
return new File([rec.arrayBuffer], name, { type: "video/webm" });
|
|
16589
16671
|
}
|
|
16672
|
+
getFileType(origin2) {
|
|
16673
|
+
switch (origin2) {
|
|
16674
|
+
case "Camera" /* Camera */:
|
|
16675
|
+
return "Camera";
|
|
16676
|
+
case "Screen" /* Screen */:
|
|
16677
|
+
return "Screen";
|
|
16678
|
+
case "Mic" /* Mic */:
|
|
16679
|
+
return "Audio";
|
|
16680
|
+
}
|
|
16681
|
+
}
|
|
16590
16682
|
async uploadFile(rec, token, onProgress) {
|
|
16591
16683
|
const file = this.toFile(rec);
|
|
16592
16684
|
for await (const uploadService of this.uploadServices) {
|
|
@@ -16598,23 +16690,24 @@ var ProctoringUploader = class {
|
|
|
16598
16690
|
}
|
|
16599
16691
|
},
|
|
16600
16692
|
token
|
|
16601
|
-
).catch(
|
|
16602
|
-
|
|
16603
|
-
|
|
16693
|
+
).catch(async (e3) => {
|
|
16694
|
+
console.log("Upload File Error", e3), trackers.registerError(
|
|
16695
|
+
this.proctoringId,
|
|
16696
|
+
`Upload File
|
|
16604
16697
|
Name: ${file.name}
|
|
16605
16698
|
Error: ${e3.message}
|
|
16606
|
-
Size: ${e3.error}`
|
|
16607
|
-
|
|
16608
|
-
|
|
16609
|
-
|
|
16610
|
-
|
|
16611
|
-
|
|
16612
|
-
|
|
16613
|
-
}
|
|
16614
|
-
|
|
16615
|
-
|
|
16616
|
-
|
|
16617
|
-
);
|
|
16699
|
+
Size: ${e3.error}`
|
|
16700
|
+
);
|
|
16701
|
+
await uploadService.upload(
|
|
16702
|
+
{
|
|
16703
|
+
file,
|
|
16704
|
+
onProgress: (progress) => {
|
|
16705
|
+
if (onProgress) onProgress(progress);
|
|
16706
|
+
}
|
|
16707
|
+
},
|
|
16708
|
+
token
|
|
16709
|
+
);
|
|
16710
|
+
});
|
|
16618
16711
|
if (result) {
|
|
16619
16712
|
let fileType = "";
|
|
16620
16713
|
if (rec.origin === "Camera" /* Camera */) {
|
|
@@ -19436,10 +19529,15 @@ var ScreenRecorder = class {
|
|
|
19436
19529
|
const rawBlob = new Blob(this.blobs, {
|
|
19437
19530
|
type: "video/webm"
|
|
19438
19531
|
});
|
|
19439
|
-
|
|
19532
|
+
let finalBlob = rawBlob;
|
|
19533
|
+
if (typeof fixWebmDuration2 === "function") {
|
|
19534
|
+
finalBlob = await fixWebmDuration2(rawBlob, this.duration);
|
|
19535
|
+
} else {
|
|
19536
|
+
console.warn("fixWebmDuration n\xE3o dispon\xEDvel");
|
|
19537
|
+
}
|
|
19440
19538
|
session.addRecording({
|
|
19441
19539
|
device: "",
|
|
19442
|
-
arrayBuffer: await
|
|
19540
|
+
arrayBuffer: await finalBlob.arrayBuffer(),
|
|
19443
19541
|
origin: "Screen" /* Screen */
|
|
19444
19542
|
});
|
|
19445
19543
|
}
|
|
@@ -23571,7 +23669,10 @@ var Proctoring = class {
|
|
|
23571
23669
|
if (this.context.token === void 0) {
|
|
23572
23670
|
throw TOKEN_MISSING;
|
|
23573
23671
|
}
|
|
23574
|
-
|
|
23672
|
+
if (options.useChallenge) {
|
|
23673
|
+
this.extensionEasycatcher = new ExtensionEasyCatcher();
|
|
23674
|
+
}
|
|
23675
|
+
this.extension = new ExtensionEasyProctor();
|
|
23575
23676
|
this.extension.addEventListener();
|
|
23576
23677
|
const baseURL = this.backend.selectBaseUrl(this.context.type);
|
|
23577
23678
|
const devices = await enumarateDevices();
|
|
@@ -23639,20 +23740,6 @@ var Proctoring = class {
|
|
|
23639
23740
|
} catch (error) {
|
|
23640
23741
|
throw SAFE_BROWSER_API_NOT_FOUND;
|
|
23641
23742
|
}
|
|
23642
|
-
this.allRecorders.cameraRecorder.onVisibilityRestored = () => {
|
|
23643
|
-
console.log("[Proctoring] Usu\xE1rio retornou ao browser.");
|
|
23644
|
-
this.onVisibilityRestoredCallback();
|
|
23645
|
-
};
|
|
23646
|
-
if (this.sessionOptions.proctoringType === "REALTIME" && !isSafeBrowser()) {
|
|
23647
|
-
try {
|
|
23648
|
-
await BackgroundUploadService.recoverPendingUploads(
|
|
23649
|
-
this.backend,
|
|
23650
|
-
this.context.token
|
|
23651
|
-
);
|
|
23652
|
-
} catch (e3) {
|
|
23653
|
-
console.warn("[Proctoring] Erro ao recuperar chunks de sess\xE3o anterior:", e3);
|
|
23654
|
-
}
|
|
23655
|
-
}
|
|
23656
23743
|
try {
|
|
23657
23744
|
console.log("Starting recorders");
|
|
23658
23745
|
await this.recorder.startAll();
|
|
@@ -23733,7 +23820,9 @@ Error: ${error}`
|
|
|
23733
23820
|
this.appChecker && await this.appChecker.disconnectWebSocket();
|
|
23734
23821
|
await this.recorder.saveAllOnSession();
|
|
23735
23822
|
await this.sendPendingRealtimeAlerts();
|
|
23823
|
+
trackers.registerError(this.proctoringId, `finish this.repository.save starting`);
|
|
23736
23824
|
await this.repository.save(this.proctoringSession);
|
|
23825
|
+
trackers.registerError(this.proctoringId, `finish this.repository.save finished`);
|
|
23737
23826
|
let uploader;
|
|
23738
23827
|
let uploaderServices;
|
|
23739
23828
|
if (versionVerify() !== "1.0.0.0") {
|
|
@@ -23955,6 +24044,61 @@ Error: ` + error
|
|
|
23955
24044
|
_screenStream: (_a2 = this.allRecorders.screenRecorder) == null ? void 0 : _a2.screenStream
|
|
23956
24045
|
};
|
|
23957
24046
|
}
|
|
24047
|
+
async startChallenge(templateId) {
|
|
24048
|
+
var _a2;
|
|
24049
|
+
if (!this.sessionOptions.useChallenge) {
|
|
24050
|
+
throw new Error("useChallenge is set as false on start method");
|
|
24051
|
+
}
|
|
24052
|
+
await this.extensionEasycatcher.checkExtensionInstalled().catch((err) => {
|
|
24053
|
+
throw new Error("EasyCatcher Extension is not installed");
|
|
24054
|
+
});
|
|
24055
|
+
this.extensionEasycatcher.start();
|
|
24056
|
+
const start = Date.now() - ((_a2 = this.allRecorders.cameraRecorder.getStartTime()) == null ? void 0 : _a2.getTime()) || 0;
|
|
24057
|
+
await this.backend.startChallenge({
|
|
24058
|
+
proctoringId: this.proctoringId,
|
|
24059
|
+
templateId,
|
|
24060
|
+
start
|
|
24061
|
+
}).then((resp) => {
|
|
24062
|
+
console.log(resp);
|
|
24063
|
+
this.challengeId = resp.id;
|
|
24064
|
+
}).catch((reason) => {
|
|
24065
|
+
trackers.registerError(
|
|
24066
|
+
this.proctoringId,
|
|
24067
|
+
"N\xE3o foi poss\xEDvel iniciar desafio!"
|
|
24068
|
+
);
|
|
24069
|
+
throw reason;
|
|
24070
|
+
});
|
|
24071
|
+
this.isChallengeRunning = true;
|
|
24072
|
+
}
|
|
24073
|
+
async stopChallenge() {
|
|
24074
|
+
var _a2;
|
|
24075
|
+
if (!this.isChallengeRunning) {
|
|
24076
|
+
throw new Error("Challenge not started");
|
|
24077
|
+
}
|
|
24078
|
+
try {
|
|
24079
|
+
const sessionData = await this.extensionEasycatcher.getSessionData();
|
|
24080
|
+
const end = Date.now() - ((_a2 = this.allRecorders.cameraRecorder.getStartTime()) == null ? void 0 : _a2.getTime()) || 0;
|
|
24081
|
+
await this.backend.stopChallenge(
|
|
24082
|
+
this.challengeId,
|
|
24083
|
+
{
|
|
24084
|
+
end,
|
|
24085
|
+
data: sessionData
|
|
24086
|
+
}
|
|
24087
|
+
).catch((reason) => {
|
|
24088
|
+
trackers.registerError(
|
|
24089
|
+
this.proctoringId,
|
|
24090
|
+
"N\xE3o foi poss\xEDvel finalizar o desafio no backend!"
|
|
24091
|
+
);
|
|
24092
|
+
return void 0;
|
|
24093
|
+
});
|
|
24094
|
+
this.isChallengeRunning = false;
|
|
24095
|
+
} catch (error) {
|
|
24096
|
+
trackers.registerError(
|
|
24097
|
+
this.proctoringId,
|
|
24098
|
+
"Erro ao recuperar dados da extens\xE3o: " + error.message
|
|
24099
|
+
);
|
|
24100
|
+
}
|
|
24101
|
+
}
|
|
23958
24102
|
};
|
|
23959
24103
|
|
|
23960
24104
|
// src/proctoring/SignTerm.ts
|
|
@@ -24183,6 +24327,8 @@ function useProctoring(proctoringOptions, enviromentConfig = "prod") {
|
|
|
24183
24327
|
return originalStart(parameters2, videoOptions);
|
|
24184
24328
|
};
|
|
24185
24329
|
const finish = proctoring.finish.bind(proctoring);
|
|
24330
|
+
const startChallenge = proctoring.startChallenge.bind(proctoring);
|
|
24331
|
+
const stopChallenge = proctoring.stopChallenge.bind(proctoring);
|
|
24186
24332
|
const pause = proctoring.pause.bind(proctoring);
|
|
24187
24333
|
const resume = proctoring.resume.bind(proctoring);
|
|
24188
24334
|
const onFocus = proctoring.setOnFocusCallback.bind(proctoring);
|
|
@@ -24207,6 +24353,8 @@ function useProctoring(proctoringOptions, enviromentConfig = "prod") {
|
|
|
24207
24353
|
login,
|
|
24208
24354
|
start,
|
|
24209
24355
|
finish,
|
|
24356
|
+
startChallenge,
|
|
24357
|
+
stopChallenge,
|
|
24210
24358
|
onFocus,
|
|
24211
24359
|
onLostFocus,
|
|
24212
24360
|
onChangeDevices: onChangeDevices2,
|