easyproctor 2.4.0 → 2.5.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/README.md +15 -0
- package/esm/index.js +431 -82
- package/index.js +431 -82
- package/interfaces/Devices.d.ts +1 -0
- package/modules/BaseDetection.d.ts +1 -0
- package/modules/faceDetection.d.ts +2 -0
- package/modules/objectDetection.d.ts +1 -0
- package/modules/onChangeDevices.d.ts +4 -1
- package/new-flow/backend/BackendService.d.ts +9 -2
- package/new-flow/proctoring/ProctoringSession.d.ts +11 -1
- package/new-flow/recorders/AlertRecorder.d.ts +5 -1
- package/new-flow/recorders/CameraRecorder.d.ts +6 -0
- package/new-flow/recorders/ScreenRecorder.d.ts +4 -0
- package/package.json +1 -1
- package/plugins/insights.d.ts +1 -0
- package/proctoring/options/ProctoringOptions.d.ts +5 -0
- package/proctoring/proctoring.d.ts +5 -0
- package/proctoring/useProctoring.d.ts +1 -1
- package/unpkg/easyproctor.min.js +39 -39
package/index.js
CHANGED
|
@@ -23563,6 +23563,7 @@ var BaseDetection = class {
|
|
|
23563
23563
|
this.modelAssetPath = modelAssetPath;
|
|
23564
23564
|
this.classVideo = classVideo;
|
|
23565
23565
|
this.classDiv = classDiv;
|
|
23566
|
+
this.startTime = new Date(Date.now());
|
|
23566
23567
|
paramsConfig && (this.paramsConfig = paramsConfig);
|
|
23567
23568
|
options && (this.options = options);
|
|
23568
23569
|
}
|
|
@@ -23652,15 +23653,22 @@ var BaseDetection = class {
|
|
|
23652
23653
|
this.options.onRealtimeAlertsCallback && this.options.onRealtimeAlertsCallback({
|
|
23653
23654
|
status: "ALERT",
|
|
23654
23655
|
description: this.alertTranslate(description),
|
|
23655
|
-
type
|
|
23656
|
+
type,
|
|
23657
|
+
category: description,
|
|
23658
|
+
begin: Date.now() - this.startTime.getTime(),
|
|
23659
|
+
end: Date.now() - this.startTime.getTime()
|
|
23656
23660
|
});
|
|
23657
|
-
|
|
23661
|
+
if (this.options.onRealtimeAlertsCallback == null)
|
|
23662
|
+
this.error && (this.error.innerText = description);
|
|
23658
23663
|
}
|
|
23659
23664
|
handleOk(description, type) {
|
|
23660
23665
|
this.options.onRealtimeAlertsCallback && this.options.onRealtimeAlertsCallback({
|
|
23661
23666
|
status: "OK",
|
|
23662
23667
|
description: this.alertTranslate(description),
|
|
23663
|
-
type
|
|
23668
|
+
type,
|
|
23669
|
+
category: description,
|
|
23670
|
+
begin: Date.now() - this.startTime.getTime(),
|
|
23671
|
+
end: Date.now() - this.startTime.getTime()
|
|
23664
23672
|
});
|
|
23665
23673
|
this.error && (this.error.innerText = "");
|
|
23666
23674
|
}
|
|
@@ -23690,6 +23698,18 @@ var BaseDetection = class {
|
|
|
23690
23698
|
return "Face detectada";
|
|
23691
23699
|
case "ok_position_face_detected":
|
|
23692
23700
|
return "Face na posi\xE7\xE3o correta";
|
|
23701
|
+
case "wrong_face_size_detected":
|
|
23702
|
+
return "Face muito perto da c\xE2mera, afaste-se um pouco mais";
|
|
23703
|
+
case "wrong_face_position_edge_detected":
|
|
23704
|
+
return "Face muito pr\xF3xima da borda, mova-se para o centro da tela";
|
|
23705
|
+
case "wrong_face_position_move_right_detected":
|
|
23706
|
+
return "Face n\xE3o centralizada, mova-se para a direita";
|
|
23707
|
+
case "wrong_face_position_move_left_detected":
|
|
23708
|
+
return "Face n\xE3o centralizada, mova-se para a esquerda";
|
|
23709
|
+
case "wrong_face_position_move_top_detected":
|
|
23710
|
+
return "Face n\xE3o centralizada, mova-se para cima";
|
|
23711
|
+
case "wrong_face_position_move_bottom_detected":
|
|
23712
|
+
return "Face n\xE3o centralizada, mova-se para baixo";
|
|
23693
23713
|
default:
|
|
23694
23714
|
return description;
|
|
23695
23715
|
}
|
|
@@ -23722,6 +23742,13 @@ var FaceDetection = class extends BaseDetection {
|
|
|
23722
23742
|
constructor(options, paramsConfig, classVideo = "videoPreviewFrameDetection", classDiv = "liveViewFrameDetection") {
|
|
23723
23743
|
super("FaceDetector", `https://storage.googleapis.com/mediapipe-models/face_detector/blaze_face_short_range/float16/1/blaze_face_short_range.tflite`, options, paramsConfig, classVideo, classDiv);
|
|
23724
23744
|
this.emmitedPositionAlert = false;
|
|
23745
|
+
this.emmitedFaceAlert = false;
|
|
23746
|
+
}
|
|
23747
|
+
stopDetection() {
|
|
23748
|
+
super.stopDetection();
|
|
23749
|
+
if (this.emmitedFaceAlert) {
|
|
23750
|
+
this.handleOk("face_ok", "face_detection_on_stream");
|
|
23751
|
+
}
|
|
23725
23752
|
}
|
|
23726
23753
|
displayVideoDetections(result) {
|
|
23727
23754
|
for (const child of this.children) {
|
|
@@ -23784,31 +23811,71 @@ var FaceDetection = class extends BaseDetection {
|
|
|
23784
23811
|
}
|
|
23785
23812
|
}
|
|
23786
23813
|
verify(result) {
|
|
23787
|
-
var _a2
|
|
23814
|
+
var _a2;
|
|
23788
23815
|
if (((_a2 = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _a2.detectFace) && result.detections.length !== this.numFacesSent) {
|
|
23789
23816
|
this.numFacesSent = result.detections.length;
|
|
23790
23817
|
if (result.detections.length === 0) {
|
|
23791
23818
|
this.handleAlert("no_face_detected", "face_detection_on_stream");
|
|
23819
|
+
this.emmitedFaceAlert = true;
|
|
23820
|
+
return;
|
|
23792
23821
|
} else if (result.detections.length > 1) {
|
|
23793
23822
|
this.handleAlert("multiple_faces_detected", "face_detection_on_stream");
|
|
23823
|
+
this.emmitedFaceAlert = true;
|
|
23824
|
+
return;
|
|
23794
23825
|
} else {
|
|
23795
23826
|
this.handleOk("face_ok", "face_detection_on_stream");
|
|
23796
|
-
|
|
23797
|
-
|
|
23798
|
-
|
|
23799
|
-
if (
|
|
23800
|
-
|
|
23827
|
+
this.emmitedFaceAlert = false;
|
|
23828
|
+
}
|
|
23829
|
+
}
|
|
23830
|
+
if (result.detections.length === 0) return;
|
|
23831
|
+
let face = result.detections[0].boundingBox;
|
|
23832
|
+
let video = document.getElementById(this.classVideo);
|
|
23833
|
+
const imageWidth = video.videoWidth;
|
|
23834
|
+
const imageHeight = video.videoHeight;
|
|
23835
|
+
let failedFacePosition = false;
|
|
23836
|
+
if (imageWidth > imageHeight) {
|
|
23837
|
+
if (face.height / imageHeight > 0.7) {
|
|
23838
|
+
!this.emmitedPositionAlert && this.handleAlert("wrong_face_size_detected", "position_detection_on_stream");
|
|
23839
|
+
failedFacePosition = true;
|
|
23840
|
+
this.emmitedPositionAlert = true;
|
|
23841
|
+
} else if (face.width / imageWidth > 0.7) {
|
|
23842
|
+
!this.emmitedPositionAlert && this.handleAlert("wrong_face_size_detected", "position_detection_on_stream");
|
|
23843
|
+
this.emmitedPositionAlert = true;
|
|
23844
|
+
failedFacePosition = true;
|
|
23845
|
+
}
|
|
23846
|
+
}
|
|
23847
|
+
let start = [face.originX, face.originY];
|
|
23848
|
+
let end = [face.originX + face.width, face.originY + face.height];
|
|
23849
|
+
if (start[0] < 0.1 * face.width || start[1] < 0.2 * face.height || end[0] > imageWidth - 0.1 * face.width || end[1] > imageHeight - 5) {
|
|
23850
|
+
!this.emmitedPositionAlert && this.handleAlert("wrong_face_position_edge_detected", "position_detection_on_stream");
|
|
23801
23851
|
this.emmitedPositionAlert = true;
|
|
23802
|
-
|
|
23803
|
-
|
|
23852
|
+
failedFacePosition = true;
|
|
23853
|
+
}
|
|
23854
|
+
let leftGap = start[0];
|
|
23855
|
+
let rightGap = imageWidth - end[0];
|
|
23856
|
+
let topGap = start[1];
|
|
23857
|
+
let bottomGap = imageHeight - end[1];
|
|
23858
|
+
if (leftGap > 2 * rightGap) {
|
|
23859
|
+
!this.emmitedPositionAlert && this.handleAlert("wrong_face_position_move_right_detected", "position_detection_on_stream");
|
|
23804
23860
|
this.emmitedPositionAlert = true;
|
|
23805
|
-
|
|
23806
|
-
|
|
23861
|
+
failedFacePosition = true;
|
|
23862
|
+
}
|
|
23863
|
+
if (topGap > 4 * bottomGap) {
|
|
23864
|
+
!this.emmitedPositionAlert && this.handleAlert("wrong_face_position_move_top_detected", "position_detection_on_stream");
|
|
23807
23865
|
this.emmitedPositionAlert = true;
|
|
23808
|
-
|
|
23809
|
-
|
|
23866
|
+
failedFacePosition = true;
|
|
23867
|
+
}
|
|
23868
|
+
if (rightGap > 2 * leftGap) {
|
|
23869
|
+
!this.emmitedPositionAlert && this.handleAlert("wrong_face_position_move_left_detected", "position_detection_on_stream");
|
|
23810
23870
|
this.emmitedPositionAlert = true;
|
|
23811
|
-
|
|
23871
|
+
failedFacePosition = true;
|
|
23872
|
+
}
|
|
23873
|
+
if (bottomGap > 3 * topGap) {
|
|
23874
|
+
!this.emmitedPositionAlert && this.handleAlert("wrong_face_position_move_bottom_detected", "position_detection_on_stream");
|
|
23875
|
+
this.emmitedPositionAlert = true;
|
|
23876
|
+
failedFacePosition = true;
|
|
23877
|
+
}
|
|
23878
|
+
if (failedFacePosition == false) {
|
|
23812
23879
|
this.emmitedPositionAlert && this.handleOk("ok_position_face_detected", "position_detection_on_stream");
|
|
23813
23880
|
this.emmitedPositionAlert = false;
|
|
23814
23881
|
}
|
|
@@ -27183,6 +27250,14 @@ var BackendService = class {
|
|
|
27183
27250
|
jwt: this.token
|
|
27184
27251
|
});
|
|
27185
27252
|
}
|
|
27253
|
+
async goToExternalCameraPositionStep(externalSessionId) {
|
|
27254
|
+
return await this.makeRequest({
|
|
27255
|
+
path: `/ExternalCamera/go-to-position-step/${externalSessionId}`,
|
|
27256
|
+
method: "POST",
|
|
27257
|
+
body: {},
|
|
27258
|
+
jwt: this.token
|
|
27259
|
+
});
|
|
27260
|
+
}
|
|
27186
27261
|
async externalCameraFinish(externalSessionId) {
|
|
27187
27262
|
return await this.makeRequest({
|
|
27188
27263
|
path: `/ExternalCamera/finish/${externalSessionId}`,
|
|
@@ -27191,15 +27266,16 @@ var BackendService = class {
|
|
|
27191
27266
|
jwt: this.token
|
|
27192
27267
|
});
|
|
27193
27268
|
}
|
|
27194
|
-
async confirmStart(proctoringOptions,
|
|
27269
|
+
async confirmStart(proctoringOptions, sessionOptions, latitude, longitude) {
|
|
27195
27270
|
return await this.makeRequest({
|
|
27196
27271
|
path: `/proctoring/start/${proctoringOptions.examId}`,
|
|
27197
27272
|
method: "POST",
|
|
27198
27273
|
body: {
|
|
27199
27274
|
clientId: proctoringOptions.clientId,
|
|
27200
|
-
proctoringType,
|
|
27275
|
+
proctoringType: sessionOptions.proctoringType,
|
|
27201
27276
|
latitude,
|
|
27202
|
-
longitude
|
|
27277
|
+
longitude,
|
|
27278
|
+
captureScreen: sessionOptions.captureScreen
|
|
27203
27279
|
},
|
|
27204
27280
|
jwt: proctoringOptions.token
|
|
27205
27281
|
});
|
|
@@ -27246,8 +27322,8 @@ var BackendService = class {
|
|
|
27246
27322
|
}
|
|
27247
27323
|
});
|
|
27248
27324
|
}
|
|
27249
|
-
async finishAndSendUrls(proctoringOptions
|
|
27250
|
-
await this.makeRequest({
|
|
27325
|
+
async finishAndSendUrls(proctoringOptions) {
|
|
27326
|
+
return await this.makeRequest({
|
|
27251
27327
|
path: `/proctoring/finish/${proctoringOptions.examId}`,
|
|
27252
27328
|
method: "POST",
|
|
27253
27329
|
body: {
|
|
@@ -27293,6 +27369,51 @@ var BackendService = class {
|
|
|
27293
27369
|
});
|
|
27294
27370
|
return result.data;
|
|
27295
27371
|
}
|
|
27372
|
+
async startChallenge(body) {
|
|
27373
|
+
const result = await this.makeRequestAxios({
|
|
27374
|
+
path: `/Challenge/start`,
|
|
27375
|
+
method: "POST",
|
|
27376
|
+
jwt: this.token,
|
|
27377
|
+
body
|
|
27378
|
+
});
|
|
27379
|
+
return result.data;
|
|
27380
|
+
}
|
|
27381
|
+
async stopChallenge(challengeId, body) {
|
|
27382
|
+
const result = await this.makeRequestAxios({
|
|
27383
|
+
path: `/Challenge/stop/${challengeId}`,
|
|
27384
|
+
method: "POST",
|
|
27385
|
+
jwt: this.token,
|
|
27386
|
+
body
|
|
27387
|
+
});
|
|
27388
|
+
return result.data;
|
|
27389
|
+
}
|
|
27390
|
+
async startRealtimeAlert(body) {
|
|
27391
|
+
const result = await this.makeRequestAxios({
|
|
27392
|
+
path: `/Realtime/start-warning`,
|
|
27393
|
+
method: "POST",
|
|
27394
|
+
jwt: this.token,
|
|
27395
|
+
body
|
|
27396
|
+
});
|
|
27397
|
+
return result.data;
|
|
27398
|
+
}
|
|
27399
|
+
async stopRealtimeAlert(body) {
|
|
27400
|
+
const result = await this.makeRequestAxios({
|
|
27401
|
+
path: `/Realtime/stop-warning`,
|
|
27402
|
+
method: "POST",
|
|
27403
|
+
jwt: this.token,
|
|
27404
|
+
body
|
|
27405
|
+
});
|
|
27406
|
+
return result.data;
|
|
27407
|
+
}
|
|
27408
|
+
async verifyFace(proctoringId2, faceImage) {
|
|
27409
|
+
const result = await this.makeRequestAxios({
|
|
27410
|
+
path: `/Realtime/verify-face`,
|
|
27411
|
+
method: "POST",
|
|
27412
|
+
jwt: this.token,
|
|
27413
|
+
body: { "proctoringId": proctoringId2, "base64": faceImage }
|
|
27414
|
+
});
|
|
27415
|
+
return result.data;
|
|
27416
|
+
}
|
|
27296
27417
|
async getServerHour(token) {
|
|
27297
27418
|
return await this.makeRequest({
|
|
27298
27419
|
path: `/Proctoring/server-hour`,
|
|
@@ -27620,7 +27741,9 @@ var getDefaultProctoringOptions = {
|
|
|
27620
27741
|
onBufferSizeError: false,
|
|
27621
27742
|
useGeolocation: false,
|
|
27622
27743
|
useSpyScan: false,
|
|
27623
|
-
useExternalCamera: false
|
|
27744
|
+
useExternalCamera: false,
|
|
27745
|
+
useChallenge: false,
|
|
27746
|
+
screenRecorderOptions: { width: 1280, height: 720 }
|
|
27624
27747
|
};
|
|
27625
27748
|
|
|
27626
27749
|
// src/proctoring/options/ProctoringVideoOptions.ts
|
|
@@ -27679,6 +27802,7 @@ var init = (backend) => {
|
|
|
27679
27802
|
return backendService;
|
|
27680
27803
|
};
|
|
27681
27804
|
var eventNames = {
|
|
27805
|
+
DEVICES_CHECKED: "devices_checked",
|
|
27682
27806
|
START: "start",
|
|
27683
27807
|
FINISH: "finish",
|
|
27684
27808
|
ERROR: "error",
|
|
@@ -27695,6 +27819,7 @@ var eventNames = {
|
|
|
27695
27819
|
};
|
|
27696
27820
|
var log = (eventName, properties) => backendService && backendService.log(eventName, properties);
|
|
27697
27821
|
var trackers = {
|
|
27822
|
+
registerDevicesChecked: (proctoringId2, success, description) => log(eventNames.DEVICES_CHECKED, { proctoringId: proctoringId2, success, description }),
|
|
27698
27823
|
registerStart: (proctoringId2, success, description) => log(eventNames.START, { proctoringId: proctoringId2, success, description }),
|
|
27699
27824
|
registerFinish: (proctoringId2, success, description) => log(eventNames.FINISH, { proctoringId: proctoringId2, success, description }),
|
|
27700
27825
|
registerError: (proctoringId2, description) => log(eventNames.ERROR, { proctoringId: proctoringId2, description }),
|
|
@@ -27985,6 +28110,12 @@ var ObjectDetection = class extends BaseDetection {
|
|
|
27985
28110
|
constructor(options, paramsConfig, classVideo = "videoPreviewFrameDetection", classDiv = "liveViewFrameDetection") {
|
|
27986
28111
|
super("ObjectDetector", `https://storage.googleapis.com/mediapipe-models/object_detector/efficientdet_lite0/float16/1/efficientdet_lite0.tflite`, options, paramsConfig, classVideo, classDiv);
|
|
27987
28112
|
}
|
|
28113
|
+
stopDetection() {
|
|
28114
|
+
super.stopDetection();
|
|
28115
|
+
if (this.numPersonsSent > 0) {
|
|
28116
|
+
this.handleOk("person_ok", "person_detection_on_stream");
|
|
28117
|
+
}
|
|
28118
|
+
}
|
|
27988
28119
|
displayVideoDetections(result) {
|
|
27989
28120
|
for (const child of this.children) {
|
|
27990
28121
|
this.liveView.removeChild(child);
|
|
@@ -28159,6 +28290,10 @@ var CameraRecorder = class {
|
|
|
28159
28290
|
this.blobsRTC = [];
|
|
28160
28291
|
this.imageCount = 0;
|
|
28161
28292
|
this.filesToUpload = [];
|
|
28293
|
+
this.animationFrameId = null;
|
|
28294
|
+
this.isCanvasLoopActive = false;
|
|
28295
|
+
this.hardwareStream = null;
|
|
28296
|
+
this.internalClonedStream = null;
|
|
28162
28297
|
this.currentRetries = 0;
|
|
28163
28298
|
this.noiseWait = 20;
|
|
28164
28299
|
this.options = options;
|
|
@@ -28220,7 +28355,7 @@ var CameraRecorder = class {
|
|
|
28220
28355
|
}
|
|
28221
28356
|
}
|
|
28222
28357
|
async startRecording(options) {
|
|
28223
|
-
var _a2, _b, _c2, _d, _e3, _f, _g
|
|
28358
|
+
var _a2, _b, _c2, _d, _e3, _f, _g;
|
|
28224
28359
|
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)) {
|
|
28225
28360
|
await this.initializeDetectors();
|
|
28226
28361
|
}
|
|
@@ -28235,7 +28370,7 @@ var CameraRecorder = class {
|
|
|
28235
28370
|
}
|
|
28236
28371
|
};
|
|
28237
28372
|
try {
|
|
28238
|
-
this.
|
|
28373
|
+
this.hardwareStream = await navigator.mediaDevices.getUserMedia(
|
|
28239
28374
|
constraints
|
|
28240
28375
|
);
|
|
28241
28376
|
} catch (error) {
|
|
@@ -28243,6 +28378,16 @@ var CameraRecorder = class {
|
|
|
28243
28378
|
throw "N\xE3o foi poss\xEDvel conectar a camera, ela pode estar sendo utilizada por outro programa";
|
|
28244
28379
|
throw error;
|
|
28245
28380
|
}
|
|
28381
|
+
this.cameraStream = this.hardwareStream;
|
|
28382
|
+
const track = this.cameraStream.getVideoTracks()[0];
|
|
28383
|
+
const settings = track.getSettings();
|
|
28384
|
+
const { width = 0, height = 0 } = settings;
|
|
28385
|
+
const needsRotationFix = isMobileDevice() && width > height;
|
|
28386
|
+
this.isCanvasLoopActive = true;
|
|
28387
|
+
if (needsRotationFix) {
|
|
28388
|
+
console.log("Aplicando corre\xE7\xE3o e substituindo stream p\xFAblico...");
|
|
28389
|
+
this.cameraStream = this.createRotatedStream(this.hardwareStream);
|
|
28390
|
+
}
|
|
28246
28391
|
const {
|
|
28247
28392
|
startRecording,
|
|
28248
28393
|
stopRecording,
|
|
@@ -28252,6 +28397,7 @@ var CameraRecorder = class {
|
|
|
28252
28397
|
getBufferSize
|
|
28253
28398
|
} = recorder(
|
|
28254
28399
|
this.cameraStream,
|
|
28400
|
+
// streamToRecord,
|
|
28255
28401
|
this.blobs,
|
|
28256
28402
|
this.options.onBufferSizeError,
|
|
28257
28403
|
(e3) => this.bufferError(e3),
|
|
@@ -28264,25 +28410,6 @@ var CameraRecorder = class {
|
|
|
28264
28410
|
this.recorderOptions = recorderOptions;
|
|
28265
28411
|
this.getBufferSize = getBufferSize;
|
|
28266
28412
|
this.recordingStart();
|
|
28267
|
-
const tracks = this.cameraStream.getVideoTracks();
|
|
28268
|
-
const settings = tracks[0].getSettings();
|
|
28269
|
-
let { width = 0, height = 0 } = settings;
|
|
28270
|
-
const isPortrait = (_d = screen.orientation) == null ? void 0 : _d.type.includes("portrait");
|
|
28271
|
-
if (isPortrait && isMobileDevice()) {
|
|
28272
|
-
if (this.videoOptions.width == height && this.videoOptions.height == width) {
|
|
28273
|
-
[width, height] = [height, width];
|
|
28274
|
-
}
|
|
28275
|
-
}
|
|
28276
|
-
console.log("isPortrait -> ", isPortrait);
|
|
28277
|
-
console.log("this.isMobileDevice() -> ", isMobileDevice());
|
|
28278
|
-
console.log("width -> ", width);
|
|
28279
|
-
console.log("height -> ", height);
|
|
28280
|
-
console.log("minWidth -> ", this.videoOptions.minWidth);
|
|
28281
|
-
console.log("minHeight -> ", this.videoOptions.minHeight);
|
|
28282
|
-
console.log("this.videoOptions.width -> ", this.videoOptions.width);
|
|
28283
|
-
console.log("this.videoOptions.height -> ", this.videoOptions.height);
|
|
28284
|
-
console.log("settings.width -> ", settings.width);
|
|
28285
|
-
console.log("settings.height -> ", settings.height);
|
|
28286
28413
|
if (this.videoOptions.minWidth > width || this.videoOptions.minHeight > height) {
|
|
28287
28414
|
throw STREAM_UNDER_MINIMUM_PERMITTED;
|
|
28288
28415
|
} else if (this.videoOptions.width !== width || this.videoOptions.height !== height) {
|
|
@@ -28298,18 +28425,37 @@ Setting: ${JSON.stringify(settings, null, 2)}`
|
|
|
28298
28425
|
);
|
|
28299
28426
|
throw ANOTHER_STREAM_ACTIVE;
|
|
28300
28427
|
}
|
|
28301
|
-
((
|
|
28302
|
-
if ((
|
|
28428
|
+
((_d = this.paramsConfig.imageBehaviourParameters) == null ? void 0 : _d.useUploadImage) && this.options.proctoringType == "IMAGE" && this.photoShotsCycle();
|
|
28429
|
+
if ((_e3 = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _e3.detectFace) {
|
|
28303
28430
|
await this.faceDetection.enableCam(this.cameraStream);
|
|
28304
28431
|
}
|
|
28305
|
-
if (((
|
|
28432
|
+
if (((_f = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _f.detectPerson) || ((_g = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _g.detectCellPhone)) {
|
|
28306
28433
|
await this.objectDetection.enableCam(this.cameraStream);
|
|
28307
28434
|
}
|
|
28308
28435
|
this.filesToUpload = [];
|
|
28309
|
-
this.options.proctoringType == "REALTIME" && this.captureFrame();
|
|
28310
28436
|
}
|
|
28311
28437
|
async stopRecording() {
|
|
28438
|
+
this.isCanvasLoopActive = false;
|
|
28312
28439
|
this.recordingStop && await this.recordingStop();
|
|
28440
|
+
try {
|
|
28441
|
+
if (this.animationFrameId) {
|
|
28442
|
+
cancelAnimationFrame(this.animationFrameId);
|
|
28443
|
+
this.animationFrameId = null;
|
|
28444
|
+
}
|
|
28445
|
+
if (this.cameraStream) {
|
|
28446
|
+
this.cameraStream.getTracks().forEach((track) => track.stop());
|
|
28447
|
+
}
|
|
28448
|
+
if (this.internalClonedStream) {
|
|
28449
|
+
this.internalClonedStream.getTracks().forEach((track) => track.stop());
|
|
28450
|
+
this.internalClonedStream = null;
|
|
28451
|
+
}
|
|
28452
|
+
if (this.hardwareStream) {
|
|
28453
|
+
this.hardwareStream.getTracks().forEach((track) => track.stop());
|
|
28454
|
+
this.hardwareStream = null;
|
|
28455
|
+
}
|
|
28456
|
+
} catch {
|
|
28457
|
+
console.error("Erro ao parar os streams de m\xEDdia.");
|
|
28458
|
+
}
|
|
28313
28459
|
this.faceDetection && this.faceDetection.detecting && this.faceDetection.stopDetection();
|
|
28314
28460
|
this.objectDetection && this.objectDetection.detecting && this.objectDetection.stopDetection();
|
|
28315
28461
|
clearInterval(this.imageInterval);
|
|
@@ -28376,6 +28522,36 @@ Setting: ${JSON.stringify(settings, null, 2)}`
|
|
|
28376
28522
|
}
|
|
28377
28523
|
}, this.paramsConfig.imageBehaviourParameters.uploadInterval * 1e3);
|
|
28378
28524
|
}
|
|
28525
|
+
async getCurrentImageBase64() {
|
|
28526
|
+
if (!this.video || !this.canvas) {
|
|
28527
|
+
this.configImageCapture();
|
|
28528
|
+
} else {
|
|
28529
|
+
if (this.video.srcObject !== this.cameraStream) {
|
|
28530
|
+
this.video.srcObject = this.cameraStream;
|
|
28531
|
+
await this.video.play();
|
|
28532
|
+
}
|
|
28533
|
+
}
|
|
28534
|
+
if (this.video.paused) {
|
|
28535
|
+
await this.video.play();
|
|
28536
|
+
}
|
|
28537
|
+
await new Promise((resolve) => {
|
|
28538
|
+
if (this.video.readyState >= 2) {
|
|
28539
|
+
resolve();
|
|
28540
|
+
return;
|
|
28541
|
+
}
|
|
28542
|
+
const onLoadedMetadata = () => {
|
|
28543
|
+
this.video.removeEventListener("loadedmetadata", onLoadedMetadata);
|
|
28544
|
+
setTimeout(() => resolve(), 50);
|
|
28545
|
+
};
|
|
28546
|
+
this.video.addEventListener("loadedmetadata", onLoadedMetadata);
|
|
28547
|
+
setTimeout(() => {
|
|
28548
|
+
this.video.removeEventListener("loadedmetadata", onLoadedMetadata);
|
|
28549
|
+
resolve();
|
|
28550
|
+
}, 500);
|
|
28551
|
+
});
|
|
28552
|
+
this.canvas.getContext("2d").drawImage(this.video, 0, 0, this.canvas.width, this.canvas.height);
|
|
28553
|
+
return this.canvas.toDataURL("image/jpeg");
|
|
28554
|
+
}
|
|
28379
28555
|
// De um em um segundo captura um frame
|
|
28380
28556
|
captureFrame() {
|
|
28381
28557
|
let imageFile;
|
|
@@ -28510,6 +28686,46 @@ Setting: ${JSON.stringify(settings, null, 2)}`
|
|
|
28510
28686
|
}
|
|
28511
28687
|
this.noiseWait++;
|
|
28512
28688
|
}
|
|
28689
|
+
/**
|
|
28690
|
+
* Cria um stream processado onde os frames são rotacionados via Canvas.
|
|
28691
|
+
* Isso corrige o problema de gravação deitada em iOS/Mobile.
|
|
28692
|
+
*/
|
|
28693
|
+
createRotatedStream(originalStream) {
|
|
28694
|
+
this.internalClonedStream = originalStream.clone();
|
|
28695
|
+
const video = document.createElement("video");
|
|
28696
|
+
video.srcObject = this.internalClonedStream;
|
|
28697
|
+
video.muted = true;
|
|
28698
|
+
video.playsInline = true;
|
|
28699
|
+
video.play();
|
|
28700
|
+
const canvas = document.createElement("canvas");
|
|
28701
|
+
const ctx = canvas.getContext("2d");
|
|
28702
|
+
const track = originalStream.getVideoTracks()[0];
|
|
28703
|
+
const settings = track.getSettings();
|
|
28704
|
+
const width = settings.width || 640;
|
|
28705
|
+
const height = settings.height || 480;
|
|
28706
|
+
canvas.width = height;
|
|
28707
|
+
canvas.height = width;
|
|
28708
|
+
const draw = () => {
|
|
28709
|
+
if (video.paused || video.ended) return;
|
|
28710
|
+
if (!this.isCanvasLoopActive) return;
|
|
28711
|
+
if (ctx) {
|
|
28712
|
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
28713
|
+
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
|
|
28714
|
+
}
|
|
28715
|
+
if (this.isCanvasLoopActive) {
|
|
28716
|
+
this.animationFrameId = requestAnimationFrame(draw);
|
|
28717
|
+
}
|
|
28718
|
+
};
|
|
28719
|
+
video.onplaying = () => {
|
|
28720
|
+
this.isCanvasLoopActive = true;
|
|
28721
|
+
draw();
|
|
28722
|
+
};
|
|
28723
|
+
const canvasStream = canvas.captureStream(30);
|
|
28724
|
+
originalStream.getAudioTracks().forEach((track2) => {
|
|
28725
|
+
canvasStream.addTrack(track2);
|
|
28726
|
+
});
|
|
28727
|
+
return canvasStream;
|
|
28728
|
+
}
|
|
28513
28729
|
};
|
|
28514
28730
|
|
|
28515
28731
|
// src/new-flow/checkers/DeviceCheckerUI.ts
|
|
@@ -28894,6 +29110,9 @@ var DeviceCheckerUI = class {
|
|
|
28894
29110
|
const center = document.createElement("div");
|
|
28895
29111
|
video.setAttribute("id", "cameraStream");
|
|
28896
29112
|
video.muted = true;
|
|
29113
|
+
video.setAttribute("playsinline", "true");
|
|
29114
|
+
video.setAttribute("webkit-playsinline", "true");
|
|
29115
|
+
video.autoplay = true;
|
|
28897
29116
|
const divCameraStyles = {
|
|
28898
29117
|
width: "100%",
|
|
28899
29118
|
display: "flex",
|
|
@@ -29322,7 +29541,7 @@ var DeviceCheckerUI = class {
|
|
|
29322
29541
|
checkmark_kick_AmbientVerify.setAttribute("class", "checkmark_kick");
|
|
29323
29542
|
}
|
|
29324
29543
|
} else {
|
|
29325
|
-
if (checkmark_FacePosition && (response.
|
|
29544
|
+
if (checkmark_FacePosition && (response.type === "position_detection_on_stream" || response.type === "face_detection_on_stream")) {
|
|
29326
29545
|
facePositionAlert && (facePositionAlert.style.color = "#FF0000");
|
|
29327
29546
|
checkmark_FacePosition.setAttribute("class", "checkmark_error");
|
|
29328
29547
|
checkmark_stem_FacePosition.setAttribute("class", "checkmark_stem_error");
|
|
@@ -29427,7 +29646,9 @@ Para iniciar um exame utilize uma outra c\xE2mera.`);
|
|
|
29427
29646
|
const cameraStream = document.querySelector("#cameraStream");
|
|
29428
29647
|
if (cameraStream) {
|
|
29429
29648
|
cameraStream.srcObject = stream4;
|
|
29430
|
-
cameraStream.play()
|
|
29649
|
+
cameraStream.play().catch((e3) => {
|
|
29650
|
+
console.warn("Erro ao iniciar preview de v\xEDdeo:", e3);
|
|
29651
|
+
});
|
|
29431
29652
|
}
|
|
29432
29653
|
}
|
|
29433
29654
|
audioDeviceInterfaceUIAllowedAmbient(allowedAmbient) {
|
|
@@ -30213,9 +30434,11 @@ var Extension = class {
|
|
|
30213
30434
|
|
|
30214
30435
|
// src/modules/onChangeDevices.ts
|
|
30215
30436
|
var onChangeDevices = class {
|
|
30216
|
-
constructor(repositoryDevices, proctoringId2) {
|
|
30437
|
+
constructor(repositoryDevices, proctoringId2, sessionOptions, allRecorders) {
|
|
30217
30438
|
this.repositoryDevices = repositoryDevices;
|
|
30218
30439
|
this.proctoringId = proctoringId2;
|
|
30440
|
+
this.sessionOptions = sessionOptions;
|
|
30441
|
+
this.allRecorders = allRecorders;
|
|
30219
30442
|
}
|
|
30220
30443
|
startRecording(options) {
|
|
30221
30444
|
navigator.mediaDevices.ondevicechange = () => {
|
|
@@ -30229,24 +30452,49 @@ var onChangeDevices = class {
|
|
|
30229
30452
|
const response = await this.repositoryDevices.getDevices("devices");
|
|
30230
30453
|
const defaultDevice = { label: "", id: "" };
|
|
30231
30454
|
const copy = { cameras: (response == null ? void 0 : response.cameras) || [defaultDevice], microphones: (response == null ? void 0 : response.microphones) || [defaultDevice] };
|
|
30232
|
-
|
|
30233
|
-
let
|
|
30455
|
+
const status = devices.cameras.length > (copy == null ? void 0 : copy.cameras.length) || devices.microphones.length > (copy == null ? void 0 : copy.microphones.length) ? "in" : "out";
|
|
30456
|
+
let resultCameras = [];
|
|
30457
|
+
let resultMicrophones = [];
|
|
30458
|
+
let isActiveDeviceRemoved = false;
|
|
30234
30459
|
if (devices.cameras.length != (copy == null ? void 0 : copy.cameras.length)) {
|
|
30235
|
-
|
|
30460
|
+
const removedCameras = status === "out" ? onlyInLeft(copy == null ? void 0 : copy.cameras, devices.cameras, isSameDevice) : [];
|
|
30461
|
+
const addedCameras = status === "in" ? onlyInLeft(devices.cameras, copy == null ? void 0 : copy.cameras, isSameDevice) : [];
|
|
30462
|
+
resultCameras = status === "out" ? removedCameras : addedCameras;
|
|
30236
30463
|
resultCameras = resultCameras.filter((item) => item.id != "default");
|
|
30464
|
+
console.log(removedCameras);
|
|
30465
|
+
console.log(this.sessionOptions.cameraId);
|
|
30466
|
+
if (status === "out") {
|
|
30467
|
+
isActiveDeviceRemoved = removedCameras.some(
|
|
30468
|
+
(device) => device.id === this.sessionOptions.cameraId
|
|
30469
|
+
);
|
|
30470
|
+
}
|
|
30237
30471
|
}
|
|
30238
30472
|
if (devices.microphones.length != (copy == null ? void 0 : copy.microphones.length)) {
|
|
30239
|
-
|
|
30473
|
+
const removedMicrophones = status === "out" ? onlyInLeft(copy == null ? void 0 : copy.microphones, devices.microphones, isSameDevice) : [];
|
|
30474
|
+
const addedMicrophones = status === "in" ? onlyInLeft(devices.microphones, copy == null ? void 0 : copy.microphones, isSameDevice) : [];
|
|
30475
|
+
resultMicrophones = status === "out" ? removedMicrophones : addedMicrophones;
|
|
30240
30476
|
resultMicrophones = resultMicrophones.filter((item) => item.id != "default" && item.id != "communications");
|
|
30477
|
+
if (status === "out" && !isActiveDeviceRemoved) {
|
|
30478
|
+
isActiveDeviceRemoved = removedMicrophones.some(
|
|
30479
|
+
(device) => device.id === this.sessionOptions.microphoneId
|
|
30480
|
+
);
|
|
30481
|
+
}
|
|
30241
30482
|
}
|
|
30242
30483
|
const devicesChanged = {
|
|
30243
30484
|
cameras: resultCameras || [],
|
|
30244
30485
|
microphones: resultMicrophones || [],
|
|
30245
|
-
status
|
|
30486
|
+
status,
|
|
30487
|
+
isActiveDevice: isActiveDeviceRemoved
|
|
30246
30488
|
};
|
|
30247
|
-
await this.repositoryDevices.save({ ...devices, id: "devices", status
|
|
30489
|
+
await this.repositoryDevices.save({ ...devices, id: "devices", status });
|
|
30248
30490
|
if (options.status && (devicesChanged.cameras.length != 0 || devicesChanged.microphones.length != 0)) {
|
|
30249
30491
|
trackers.registerChangeDevice(this.proctoringId, devicesChanged.status, JSON.stringify(devicesChanged, null, 2));
|
|
30492
|
+
if (devicesChanged.isActiveDevice) {
|
|
30493
|
+
this.allRecorders.alertRecorder.addAlert({
|
|
30494
|
+
alert: 39 /* ChangeDevices */,
|
|
30495
|
+
type: 2 /* Video */
|
|
30496
|
+
});
|
|
30497
|
+
}
|
|
30250
30498
|
options.status(devicesChanged);
|
|
30251
30499
|
}
|
|
30252
30500
|
}
|
|
@@ -30454,6 +30702,14 @@ var AlertRecorder = class {
|
|
|
30454
30702
|
lastAlert.end = Date.now() - this.startTime.getTime();
|
|
30455
30703
|
}
|
|
30456
30704
|
}
|
|
30705
|
+
addAlert({ alert, type }) {
|
|
30706
|
+
this.alerts.push({
|
|
30707
|
+
begin: Date.now() - this.startTime.getTime(),
|
|
30708
|
+
end: Date.now() - this.startTime.getTime(),
|
|
30709
|
+
alert,
|
|
30710
|
+
type
|
|
30711
|
+
});
|
|
30712
|
+
}
|
|
30457
30713
|
};
|
|
30458
30714
|
|
|
30459
30715
|
// src/new-flow/recorders/AudioRecorder.ts
|
|
@@ -32942,19 +33198,38 @@ var ScreenRecorder = class {
|
|
|
32942
33198
|
}
|
|
32943
33199
|
async startRecording() {
|
|
32944
33200
|
this.startTime = new Date(Date.now());
|
|
33201
|
+
if (isMobileDevice()) return;
|
|
32945
33202
|
const { allowOnlyFirstMonitor, allowMultipleMonitors, onStopSharingScreenCallback, onBufferSizeErrorCallback } = this.options;
|
|
32946
|
-
const
|
|
33203
|
+
const complexConstraints = {
|
|
32947
33204
|
video: {
|
|
32948
33205
|
cursor: "always",
|
|
32949
|
-
width:
|
|
32950
|
-
height:
|
|
33206
|
+
width: this.options.screenRecorderOptions.width,
|
|
33207
|
+
height: this.options.screenRecorderOptions.height,
|
|
32951
33208
|
displaySurface: "monitor"
|
|
32952
33209
|
},
|
|
32953
33210
|
audio: false
|
|
32954
33211
|
};
|
|
32955
|
-
|
|
32956
|
-
|
|
32957
|
-
|
|
33212
|
+
const simpleConstraints = {
|
|
33213
|
+
video: {
|
|
33214
|
+
cursor: "always",
|
|
33215
|
+
width: 1280,
|
|
33216
|
+
height: 720,
|
|
33217
|
+
displaySurface: "monitor"
|
|
33218
|
+
},
|
|
33219
|
+
audio: false
|
|
33220
|
+
};
|
|
33221
|
+
let stream4;
|
|
33222
|
+
try {
|
|
33223
|
+
stream4 = await navigator.mediaDevices.getDisplayMedia(complexConstraints);
|
|
33224
|
+
} catch (e3) {
|
|
33225
|
+
if (e3 instanceof TypeError && e3.message.includes("min constraints are not supported")) {
|
|
33226
|
+
console.warn("Navegador n\xE3o suporta restri\xE7\xF5es 'min/max/ideal'. Tentando com 720p fixo.");
|
|
33227
|
+
stream4 = await navigator.mediaDevices.getDisplayMedia(simpleConstraints);
|
|
33228
|
+
} else {
|
|
33229
|
+
throw e3;
|
|
33230
|
+
}
|
|
33231
|
+
}
|
|
33232
|
+
this.screenStream = stream4;
|
|
32958
33233
|
const tracks = this.screenStream.getVideoTracks();
|
|
32959
33234
|
tracks[0].onended = onStopSharingScreenCallback;
|
|
32960
33235
|
const isFirefox = navigator.userAgent.indexOf("Firefox") > -1;
|
|
@@ -33246,15 +33521,12 @@ var _ExternalCameraChecker = class _ExternalCameraChecker {
|
|
|
33246
33521
|
}
|
|
33247
33522
|
}
|
|
33248
33523
|
async goToPositionGuide() {
|
|
33249
|
-
|
|
33250
|
-
const
|
|
33251
|
-
|
|
33252
|
-
|
|
33253
|
-
|
|
33254
|
-
|
|
33255
|
-
this.externalSessionId,
|
|
33256
|
-
actionMessage
|
|
33257
|
-
);
|
|
33524
|
+
try {
|
|
33525
|
+
const response = await this.backend.goToExternalCameraPositionStep("" + this.externalSessionId);
|
|
33526
|
+
console.log(response);
|
|
33527
|
+
} catch (error) {
|
|
33528
|
+
console.error("Erro ao enviar comando de Position:", error);
|
|
33529
|
+
throw new Error("N\xE3o foi poss\xEDvel enviar comando de Position Guide.");
|
|
33258
33530
|
}
|
|
33259
33531
|
}
|
|
33260
33532
|
async reset() {
|
|
@@ -33933,13 +34205,9 @@ var ExternalCameraChecker = _ExternalCameraChecker;
|
|
|
33933
34205
|
|
|
33934
34206
|
// src/proctoring/proctoring.ts
|
|
33935
34207
|
var Proctoring = class {
|
|
33936
|
-
// private onProgress = (percentage: number) => {};
|
|
33937
|
-
// public setOnProgress(cb: (percentage: number) => void) {
|
|
33938
|
-
// console.log("proctoring.setOnProgress");
|
|
33939
|
-
// this.onProgress = (percentage) => cb(percentage);
|
|
33940
|
-
// }
|
|
33941
34208
|
constructor(context) {
|
|
33942
34209
|
this.context = context;
|
|
34210
|
+
this.deviceData = null;
|
|
33943
34211
|
this.paramsConfig = {
|
|
33944
34212
|
audioBehaviourParameters: {
|
|
33945
34213
|
recordingBitrate: 128,
|
|
@@ -33992,11 +34260,17 @@ var Proctoring = class {
|
|
|
33992
34260
|
this.appChecker = new ExternalCameraChecker(this.context, (response) => this.onRealtimeAlertsCallback(response));
|
|
33993
34261
|
}
|
|
33994
34262
|
setOnStopSharingScreenCallback(cb) {
|
|
33995
|
-
this.onStopSharingScreenCallback = () => {
|
|
34263
|
+
this.onStopSharingScreenCallback = async () => {
|
|
34264
|
+
var _a2, _b, _c2, _d;
|
|
33996
34265
|
trackers.registerStopSharingScreen(
|
|
33997
34266
|
this.proctoringId,
|
|
33998
34267
|
"Stop sharing screen"
|
|
33999
34268
|
);
|
|
34269
|
+
(_b = (_a2 = this.allRecorders) == null ? void 0 : _a2.alertRecorder) == null ? void 0 : _b.addAlert({
|
|
34270
|
+
alert: 34 /* StopSharingScreen */,
|
|
34271
|
+
type: 3 /* Screen */
|
|
34272
|
+
});
|
|
34273
|
+
(_d = (_c2 = this.allRecorders) == null ? void 0 : _c2.screenRecorder) == null ? void 0 : _d.stopRecording();
|
|
34000
34274
|
cb();
|
|
34001
34275
|
};
|
|
34002
34276
|
}
|
|
@@ -34009,17 +34283,71 @@ var Proctoring = class {
|
|
|
34009
34283
|
async onChangeDevices(options = {}) {
|
|
34010
34284
|
const onChange = new onChangeDevices(
|
|
34011
34285
|
this.repositoryDevices,
|
|
34012
|
-
this.proctoringId
|
|
34286
|
+
this.proctoringId,
|
|
34287
|
+
this.sessionOptions,
|
|
34288
|
+
this.allRecorders
|
|
34013
34289
|
);
|
|
34014
34290
|
onChange.startRecording(options);
|
|
34015
34291
|
this.onChangeDevicesCallback = (devices) => options.status && options.status(devices);
|
|
34016
34292
|
}
|
|
34293
|
+
convertRealtimeCategoryToAlertCategory(category) {
|
|
34294
|
+
switch (category) {
|
|
34295
|
+
case "no_face_detected":
|
|
34296
|
+
return 1 /* NoFace */;
|
|
34297
|
+
case "multiple_faces_detected":
|
|
34298
|
+
return 2 /* MultipleFaces */;
|
|
34299
|
+
case "multiple_persons_detected":
|
|
34300
|
+
return 28 /* EnvironmentMultiplePeople */;
|
|
34301
|
+
case "no_person_detected":
|
|
34302
|
+
return 29 /* EnvironmentNoPeople */;
|
|
34303
|
+
default:
|
|
34304
|
+
return null;
|
|
34305
|
+
}
|
|
34306
|
+
}
|
|
34307
|
+
convertRealtimeTypeToWarningType(category) {
|
|
34308
|
+
switch (category) {
|
|
34309
|
+
case "face_detection_on_stream":
|
|
34310
|
+
return 0 /* Face */;
|
|
34311
|
+
case "person_detection_on_stream":
|
|
34312
|
+
return 1 /* People */;
|
|
34313
|
+
default:
|
|
34314
|
+
return null;
|
|
34315
|
+
}
|
|
34316
|
+
}
|
|
34017
34317
|
async onRealtimeAlerts(options = {}) {
|
|
34018
|
-
this.onRealtimeAlertsCallback = (response) =>
|
|
34318
|
+
this.onRealtimeAlertsCallback = async (response) => {
|
|
34319
|
+
options.data && options.data(response);
|
|
34320
|
+
if (this.sessionOptions.proctoringType === "REALTIME" && (response.type === "face_detection_on_stream" || response.type === "person_detection_on_stream")) {
|
|
34321
|
+
if (response.status === "ALERT") {
|
|
34322
|
+
await this.backend.startRealtimeAlert({
|
|
34323
|
+
proctoringId: this.proctoringId,
|
|
34324
|
+
begin: response.begin,
|
|
34325
|
+
end: response.end,
|
|
34326
|
+
alert: this.convertRealtimeCategoryToAlertCategory(response.category)
|
|
34327
|
+
});
|
|
34328
|
+
} else if (response.status === "OK") {
|
|
34329
|
+
await this.backend.stopRealtimeAlert({
|
|
34330
|
+
proctoringId: this.proctoringId,
|
|
34331
|
+
begin: response.begin,
|
|
34332
|
+
end: response.end,
|
|
34333
|
+
warningCategoryEnum: this.convertRealtimeTypeToWarningType(response.type),
|
|
34334
|
+
alertImageBase64: await this.allRecorders.cameraRecorder.getCurrentImageBase64()
|
|
34335
|
+
});
|
|
34336
|
+
}
|
|
34337
|
+
}
|
|
34338
|
+
};
|
|
34019
34339
|
}
|
|
34020
34340
|
setOnBufferSizeErrorCallback(cb) {
|
|
34021
34341
|
this.onBufferSizeErrorCallback = (cameraStream) => cb(cameraStream);
|
|
34022
34342
|
}
|
|
34343
|
+
// private onProgress = (percentage: number) => {};
|
|
34344
|
+
// public setOnProgress(cb: (percentage: number) => void) {
|
|
34345
|
+
// console.log("proctoring.setOnProgress");
|
|
34346
|
+
// this.onProgress = (percentage) => cb(percentage);
|
|
34347
|
+
// }
|
|
34348
|
+
setDeviceCheckData(data) {
|
|
34349
|
+
this.deviceData = data;
|
|
34350
|
+
}
|
|
34023
34351
|
createRecorders(options = getDefaultProctoringOptions) {
|
|
34024
34352
|
var _a2, _b;
|
|
34025
34353
|
this.onChangeDevices();
|
|
@@ -34046,6 +34374,7 @@ var Proctoring = class {
|
|
|
34046
34374
|
const screenRecorder = this.sessionOptions.captureScreen ? new ScreenRecorder({
|
|
34047
34375
|
allowOnlyFirstMonitor: (_a2 = this.sessionOptions.allowOnlyFirstMonitor) != null ? _a2 : true,
|
|
34048
34376
|
allowMultipleMonitors: (_b = this.sessionOptions.allowMultipleMonitors) != null ? _b : true,
|
|
34377
|
+
screenRecorderOptions: this.sessionOptions.screenRecorderOptions,
|
|
34049
34378
|
onStopSharingScreenCallback: () => this.onStopSharingScreenCallback(),
|
|
34050
34379
|
onBufferSizeError: this.sessionOptions.onBufferSizeError,
|
|
34051
34380
|
onBufferSizeErrorCallback: () => this.onBufferSizeErrorCallback()
|
|
@@ -34118,11 +34447,16 @@ var Proctoring = class {
|
|
|
34118
34447
|
examId: this.context.examId,
|
|
34119
34448
|
token: this.context.token
|
|
34120
34449
|
},
|
|
34121
|
-
this.sessionOptions
|
|
34450
|
+
this.sessionOptions,
|
|
34122
34451
|
this.geolocation ? this.geolocation.coords.latitude : void 0,
|
|
34123
34452
|
this.geolocation ? this.geolocation.coords.longitude : void 0
|
|
34124
34453
|
);
|
|
34125
34454
|
this.proctoringId = startResponse.id;
|
|
34455
|
+
trackers.registerDevicesChecked(
|
|
34456
|
+
this.proctoringId,
|
|
34457
|
+
!!this.deviceData,
|
|
34458
|
+
`Devices checked: ${JSON.stringify(this.deviceData)} | Devices List: ${JSON.stringify(devices)}`
|
|
34459
|
+
);
|
|
34126
34460
|
try {
|
|
34127
34461
|
if (options == null ? void 0 : options.useExternalCamera) {
|
|
34128
34462
|
await this.appChecker.startTransmission(this.proctoringId);
|
|
@@ -34156,6 +34490,11 @@ Navigator: ${JSON.stringify(_navigator2)}`
|
|
|
34156
34490
|
startResponse.screenStream = this.allRecorders.screenRecorder.screenStream;
|
|
34157
34491
|
}
|
|
34158
34492
|
this.state = "Recording" /* Recording */;
|
|
34493
|
+
setTimeout(async () => {
|
|
34494
|
+
if (this.sessionOptions.proctoringType === "REALTIME") {
|
|
34495
|
+
await this.backend.verifyFace(this.proctoringId, await this.allRecorders.cameraRecorder.getCurrentImageBase64());
|
|
34496
|
+
}
|
|
34497
|
+
}, 1e3);
|
|
34159
34498
|
return startResponse;
|
|
34160
34499
|
} catch (error) {
|
|
34161
34500
|
console.log(error);
|
|
@@ -34274,8 +34613,11 @@ Upload Services: ${uploaderServices}`,
|
|
|
34274
34613
|
);
|
|
34275
34614
|
});
|
|
34276
34615
|
}
|
|
34277
|
-
await this.backend.finishAndSendUrls(this.context
|
|
34616
|
+
await this.backend.finishAndSendUrls(this.context).then((finishResponse) => {
|
|
34617
|
+
var _a2, _b;
|
|
34278
34618
|
trackers.registerFinish(this.proctoringSession.id, true, "");
|
|
34619
|
+
console.log("finishResponse: ", finishResponse);
|
|
34620
|
+
options.onFinish && options.onFinish((_a2 = finishResponse == null ? void 0 : finishResponse.score) != null ? _a2 : 100, (_b = finishResponse == null ? void 0 : finishResponse.approved) != null ? _b : true);
|
|
34279
34621
|
}).catch((error) => {
|
|
34280
34622
|
trackers.registerFinish(
|
|
34281
34623
|
this.proctoringSession.id,
|
|
@@ -34622,7 +34964,14 @@ function useProctoring(proctoringOptions, enviromentConfig = "prod") {
|
|
|
34622
34964
|
const signTerm = new SignTerm(parameters);
|
|
34623
34965
|
const photo = new CapturePhoto();
|
|
34624
34966
|
const login = proctoring.login.bind(proctoring);
|
|
34625
|
-
const
|
|
34967
|
+
const originalStart = proctoring.start.bind(proctoring);
|
|
34968
|
+
const start = async (parameters2) => {
|
|
34969
|
+
const deviceResult = checker.getDeviceCheckResult();
|
|
34970
|
+
if (deviceResult) {
|
|
34971
|
+
proctoring.setDeviceCheckData(deviceResult);
|
|
34972
|
+
}
|
|
34973
|
+
return originalStart(parameters2);
|
|
34974
|
+
};
|
|
34626
34975
|
const finish = proctoring.finish.bind(proctoring);
|
|
34627
34976
|
const pause = proctoring.pause.bind(proctoring);
|
|
34628
34977
|
const resume = proctoring.resume.bind(proctoring);
|