easyproctor-hml 2.5.17 → 2.5.19
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 +88 -47
- package/index.js +88 -47
- package/interfaces/ParamsConfig.d.ts +1 -2
- package/new-flow/backend/BackendService.d.ts +1 -1
- package/new-flow/proctoring/ProctoringSession.d.ts +3 -3
- package/new-flow/recorders/AlertRecorder.d.ts +1 -0
- package/new-flow/recorders/CameraRecorder.d.ts +1 -1
- package/package.json +1 -1
- package/proctoring/proctoring.d.ts +2 -0
- package/proctoring/useProctoring.d.ts +1 -1
- package/unpkg/easyproctor.min.js +11 -11
package/esm/index.js
CHANGED
|
@@ -11819,12 +11819,12 @@ var BackendService = class {
|
|
|
11819
11819
|
});
|
|
11820
11820
|
return result.data;
|
|
11821
11821
|
}
|
|
11822
|
-
async verifyFace(proctoringId2, faceImage) {
|
|
11822
|
+
async verifyFace(proctoringId2, faceImage, retry) {
|
|
11823
11823
|
const result = await this.makeRequestAxios({
|
|
11824
11824
|
path: `/Realtime/verify-face`,
|
|
11825
11825
|
method: "POST",
|
|
11826
11826
|
jwt: this.token,
|
|
11827
|
-
body: { "proctoringId": proctoringId2, "base64": faceImage }
|
|
11827
|
+
body: { "proctoringId": proctoringId2, "base64": faceImage, "retry": retry }
|
|
11828
11828
|
});
|
|
11829
11829
|
return result.data;
|
|
11830
11830
|
}
|
|
@@ -12700,7 +12700,6 @@ var CameraRecorder = class {
|
|
|
12700
12700
|
noiseLimit: 40
|
|
12701
12701
|
},
|
|
12702
12702
|
imageBehaviourParameters: {
|
|
12703
|
-
frames: 40,
|
|
12704
12703
|
useUploadImage: true,
|
|
12705
12704
|
uploadInterval: 20,
|
|
12706
12705
|
saveVideo: true
|
|
@@ -12712,7 +12711,6 @@ var CameraRecorder = class {
|
|
|
12712
12711
|
}
|
|
12713
12712
|
};
|
|
12714
12713
|
// private imageParams: ImageParameters = {
|
|
12715
|
-
// frames: 40,
|
|
12716
12714
|
// useUploadImage: true,
|
|
12717
12715
|
// uploadInterval: 20,
|
|
12718
12716
|
// saveVideo: true
|
|
@@ -12804,7 +12802,7 @@ var CameraRecorder = class {
|
|
|
12804
12802
|
}
|
|
12805
12803
|
}
|
|
12806
12804
|
async startRecording(options) {
|
|
12807
|
-
var _a2, _b, _c2, _d, _e3, _f, _g, _h
|
|
12805
|
+
var _a2, _b, _c2, _d, _e3, _f, _g, _h;
|
|
12808
12806
|
if ((((_a2 = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _a2.detectPerson) || ((_b = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _b.detectCellPhone) || ((_c2 = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _c2.detectFace)) && !(options == null ? void 0 : options.retry)) {
|
|
12809
12807
|
await this.initializeDetectors();
|
|
12810
12808
|
}
|
|
@@ -12884,7 +12882,6 @@ Setting: ${JSON.stringify(settings, null, 2)}`
|
|
|
12884
12882
|
this.filesToUpload = [];
|
|
12885
12883
|
if (this.options.proctoringType == "REALTIME") {
|
|
12886
12884
|
this.captureFrame();
|
|
12887
|
-
this.sendFrameInterval = setInterval(() => this.captureFrame(), 1e3 * ((_i3 = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _i3.realtimeUploadInterval));
|
|
12888
12885
|
}
|
|
12889
12886
|
this.packageCount = 0;
|
|
12890
12887
|
}
|
|
@@ -12915,7 +12912,8 @@ Setting: ${JSON.stringify(settings, null, 2)}`
|
|
|
12915
12912
|
clearInterval(this.imageInterval);
|
|
12916
12913
|
clearInterval(this.sendFrameInterval);
|
|
12917
12914
|
if (this.options.proctoringType == "REALTIME" && this.upload && this.backendToken) {
|
|
12918
|
-
await this.sendPackage();
|
|
12915
|
+
await this.sendPackage(this.filesToUpload);
|
|
12916
|
+
await this.filesToUpload.splice(0, this.filesToUpload.length);
|
|
12919
12917
|
}
|
|
12920
12918
|
this.volumeMeter && this.volumeMeter.stop();
|
|
12921
12919
|
this.intervalNoiseDetection && clearInterval(this.intervalNoiseDetection);
|
|
@@ -12985,23 +12983,29 @@ Setting: ${JSON.stringify(settings, null, 2)}`
|
|
|
12985
12983
|
this.canvas.getContext("2d").drawImage(this.video, 0, 0, this.canvas.width, this.canvas.height);
|
|
12986
12984
|
return this.canvas.toDataURL("image/jpeg");
|
|
12987
12985
|
}
|
|
12988
|
-
//
|
|
12986
|
+
// captura um frame a cada intervalo de tempo definido no paramsConfig.videoBehaviourParameters?.realtimeCaptureInterval!
|
|
12989
12987
|
captureFrame() {
|
|
12990
|
-
var _a2;
|
|
12988
|
+
var _a2, _b;
|
|
12991
12989
|
let imageFile;
|
|
12992
12990
|
this.configImageCapture();
|
|
12991
|
+
let newCanvasWidth = this.videoOptions.width / 2;
|
|
12992
|
+
let newCanvasHeight = this.videoOptions.height / 2;
|
|
12993
|
+
if (newCanvasWidth < 320) newCanvasWidth = 320;
|
|
12994
|
+
if (newCanvasHeight < 180) newCanvasHeight = 180;
|
|
12995
|
+
this.canvas.width = newCanvasWidth;
|
|
12996
|
+
this.canvas.height = newCanvasHeight;
|
|
12993
12997
|
const packSize = (_a2 = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _a2.realtimePackageSize;
|
|
12994
|
-
|
|
12995
|
-
this.imageCount++;
|
|
12998
|
+
this.imageCount = 0;
|
|
12996
12999
|
this.imageInterval = setInterval(async () => {
|
|
13000
|
+
console.log("capturando frame " + this.imageCount);
|
|
12997
13001
|
this.canvas.getContext("2d").drawImage(this.video, 0, 0, this.canvas.width, this.canvas.height);
|
|
12998
13002
|
const image_data_url = this.canvas.toDataURL("image/jpeg");
|
|
12999
13003
|
if (this.proctoringId == void 0) return;
|
|
13000
|
-
if (
|
|
13001
|
-
initSend = true;
|
|
13004
|
+
if (packSize == this.imageCount) {
|
|
13002
13005
|
this.imageCount = 0;
|
|
13003
|
-
|
|
13004
|
-
this.sendPackage();
|
|
13006
|
+
const framesToSend = [...this.filesToUpload];
|
|
13007
|
+
this.sendPackage(framesToSend);
|
|
13008
|
+
await this.filesToUpload.splice(0, this.filesToUpload.length);
|
|
13005
13009
|
}
|
|
13006
13010
|
let imageName = `${this.proctoringId}_${this.imageCount + 1}.jpg`;
|
|
13007
13011
|
imageFile = await this.getFile(image_data_url, imageName, "image/jpeg");
|
|
@@ -13009,22 +13013,24 @@ Setting: ${JSON.stringify(settings, null, 2)}`
|
|
|
13009
13013
|
this.filesToUpload.push(imageFile);
|
|
13010
13014
|
this.imageCount++;
|
|
13011
13015
|
}
|
|
13012
|
-
}, 1e3);
|
|
13016
|
+
}, ((_b = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _b.realtimeCaptureInterval) * 1e3);
|
|
13013
13017
|
}
|
|
13014
13018
|
// envia pacote de imagens
|
|
13015
|
-
async sendPackage() {
|
|
13019
|
+
async sendPackage(framesToSend) {
|
|
13020
|
+
var _a2, _b;
|
|
13016
13021
|
let pending = false;
|
|
13017
13022
|
let undeliveredPackagesCount = 0;
|
|
13023
|
+
const packSize = (_a2 = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _a2.realtimePackageSize;
|
|
13024
|
+
const packCaptureInterval = ((_b = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _b.realtimeCaptureInterval) + 1;
|
|
13018
13025
|
if (this.upload && this.backendToken && !pending && this.filesToUpload.length > 0) {
|
|
13019
13026
|
undeliveredPackagesCount = 0;
|
|
13020
13027
|
pending = true;
|
|
13021
13028
|
const zip = new import_jszip_min.default();
|
|
13022
|
-
const
|
|
13023
|
-
for (const file of files) {
|
|
13029
|
+
for (const file of framesToSend) {
|
|
13024
13030
|
zip.file(file.name, file);
|
|
13025
13031
|
}
|
|
13026
13032
|
const blob = await zip.generateAsync({ type: "blob" });
|
|
13027
|
-
let packageName = "realtime_package_" +
|
|
13033
|
+
let packageName = "realtime_package_" + packSize * packCaptureInterval * this.packageCount + ".zip";
|
|
13028
13034
|
const myPackage = new File(
|
|
13029
13035
|
[blob],
|
|
13030
13036
|
packageName,
|
|
@@ -13037,7 +13043,6 @@ Setting: ${JSON.stringify(settings, null, 2)}`
|
|
|
13037
13043
|
this.backendToken
|
|
13038
13044
|
);
|
|
13039
13045
|
if (uploadResult.uploaded == true) {
|
|
13040
|
-
await this.filesToUpload.splice(0, this.filesToUpload.length);
|
|
13041
13046
|
this.packageCount++;
|
|
13042
13047
|
} else {
|
|
13043
13048
|
console.log("erro no upload do pacote");
|
|
@@ -15200,9 +15205,15 @@ var AlertRecorder = class {
|
|
|
15200
15205
|
// HANDLERS (Funções Arrow para preservar o 'this')
|
|
15201
15206
|
// ==========================================
|
|
15202
15207
|
// 1. LOST / RETURN FOCUS
|
|
15208
|
+
this.handleVisibilityChange = () => {
|
|
15209
|
+
if (document.visibilityState === "visible") {
|
|
15210
|
+
this.handleReturnFocus();
|
|
15211
|
+
} else {
|
|
15212
|
+
this.handleLostFocus();
|
|
15213
|
+
}
|
|
15214
|
+
};
|
|
15203
15215
|
this.handleLostFocus = () => {
|
|
15204
15216
|
if (this.getRelativeTime() > 1e4) {
|
|
15205
|
-
this.createAlert(25 /* FocusOff */, 3 /* Screen */, "Usu\xE1rio mudou de aba ou minimizou");
|
|
15206
15217
|
const alertPayload = {
|
|
15207
15218
|
begin: this.getRelativeTime(),
|
|
15208
15219
|
end: 0,
|
|
@@ -15233,7 +15244,7 @@ var AlertRecorder = class {
|
|
|
15233
15244
|
const windowWidth = window.outerWidth;
|
|
15234
15245
|
if (windowWidth < screenWidth * 0.85) {
|
|
15235
15246
|
const msg = `Split Screen Detectado: Janela ocupa ${(windowWidth / screenWidth * 100).toFixed(0)}% da tela`;
|
|
15236
|
-
this.createAlert(
|
|
15247
|
+
this.createAlert(43 /* SplitScreen */, 3 /* Screen */, msg);
|
|
15237
15248
|
this.onRealtimeAlertCallback && this.onRealtimeAlertCallback({
|
|
15238
15249
|
status: "ALERT",
|
|
15239
15250
|
description: msg,
|
|
@@ -15251,7 +15262,7 @@ var AlertRecorder = class {
|
|
|
15251
15262
|
this.handleCopy = (e3) => {
|
|
15252
15263
|
e3.preventDefault();
|
|
15253
15264
|
const msg = "Tentativa de Copiar (Clipboard)";
|
|
15254
|
-
this.createAlert(
|
|
15265
|
+
this.createAlert(42 /* ClipBoardUse */, 3 /* Screen */, msg);
|
|
15255
15266
|
this.onRealtimeAlertCallback && this.onRealtimeAlertCallback({
|
|
15256
15267
|
status: "ALERT",
|
|
15257
15268
|
description: msg,
|
|
@@ -15261,7 +15272,7 @@ var AlertRecorder = class {
|
|
|
15261
15272
|
this.handleCut = (e3) => {
|
|
15262
15273
|
e3.preventDefault();
|
|
15263
15274
|
const msg = "Tentativa de Recortar (Clipboard)";
|
|
15264
|
-
this.createAlert(
|
|
15275
|
+
this.createAlert(42 /* ClipBoardUse */, 3 /* Screen */, msg);
|
|
15265
15276
|
this.onRealtimeAlertCallback && this.onRealtimeAlertCallback({
|
|
15266
15277
|
status: "ALERT",
|
|
15267
15278
|
description: msg,
|
|
@@ -15271,7 +15282,7 @@ var AlertRecorder = class {
|
|
|
15271
15282
|
this.handlePaste = (e3) => {
|
|
15272
15283
|
e3.preventDefault();
|
|
15273
15284
|
const msg = "Tentativa de Colar (Clipboard)";
|
|
15274
|
-
this.createAlert(
|
|
15285
|
+
this.createAlert(42 /* ClipBoardUse */, 3 /* Screen */, msg);
|
|
15275
15286
|
this.onRealtimeAlertCallback && this.onRealtimeAlertCallback({
|
|
15276
15287
|
status: "ALERT",
|
|
15277
15288
|
description: msg,
|
|
@@ -15307,8 +15318,7 @@ var AlertRecorder = class {
|
|
|
15307
15318
|
// ==========================================
|
|
15308
15319
|
attachListeners() {
|
|
15309
15320
|
if (this.optionsProctoring.captureScreen) {
|
|
15310
|
-
window.addEventListener("
|
|
15311
|
-
window.addEventListener("focus", this.handleReturnFocus);
|
|
15321
|
+
window.addEventListener("visibilitychange", this.handleVisibilityChange);
|
|
15312
15322
|
window.addEventListener("resize", this.handleResize);
|
|
15313
15323
|
window.document.addEventListener("copy", this.handleCopy);
|
|
15314
15324
|
window.document.addEventListener("cut", this.handleCut);
|
|
@@ -15316,8 +15326,7 @@ var AlertRecorder = class {
|
|
|
15316
15326
|
}
|
|
15317
15327
|
}
|
|
15318
15328
|
detachListeners() {
|
|
15319
|
-
window.removeEventListener("
|
|
15320
|
-
window.removeEventListener("focus", this.handleReturnFocus);
|
|
15329
|
+
window.removeEventListener("visibilitychange", this.handleVisibilityChange);
|
|
15321
15330
|
window.removeEventListener("resize", this.handleResize);
|
|
15322
15331
|
window.document.removeEventListener("copy", this.handleCopy);
|
|
15323
15332
|
window.document.removeEventListener("cut", this.handleCut);
|
|
@@ -15352,7 +15361,7 @@ var AlertRecorder = class {
|
|
|
15352
15361
|
// }
|
|
15353
15362
|
// 4. BACKGROUND EVENTS (Eventos disparados manualmente)
|
|
15354
15363
|
addBackgroundEvent(description, category = 200 /* System */) {
|
|
15355
|
-
this.createAlert(category,
|
|
15364
|
+
this.createAlert(category, 3 /* Screen */, description);
|
|
15356
15365
|
this.onRealtimeAlertCallback && this.onRealtimeAlertCallback({
|
|
15357
15366
|
status: "ALERT",
|
|
15358
15367
|
description,
|
|
@@ -21590,7 +21599,8 @@ var _ExternalCameraChecker = class _ExternalCameraChecker {
|
|
|
21590
21599
|
this.connection = new HubConnectionBuilder().withUrl(hubUrl, {
|
|
21591
21600
|
accessTokenFactory: () => this.context.token,
|
|
21592
21601
|
transport: HttpTransportType.WebSockets,
|
|
21593
|
-
withCredentials: false
|
|
21602
|
+
withCredentials: false,
|
|
21603
|
+
skipNegotiation: true
|
|
21594
21604
|
}).withAutomaticReconnect().configureLogging(LogLevel.Information).build();
|
|
21595
21605
|
this.connection.on(
|
|
21596
21606
|
"ReceiveMessage",
|
|
@@ -21797,7 +21807,6 @@ var Proctoring = class {
|
|
|
21797
21807
|
noiseLimit: 40
|
|
21798
21808
|
},
|
|
21799
21809
|
imageBehaviourParameters: {
|
|
21800
|
-
frames: 40,
|
|
21801
21810
|
useUploadImage: true,
|
|
21802
21811
|
uploadInterval: 20,
|
|
21803
21812
|
saveVideo: true
|
|
@@ -21808,8 +21817,8 @@ var Proctoring = class {
|
|
|
21808
21817
|
detectCellPhone: false,
|
|
21809
21818
|
detectNoise: false,
|
|
21810
21819
|
detectSpeech: false,
|
|
21811
|
-
realtimePackageSize:
|
|
21812
|
-
|
|
21820
|
+
realtimePackageSize: 10,
|
|
21821
|
+
realtimeCaptureInterval: 2
|
|
21813
21822
|
}
|
|
21814
21823
|
};
|
|
21815
21824
|
this.proctoringId = "";
|
|
@@ -21945,6 +21954,29 @@ var Proctoring = class {
|
|
|
21945
21954
|
return null;
|
|
21946
21955
|
}
|
|
21947
21956
|
}
|
|
21957
|
+
// metodo para fechar o alerta realtime e fica tentando verificar a face até 5 vezes
|
|
21958
|
+
async stopRealtimeAlert(alert) {
|
|
21959
|
+
const verifyMaxRetries = 3;
|
|
21960
|
+
const verifyFace = async (verifyCount) => {
|
|
21961
|
+
if (verifyCount > verifyMaxRetries) return;
|
|
21962
|
+
try {
|
|
21963
|
+
var response = await this.backend.stopRealtimeAlert({
|
|
21964
|
+
proctoringId: this.proctoringId,
|
|
21965
|
+
begin: alert.begin,
|
|
21966
|
+
end: alert.end,
|
|
21967
|
+
warningCategoryEnum: this.convertRealtimeTypeToWarningType(alert.type),
|
|
21968
|
+
alertImageBase64: await this.allRecorders.cameraRecorder.getCurrentImageBase64(),
|
|
21969
|
+
retry: verifyCount < verifyMaxRetries - 1 ? true : false
|
|
21970
|
+
});
|
|
21971
|
+
console.log("response stopRealtimeAlert", response);
|
|
21972
|
+
return response;
|
|
21973
|
+
} catch (error) {
|
|
21974
|
+
console.log("error stopRealtimeAlert", error);
|
|
21975
|
+
return verifyFace(verifyCount + 1);
|
|
21976
|
+
}
|
|
21977
|
+
};
|
|
21978
|
+
await verifyFace(1);
|
|
21979
|
+
}
|
|
21948
21980
|
async onRealtimeAlerts(options = {}) {
|
|
21949
21981
|
this.setOnLostFocusAlertRecorderCallback();
|
|
21950
21982
|
this.setOnFocusAlertRecorderCallback();
|
|
@@ -21959,13 +21991,7 @@ var Proctoring = class {
|
|
|
21959
21991
|
alert: this.convertRealtimeCategoryToAlertCategory(response.category)
|
|
21960
21992
|
});
|
|
21961
21993
|
} else if (response.status === "OK") {
|
|
21962
|
-
await this.
|
|
21963
|
-
proctoringId: this.proctoringId,
|
|
21964
|
-
begin: response.begin,
|
|
21965
|
-
end: response.end,
|
|
21966
|
-
warningCategoryEnum: this.convertRealtimeTypeToWarningType(response.type),
|
|
21967
|
-
alertImageBase64: await this.allRecorders.cameraRecorder.getCurrentImageBase64()
|
|
21968
|
-
});
|
|
21994
|
+
await this.stopRealtimeAlert(response);
|
|
21969
21995
|
}
|
|
21970
21996
|
}
|
|
21971
21997
|
};
|
|
@@ -22128,11 +22154,23 @@ Navigator: ${JSON.stringify(_navigator2)}`
|
|
|
22128
22154
|
startResponse.screenStream = this.allRecorders.screenRecorder.screenStream;
|
|
22129
22155
|
}
|
|
22130
22156
|
this.state = "Recording" /* Recording */;
|
|
22131
|
-
|
|
22157
|
+
let verifyFirstFaceIntervalCount = 0;
|
|
22158
|
+
let verifyingFace = false;
|
|
22159
|
+
this.verifyFirstFaceInterval = setInterval(async () => {
|
|
22132
22160
|
if (this.sessionOptions.proctoringType === "REALTIME") {
|
|
22133
|
-
|
|
22161
|
+
if (verifyingFace) return;
|
|
22162
|
+
verifyingFace = true;
|
|
22163
|
+
verifyFirstFaceIntervalCount++;
|
|
22164
|
+
try {
|
|
22165
|
+
var response = await this.backend.verifyFace(this.proctoringId, await this.allRecorders.cameraRecorder.getCurrentImageBase64(), verifyFirstFaceIntervalCount > 5 ? false : true);
|
|
22166
|
+
verifyingFace = false;
|
|
22167
|
+
clearInterval(this.verifyFirstFaceInterval);
|
|
22168
|
+
} catch (error) {
|
|
22169
|
+
verifyingFace = false;
|
|
22170
|
+
return;
|
|
22171
|
+
}
|
|
22134
22172
|
}
|
|
22135
|
-
},
|
|
22173
|
+
}, 1500);
|
|
22136
22174
|
return startResponse;
|
|
22137
22175
|
} catch (error) {
|
|
22138
22176
|
console.log(error);
|
|
@@ -22270,6 +22308,9 @@ Upload Services: ${uploaderServices}`,
|
|
|
22270
22308
|
await this.backend.externalCameraFinish(externalSessionId);
|
|
22271
22309
|
}
|
|
22272
22310
|
}
|
|
22311
|
+
if (this.verifyFirstFaceInterval) {
|
|
22312
|
+
clearInterval(this.verifyFirstFaceInterval);
|
|
22313
|
+
}
|
|
22273
22314
|
this.state = "Stop" /* Stop */;
|
|
22274
22315
|
} catch (error) {
|
|
22275
22316
|
await this.cancel();
|
|
@@ -22657,12 +22698,12 @@ function useProctoring(proctoringOptions, enviromentConfig = "prod") {
|
|
|
22657
22698
|
const photo = new CapturePhoto();
|
|
22658
22699
|
const login = proctoring.login.bind(proctoring);
|
|
22659
22700
|
const originalStart = proctoring.start.bind(proctoring);
|
|
22660
|
-
const start = async (parameters2) => {
|
|
22701
|
+
const start = async (parameters2, videoOptions) => {
|
|
22661
22702
|
const deviceResult = checker.getDeviceCheckResult();
|
|
22662
22703
|
if (deviceResult) {
|
|
22663
22704
|
proctoring.setDeviceCheckData(deviceResult);
|
|
22664
22705
|
}
|
|
22665
|
-
return originalStart(parameters2);
|
|
22706
|
+
return originalStart(parameters2, videoOptions);
|
|
22666
22707
|
};
|
|
22667
22708
|
const finish = proctoring.finish.bind(proctoring);
|
|
22668
22709
|
const startChallenge = proctoring.startChallenge.bind(proctoring);
|
package/index.js
CHANGED
|
@@ -29916,12 +29916,12 @@ var BackendService = class {
|
|
|
29916
29916
|
});
|
|
29917
29917
|
return result.data;
|
|
29918
29918
|
}
|
|
29919
|
-
async verifyFace(proctoringId2, faceImage) {
|
|
29919
|
+
async verifyFace(proctoringId2, faceImage, retry) {
|
|
29920
29920
|
const result = await this.makeRequestAxios({
|
|
29921
29921
|
path: `/Realtime/verify-face`,
|
|
29922
29922
|
method: "POST",
|
|
29923
29923
|
jwt: this.token,
|
|
29924
|
-
body: { "proctoringId": proctoringId2, "base64": faceImage }
|
|
29924
|
+
body: { "proctoringId": proctoringId2, "base64": faceImage, "retry": retry }
|
|
29925
29925
|
});
|
|
29926
29926
|
return result.data;
|
|
29927
29927
|
}
|
|
@@ -30797,7 +30797,6 @@ var CameraRecorder = class {
|
|
|
30797
30797
|
noiseLimit: 40
|
|
30798
30798
|
},
|
|
30799
30799
|
imageBehaviourParameters: {
|
|
30800
|
-
frames: 40,
|
|
30801
30800
|
useUploadImage: true,
|
|
30802
30801
|
uploadInterval: 20,
|
|
30803
30802
|
saveVideo: true
|
|
@@ -30809,7 +30808,6 @@ var CameraRecorder = class {
|
|
|
30809
30808
|
}
|
|
30810
30809
|
};
|
|
30811
30810
|
// private imageParams: ImageParameters = {
|
|
30812
|
-
// frames: 40,
|
|
30813
30811
|
// useUploadImage: true,
|
|
30814
30812
|
// uploadInterval: 20,
|
|
30815
30813
|
// saveVideo: true
|
|
@@ -30901,7 +30899,7 @@ var CameraRecorder = class {
|
|
|
30901
30899
|
}
|
|
30902
30900
|
}
|
|
30903
30901
|
async startRecording(options) {
|
|
30904
|
-
var _a2, _b, _c2, _d, _e3, _f, _g, _h
|
|
30902
|
+
var _a2, _b, _c2, _d, _e3, _f, _g, _h;
|
|
30905
30903
|
if ((((_a2 = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _a2.detectPerson) || ((_b = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _b.detectCellPhone) || ((_c2 = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _c2.detectFace)) && !(options == null ? void 0 : options.retry)) {
|
|
30906
30904
|
await this.initializeDetectors();
|
|
30907
30905
|
}
|
|
@@ -30981,7 +30979,6 @@ Setting: ${JSON.stringify(settings, null, 2)}`
|
|
|
30981
30979
|
this.filesToUpload = [];
|
|
30982
30980
|
if (this.options.proctoringType == "REALTIME") {
|
|
30983
30981
|
this.captureFrame();
|
|
30984
|
-
this.sendFrameInterval = setInterval(() => this.captureFrame(), 1e3 * ((_i3 = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _i3.realtimeUploadInterval));
|
|
30985
30982
|
}
|
|
30986
30983
|
this.packageCount = 0;
|
|
30987
30984
|
}
|
|
@@ -31012,7 +31009,8 @@ Setting: ${JSON.stringify(settings, null, 2)}`
|
|
|
31012
31009
|
clearInterval(this.imageInterval);
|
|
31013
31010
|
clearInterval(this.sendFrameInterval);
|
|
31014
31011
|
if (this.options.proctoringType == "REALTIME" && this.upload && this.backendToken) {
|
|
31015
|
-
await this.sendPackage();
|
|
31012
|
+
await this.sendPackage(this.filesToUpload);
|
|
31013
|
+
await this.filesToUpload.splice(0, this.filesToUpload.length);
|
|
31016
31014
|
}
|
|
31017
31015
|
this.volumeMeter && this.volumeMeter.stop();
|
|
31018
31016
|
this.intervalNoiseDetection && clearInterval(this.intervalNoiseDetection);
|
|
@@ -31082,23 +31080,29 @@ Setting: ${JSON.stringify(settings, null, 2)}`
|
|
|
31082
31080
|
this.canvas.getContext("2d").drawImage(this.video, 0, 0, this.canvas.width, this.canvas.height);
|
|
31083
31081
|
return this.canvas.toDataURL("image/jpeg");
|
|
31084
31082
|
}
|
|
31085
|
-
//
|
|
31083
|
+
// captura um frame a cada intervalo de tempo definido no paramsConfig.videoBehaviourParameters?.realtimeCaptureInterval!
|
|
31086
31084
|
captureFrame() {
|
|
31087
|
-
var _a2;
|
|
31085
|
+
var _a2, _b;
|
|
31088
31086
|
let imageFile;
|
|
31089
31087
|
this.configImageCapture();
|
|
31088
|
+
let newCanvasWidth = this.videoOptions.width / 2;
|
|
31089
|
+
let newCanvasHeight = this.videoOptions.height / 2;
|
|
31090
|
+
if (newCanvasWidth < 320) newCanvasWidth = 320;
|
|
31091
|
+
if (newCanvasHeight < 180) newCanvasHeight = 180;
|
|
31092
|
+
this.canvas.width = newCanvasWidth;
|
|
31093
|
+
this.canvas.height = newCanvasHeight;
|
|
31090
31094
|
const packSize = (_a2 = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _a2.realtimePackageSize;
|
|
31091
|
-
|
|
31092
|
-
this.imageCount++;
|
|
31095
|
+
this.imageCount = 0;
|
|
31093
31096
|
this.imageInterval = setInterval(async () => {
|
|
31097
|
+
console.log("capturando frame " + this.imageCount);
|
|
31094
31098
|
this.canvas.getContext("2d").drawImage(this.video, 0, 0, this.canvas.width, this.canvas.height);
|
|
31095
31099
|
const image_data_url = this.canvas.toDataURL("image/jpeg");
|
|
31096
31100
|
if (this.proctoringId == void 0) return;
|
|
31097
|
-
if (
|
|
31098
|
-
initSend = true;
|
|
31101
|
+
if (packSize == this.imageCount) {
|
|
31099
31102
|
this.imageCount = 0;
|
|
31100
|
-
|
|
31101
|
-
this.sendPackage();
|
|
31103
|
+
const framesToSend = [...this.filesToUpload];
|
|
31104
|
+
this.sendPackage(framesToSend);
|
|
31105
|
+
await this.filesToUpload.splice(0, this.filesToUpload.length);
|
|
31102
31106
|
}
|
|
31103
31107
|
let imageName = `${this.proctoringId}_${this.imageCount + 1}.jpg`;
|
|
31104
31108
|
imageFile = await this.getFile(image_data_url, imageName, "image/jpeg");
|
|
@@ -31106,22 +31110,24 @@ Setting: ${JSON.stringify(settings, null, 2)}`
|
|
|
31106
31110
|
this.filesToUpload.push(imageFile);
|
|
31107
31111
|
this.imageCount++;
|
|
31108
31112
|
}
|
|
31109
|
-
}, 1e3);
|
|
31113
|
+
}, ((_b = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _b.realtimeCaptureInterval) * 1e3);
|
|
31110
31114
|
}
|
|
31111
31115
|
// envia pacote de imagens
|
|
31112
|
-
async sendPackage() {
|
|
31116
|
+
async sendPackage(framesToSend) {
|
|
31117
|
+
var _a2, _b;
|
|
31113
31118
|
let pending = false;
|
|
31114
31119
|
let undeliveredPackagesCount = 0;
|
|
31120
|
+
const packSize = (_a2 = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _a2.realtimePackageSize;
|
|
31121
|
+
const packCaptureInterval = ((_b = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _b.realtimeCaptureInterval) + 1;
|
|
31115
31122
|
if (this.upload && this.backendToken && !pending && this.filesToUpload.length > 0) {
|
|
31116
31123
|
undeliveredPackagesCount = 0;
|
|
31117
31124
|
pending = true;
|
|
31118
31125
|
const zip = new import_jszip_min.default();
|
|
31119
|
-
const
|
|
31120
|
-
for (const file of files) {
|
|
31126
|
+
for (const file of framesToSend) {
|
|
31121
31127
|
zip.file(file.name, file);
|
|
31122
31128
|
}
|
|
31123
31129
|
const blob = await zip.generateAsync({ type: "blob" });
|
|
31124
|
-
let packageName = "realtime_package_" +
|
|
31130
|
+
let packageName = "realtime_package_" + packSize * packCaptureInterval * this.packageCount + ".zip";
|
|
31125
31131
|
const myPackage = new File(
|
|
31126
31132
|
[blob],
|
|
31127
31133
|
packageName,
|
|
@@ -31134,7 +31140,6 @@ Setting: ${JSON.stringify(settings, null, 2)}`
|
|
|
31134
31140
|
this.backendToken
|
|
31135
31141
|
);
|
|
31136
31142
|
if (uploadResult.uploaded == true) {
|
|
31137
|
-
await this.filesToUpload.splice(0, this.filesToUpload.length);
|
|
31138
31143
|
this.packageCount++;
|
|
31139
31144
|
} else {
|
|
31140
31145
|
console.log("erro no upload do pacote");
|
|
@@ -33297,9 +33302,15 @@ var AlertRecorder = class {
|
|
|
33297
33302
|
// HANDLERS (Funções Arrow para preservar o 'this')
|
|
33298
33303
|
// ==========================================
|
|
33299
33304
|
// 1. LOST / RETURN FOCUS
|
|
33305
|
+
this.handleVisibilityChange = () => {
|
|
33306
|
+
if (document.visibilityState === "visible") {
|
|
33307
|
+
this.handleReturnFocus();
|
|
33308
|
+
} else {
|
|
33309
|
+
this.handleLostFocus();
|
|
33310
|
+
}
|
|
33311
|
+
};
|
|
33300
33312
|
this.handleLostFocus = () => {
|
|
33301
33313
|
if (this.getRelativeTime() > 1e4) {
|
|
33302
|
-
this.createAlert(25 /* FocusOff */, 3 /* Screen */, "Usu\xE1rio mudou de aba ou minimizou");
|
|
33303
33314
|
const alertPayload = {
|
|
33304
33315
|
begin: this.getRelativeTime(),
|
|
33305
33316
|
end: 0,
|
|
@@ -33330,7 +33341,7 @@ var AlertRecorder = class {
|
|
|
33330
33341
|
const windowWidth = window.outerWidth;
|
|
33331
33342
|
if (windowWidth < screenWidth * 0.85) {
|
|
33332
33343
|
const msg = `Split Screen Detectado: Janela ocupa ${(windowWidth / screenWidth * 100).toFixed(0)}% da tela`;
|
|
33333
|
-
this.createAlert(
|
|
33344
|
+
this.createAlert(43 /* SplitScreen */, 3 /* Screen */, msg);
|
|
33334
33345
|
this.onRealtimeAlertCallback && this.onRealtimeAlertCallback({
|
|
33335
33346
|
status: "ALERT",
|
|
33336
33347
|
description: msg,
|
|
@@ -33348,7 +33359,7 @@ var AlertRecorder = class {
|
|
|
33348
33359
|
this.handleCopy = (e3) => {
|
|
33349
33360
|
e3.preventDefault();
|
|
33350
33361
|
const msg = "Tentativa de Copiar (Clipboard)";
|
|
33351
|
-
this.createAlert(
|
|
33362
|
+
this.createAlert(42 /* ClipBoardUse */, 3 /* Screen */, msg);
|
|
33352
33363
|
this.onRealtimeAlertCallback && this.onRealtimeAlertCallback({
|
|
33353
33364
|
status: "ALERT",
|
|
33354
33365
|
description: msg,
|
|
@@ -33358,7 +33369,7 @@ var AlertRecorder = class {
|
|
|
33358
33369
|
this.handleCut = (e3) => {
|
|
33359
33370
|
e3.preventDefault();
|
|
33360
33371
|
const msg = "Tentativa de Recortar (Clipboard)";
|
|
33361
|
-
this.createAlert(
|
|
33372
|
+
this.createAlert(42 /* ClipBoardUse */, 3 /* Screen */, msg);
|
|
33362
33373
|
this.onRealtimeAlertCallback && this.onRealtimeAlertCallback({
|
|
33363
33374
|
status: "ALERT",
|
|
33364
33375
|
description: msg,
|
|
@@ -33368,7 +33379,7 @@ var AlertRecorder = class {
|
|
|
33368
33379
|
this.handlePaste = (e3) => {
|
|
33369
33380
|
e3.preventDefault();
|
|
33370
33381
|
const msg = "Tentativa de Colar (Clipboard)";
|
|
33371
|
-
this.createAlert(
|
|
33382
|
+
this.createAlert(42 /* ClipBoardUse */, 3 /* Screen */, msg);
|
|
33372
33383
|
this.onRealtimeAlertCallback && this.onRealtimeAlertCallback({
|
|
33373
33384
|
status: "ALERT",
|
|
33374
33385
|
description: msg,
|
|
@@ -33404,8 +33415,7 @@ var AlertRecorder = class {
|
|
|
33404
33415
|
// ==========================================
|
|
33405
33416
|
attachListeners() {
|
|
33406
33417
|
if (this.optionsProctoring.captureScreen) {
|
|
33407
|
-
window.addEventListener("
|
|
33408
|
-
window.addEventListener("focus", this.handleReturnFocus);
|
|
33418
|
+
window.addEventListener("visibilitychange", this.handleVisibilityChange);
|
|
33409
33419
|
window.addEventListener("resize", this.handleResize);
|
|
33410
33420
|
window.document.addEventListener("copy", this.handleCopy);
|
|
33411
33421
|
window.document.addEventListener("cut", this.handleCut);
|
|
@@ -33413,8 +33423,7 @@ var AlertRecorder = class {
|
|
|
33413
33423
|
}
|
|
33414
33424
|
}
|
|
33415
33425
|
detachListeners() {
|
|
33416
|
-
window.removeEventListener("
|
|
33417
|
-
window.removeEventListener("focus", this.handleReturnFocus);
|
|
33426
|
+
window.removeEventListener("visibilitychange", this.handleVisibilityChange);
|
|
33418
33427
|
window.removeEventListener("resize", this.handleResize);
|
|
33419
33428
|
window.document.removeEventListener("copy", this.handleCopy);
|
|
33420
33429
|
window.document.removeEventListener("cut", this.handleCut);
|
|
@@ -33449,7 +33458,7 @@ var AlertRecorder = class {
|
|
|
33449
33458
|
// }
|
|
33450
33459
|
// 4. BACKGROUND EVENTS (Eventos disparados manualmente)
|
|
33451
33460
|
addBackgroundEvent(description, category = 200 /* System */) {
|
|
33452
|
-
this.createAlert(category,
|
|
33461
|
+
this.createAlert(category, 3 /* Screen */, description);
|
|
33453
33462
|
this.onRealtimeAlertCallback && this.onRealtimeAlertCallback({
|
|
33454
33463
|
status: "ALERT",
|
|
33455
33464
|
description,
|
|
@@ -36839,7 +36848,8 @@ var _ExternalCameraChecker = class _ExternalCameraChecker {
|
|
|
36839
36848
|
this.connection = new import_signalr.HubConnectionBuilder().withUrl(hubUrl, {
|
|
36840
36849
|
accessTokenFactory: () => this.context.token,
|
|
36841
36850
|
transport: import_signalr.HttpTransportType.WebSockets,
|
|
36842
|
-
withCredentials: false
|
|
36851
|
+
withCredentials: false,
|
|
36852
|
+
skipNegotiation: true
|
|
36843
36853
|
}).withAutomaticReconnect().configureLogging(import_signalr.LogLevel.Information).build();
|
|
36844
36854
|
this.connection.on(
|
|
36845
36855
|
"ReceiveMessage",
|
|
@@ -37046,7 +37056,6 @@ var Proctoring = class {
|
|
|
37046
37056
|
noiseLimit: 40
|
|
37047
37057
|
},
|
|
37048
37058
|
imageBehaviourParameters: {
|
|
37049
|
-
frames: 40,
|
|
37050
37059
|
useUploadImage: true,
|
|
37051
37060
|
uploadInterval: 20,
|
|
37052
37061
|
saveVideo: true
|
|
@@ -37057,8 +37066,8 @@ var Proctoring = class {
|
|
|
37057
37066
|
detectCellPhone: false,
|
|
37058
37067
|
detectNoise: false,
|
|
37059
37068
|
detectSpeech: false,
|
|
37060
|
-
realtimePackageSize:
|
|
37061
|
-
|
|
37069
|
+
realtimePackageSize: 10,
|
|
37070
|
+
realtimeCaptureInterval: 2
|
|
37062
37071
|
}
|
|
37063
37072
|
};
|
|
37064
37073
|
this.proctoringId = "";
|
|
@@ -37194,6 +37203,29 @@ var Proctoring = class {
|
|
|
37194
37203
|
return null;
|
|
37195
37204
|
}
|
|
37196
37205
|
}
|
|
37206
|
+
// metodo para fechar o alerta realtime e fica tentando verificar a face até 5 vezes
|
|
37207
|
+
async stopRealtimeAlert(alert) {
|
|
37208
|
+
const verifyMaxRetries = 3;
|
|
37209
|
+
const verifyFace = async (verifyCount) => {
|
|
37210
|
+
if (verifyCount > verifyMaxRetries) return;
|
|
37211
|
+
try {
|
|
37212
|
+
var response = await this.backend.stopRealtimeAlert({
|
|
37213
|
+
proctoringId: this.proctoringId,
|
|
37214
|
+
begin: alert.begin,
|
|
37215
|
+
end: alert.end,
|
|
37216
|
+
warningCategoryEnum: this.convertRealtimeTypeToWarningType(alert.type),
|
|
37217
|
+
alertImageBase64: await this.allRecorders.cameraRecorder.getCurrentImageBase64(),
|
|
37218
|
+
retry: verifyCount < verifyMaxRetries - 1 ? true : false
|
|
37219
|
+
});
|
|
37220
|
+
console.log("response stopRealtimeAlert", response);
|
|
37221
|
+
return response;
|
|
37222
|
+
} catch (error) {
|
|
37223
|
+
console.log("error stopRealtimeAlert", error);
|
|
37224
|
+
return verifyFace(verifyCount + 1);
|
|
37225
|
+
}
|
|
37226
|
+
};
|
|
37227
|
+
await verifyFace(1);
|
|
37228
|
+
}
|
|
37197
37229
|
async onRealtimeAlerts(options = {}) {
|
|
37198
37230
|
this.setOnLostFocusAlertRecorderCallback();
|
|
37199
37231
|
this.setOnFocusAlertRecorderCallback();
|
|
@@ -37208,13 +37240,7 @@ var Proctoring = class {
|
|
|
37208
37240
|
alert: this.convertRealtimeCategoryToAlertCategory(response.category)
|
|
37209
37241
|
});
|
|
37210
37242
|
} else if (response.status === "OK") {
|
|
37211
|
-
await this.
|
|
37212
|
-
proctoringId: this.proctoringId,
|
|
37213
|
-
begin: response.begin,
|
|
37214
|
-
end: response.end,
|
|
37215
|
-
warningCategoryEnum: this.convertRealtimeTypeToWarningType(response.type),
|
|
37216
|
-
alertImageBase64: await this.allRecorders.cameraRecorder.getCurrentImageBase64()
|
|
37217
|
-
});
|
|
37243
|
+
await this.stopRealtimeAlert(response);
|
|
37218
37244
|
}
|
|
37219
37245
|
}
|
|
37220
37246
|
};
|
|
@@ -37377,11 +37403,23 @@ Navigator: ${JSON.stringify(_navigator2)}`
|
|
|
37377
37403
|
startResponse.screenStream = this.allRecorders.screenRecorder.screenStream;
|
|
37378
37404
|
}
|
|
37379
37405
|
this.state = "Recording" /* Recording */;
|
|
37380
|
-
|
|
37406
|
+
let verifyFirstFaceIntervalCount = 0;
|
|
37407
|
+
let verifyingFace = false;
|
|
37408
|
+
this.verifyFirstFaceInterval = setInterval(async () => {
|
|
37381
37409
|
if (this.sessionOptions.proctoringType === "REALTIME") {
|
|
37382
|
-
|
|
37410
|
+
if (verifyingFace) return;
|
|
37411
|
+
verifyingFace = true;
|
|
37412
|
+
verifyFirstFaceIntervalCount++;
|
|
37413
|
+
try {
|
|
37414
|
+
var response = await this.backend.verifyFace(this.proctoringId, await this.allRecorders.cameraRecorder.getCurrentImageBase64(), verifyFirstFaceIntervalCount > 5 ? false : true);
|
|
37415
|
+
verifyingFace = false;
|
|
37416
|
+
clearInterval(this.verifyFirstFaceInterval);
|
|
37417
|
+
} catch (error) {
|
|
37418
|
+
verifyingFace = false;
|
|
37419
|
+
return;
|
|
37420
|
+
}
|
|
37383
37421
|
}
|
|
37384
|
-
},
|
|
37422
|
+
}, 1500);
|
|
37385
37423
|
return startResponse;
|
|
37386
37424
|
} catch (error) {
|
|
37387
37425
|
console.log(error);
|
|
@@ -37519,6 +37557,9 @@ Upload Services: ${uploaderServices}`,
|
|
|
37519
37557
|
await this.backend.externalCameraFinish(externalSessionId);
|
|
37520
37558
|
}
|
|
37521
37559
|
}
|
|
37560
|
+
if (this.verifyFirstFaceInterval) {
|
|
37561
|
+
clearInterval(this.verifyFirstFaceInterval);
|
|
37562
|
+
}
|
|
37522
37563
|
this.state = "Stop" /* Stop */;
|
|
37523
37564
|
} catch (error) {
|
|
37524
37565
|
await this.cancel();
|
|
@@ -37906,12 +37947,12 @@ function useProctoring(proctoringOptions, enviromentConfig = "prod") {
|
|
|
37906
37947
|
const photo = new CapturePhoto();
|
|
37907
37948
|
const login = proctoring.login.bind(proctoring);
|
|
37908
37949
|
const originalStart = proctoring.start.bind(proctoring);
|
|
37909
|
-
const start = async (parameters2) => {
|
|
37950
|
+
const start = async (parameters2, videoOptions) => {
|
|
37910
37951
|
const deviceResult = checker.getDeviceCheckResult();
|
|
37911
37952
|
if (deviceResult) {
|
|
37912
37953
|
proctoring.setDeviceCheckData(deviceResult);
|
|
37913
37954
|
}
|
|
37914
|
-
return originalStart(parameters2);
|
|
37955
|
+
return originalStart(parameters2, videoOptions);
|
|
37915
37956
|
};
|
|
37916
37957
|
const finish = proctoring.finish.bind(proctoring);
|
|
37917
37958
|
const startChallenge = proctoring.startChallenge.bind(proctoring);
|