easyproctor-hml 3.1.0 → 3.2.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 +5 -0
- package/esm/index.js +173 -119
- package/index.js +173 -119
- package/interfaces/ParamsConfig.d.ts +3 -6
- package/new-flow/proctoring/ProctoringSession.d.ts +1 -0
- package/new-flow/recorders/AlertRecorder.d.ts +5 -3
- package/new-flow/recorders/CameraRecorder.d.ts +1 -1
- package/new-flow/recorders/NoiseRecorder.d.ts +3 -0
- package/new-flow/recorders/ScreenRecorder.d.ts +8 -5
- package/package.json +1 -1
- package/plugins/recorder.d.ts +2 -1
- package/proctoring/options/ProctoringOptions.d.ts +1 -5
- package/unpkg/easyproctor.min.js +30 -30
package/index.js
CHANGED
|
@@ -30792,14 +30792,13 @@ var getDefaultProctoringOptions = {
|
|
|
30792
30792
|
captureScreen: true,
|
|
30793
30793
|
noiseLimit: 40,
|
|
30794
30794
|
// deprecated
|
|
30795
|
-
proctoringType: "
|
|
30795
|
+
proctoringType: "VIDEO",
|
|
30796
30796
|
insights: "",
|
|
30797
30797
|
onBufferSizeError: false,
|
|
30798
30798
|
useGeolocation: false,
|
|
30799
30799
|
useSpyScan: false,
|
|
30800
30800
|
useExternalCamera: false,
|
|
30801
30801
|
useChallenge: false,
|
|
30802
|
-
screenRecorderOptions: { width: 1280, height: 720 },
|
|
30803
30802
|
auto: false
|
|
30804
30803
|
};
|
|
30805
30804
|
|
|
@@ -30868,7 +30867,7 @@ var proctoringId;
|
|
|
30868
30867
|
function setRecorderProctoringId(id) {
|
|
30869
30868
|
proctoringId = id;
|
|
30870
30869
|
}
|
|
30871
|
-
function recorder(stream4, buffer, onBufferSizeError = false, onBufferSizeErrorCallback,
|
|
30870
|
+
function recorder(stream4, buffer, onBufferSizeError = false, onBufferSizeErrorCallback, recorderOpts) {
|
|
30872
30871
|
let resolvePromise;
|
|
30873
30872
|
let onBufferSizeInterval;
|
|
30874
30873
|
let lastEvent;
|
|
@@ -30880,9 +30879,11 @@ function recorder(stream4, buffer, onBufferSizeError = false, onBufferSizeErrorC
|
|
|
30880
30879
|
let recorderOptions = {
|
|
30881
30880
|
// eslint-disable-next-line no-useless-escape
|
|
30882
30881
|
mimeType: "video/webm",
|
|
30883
|
-
videoBitsPerSecond:
|
|
30882
|
+
videoBitsPerSecond: 25e4 * ((recorderOpts == null ? void 0 : recorderOpts.quality) || 1),
|
|
30883
|
+
// 250Kbps por padrão
|
|
30884
30884
|
audioBitsPerSecond: 64 * 1e3
|
|
30885
30885
|
};
|
|
30886
|
+
console.log("recorderOptions", recorderOptions);
|
|
30886
30887
|
if (MediaRecorder.isTypeSupported("video/webm;codecs=vp9")) {
|
|
30887
30888
|
recorderOptions.mimeType = "video/webm;codecs=vp9";
|
|
30888
30889
|
} else {
|
|
@@ -30890,12 +30891,6 @@ function recorder(stream4, buffer, onBufferSizeError = false, onBufferSizeErrorC
|
|
|
30890
30891
|
"vp9 codec not supported. Using default mimeType without vp9."
|
|
30891
30892
|
);
|
|
30892
30893
|
}
|
|
30893
|
-
if (audio) {
|
|
30894
|
-
recorderOptions = {
|
|
30895
|
-
mimeType: "audio/webm",
|
|
30896
|
-
audioBitsPerSecond: 64 * 1e3
|
|
30897
|
-
};
|
|
30898
|
-
}
|
|
30899
30894
|
function buildMediaRecorder(stream5, recorderOptions2) {
|
|
30900
30895
|
const tracks = stream5.getTracks();
|
|
30901
30896
|
if (tracks.length == 0) {
|
|
@@ -30966,7 +30961,7 @@ function recorder(stream4, buffer, onBufferSizeError = false, onBufferSizeErrorC
|
|
|
30966
30961
|
console.error("Timeout ao iniciar o recorder");
|
|
30967
30962
|
reject(new Error("Timeout ao iniciar o recorder"));
|
|
30968
30963
|
}
|
|
30969
|
-
},
|
|
30964
|
+
}, 5e3);
|
|
30970
30965
|
});
|
|
30971
30966
|
}
|
|
30972
30967
|
async function startRecording() {
|
|
@@ -31988,29 +31983,20 @@ var _CameraRecorder = class _CameraRecorder {
|
|
|
31988
31983
|
recordingBitrate: 128,
|
|
31989
31984
|
noiseLimit: 40
|
|
31990
31985
|
},
|
|
31991
|
-
imageBehaviourParameters: {
|
|
31992
|
-
useUploadImage: true,
|
|
31993
|
-
uploadInterval: 20,
|
|
31994
|
-
saveVideo: true
|
|
31995
|
-
},
|
|
31996
31986
|
videoBehaviourParameters: {
|
|
31997
31987
|
detectPerson: false,
|
|
31998
31988
|
detectFace: false,
|
|
31999
|
-
detectCellPhone: false
|
|
31989
|
+
detectCellPhone: false,
|
|
31990
|
+
cameraVideoQuality: 1
|
|
32000
31991
|
}
|
|
32001
31992
|
};
|
|
32002
|
-
// private imageParams: ImageParameters = {
|
|
32003
|
-
// useUploadImage: true,
|
|
32004
|
-
// uploadInterval: 20,
|
|
32005
|
-
// saveVideo: true
|
|
32006
|
-
// };
|
|
32007
31993
|
this.options = {
|
|
32008
31994
|
cameraId: void 0,
|
|
32009
31995
|
microphoneId: void 0,
|
|
32010
31996
|
onBufferSizeError: false,
|
|
32011
31997
|
onBufferSizeErrorCallback: (cameraStream) => {
|
|
32012
31998
|
},
|
|
32013
|
-
proctoringType: "
|
|
31999
|
+
proctoringType: "VIDEO",
|
|
32014
32000
|
onChangeDevicesCallback: (devices) => {
|
|
32015
32001
|
},
|
|
32016
32002
|
onRealtimeAlertsCallback: (response) => {
|
|
@@ -32317,14 +32303,15 @@ Setting: ${JSON.stringify(settings, null, 2)}`
|
|
|
32317
32303
|
await new Promise((r3) => setTimeout(r3, 300));
|
|
32318
32304
|
}
|
|
32319
32305
|
async startRecording() {
|
|
32320
|
-
var _a2, _b, _c2, _d, _e3, _f, _g, _h;
|
|
32306
|
+
var _a2, _b, _c2, _d, _e3, _f, _g, _h, _i3;
|
|
32321
32307
|
await this.startStream();
|
|
32322
32308
|
await this.attachAndWarmup(this.cameraStream);
|
|
32323
32309
|
const recorderOpts = this.isChunkEnabled ? {
|
|
32324
32310
|
timeslice: _CameraRecorder.CHUNK_TIMESLICE_MS,
|
|
32325
32311
|
onChunkAvailable: (blob, idx) => {
|
|
32326
32312
|
this.handleNewChunk(blob, idx);
|
|
32327
|
-
}
|
|
32313
|
+
},
|
|
32314
|
+
quality: (_a2 = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _a2.cameraVideoQuality
|
|
32328
32315
|
} : {};
|
|
32329
32316
|
const {
|
|
32330
32317
|
startRecording,
|
|
@@ -32341,7 +32328,6 @@ Setting: ${JSON.stringify(settings, null, 2)}`
|
|
|
32341
32328
|
this.blobs,
|
|
32342
32329
|
this.options.onBufferSizeError,
|
|
32343
32330
|
(e3) => this.bufferError(e3),
|
|
32344
|
-
false,
|
|
32345
32331
|
recorderOpts
|
|
32346
32332
|
);
|
|
32347
32333
|
this.recordingStart = startRecording;
|
|
@@ -32354,7 +32340,7 @@ Setting: ${JSON.stringify(settings, null, 2)}`
|
|
|
32354
32340
|
this.getDuration = getDuration;
|
|
32355
32341
|
this.chunkIndex = 0;
|
|
32356
32342
|
if (this.isChunkEnabled) {
|
|
32357
|
-
(
|
|
32343
|
+
(_b = this.backgroundUpload) == null ? void 0 : _b.start();
|
|
32358
32344
|
this.setupLifecycleListeners();
|
|
32359
32345
|
}
|
|
32360
32346
|
try {
|
|
@@ -32363,7 +32349,7 @@ Setting: ${JSON.stringify(settings, null, 2)}`
|
|
|
32363
32349
|
} catch (error) {
|
|
32364
32350
|
console.log("Camera Recorder error", error);
|
|
32365
32351
|
this.stopRecording();
|
|
32366
|
-
const maxRetries = ((
|
|
32352
|
+
const maxRetries = ((_c2 = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _c2.maxRetries) || 3;
|
|
32367
32353
|
if (this.currentRetries < maxRetries) {
|
|
32368
32354
|
console.log("Camera Recorder retry", this.currentRetries);
|
|
32369
32355
|
this.currentRetries++;
|
|
@@ -32373,13 +32359,13 @@ Setting: ${JSON.stringify(settings, null, 2)}`
|
|
|
32373
32359
|
}
|
|
32374
32360
|
}
|
|
32375
32361
|
this.stopped = false;
|
|
32376
|
-
if (((
|
|
32362
|
+
if (((_d = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _d.detectPerson) || ((_e3 = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _e3.detectCellPhone) || ((_f = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _f.detectFace)) {
|
|
32377
32363
|
await this.initializeDetectors();
|
|
32378
32364
|
}
|
|
32379
|
-
if ((
|
|
32365
|
+
if ((_g = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _g.detectFace) {
|
|
32380
32366
|
await this.faceDetection.enableCam(this.cameraStream);
|
|
32381
32367
|
}
|
|
32382
|
-
if (((
|
|
32368
|
+
if (((_h = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _h.detectPerson) || ((_i3 = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _i3.detectCellPhone)) {
|
|
32383
32369
|
await this.objectDetection.enableCam(this.cameraStream);
|
|
32384
32370
|
}
|
|
32385
32371
|
this.filesToUpload = [];
|
|
@@ -32614,7 +32600,7 @@ Setting: ${JSON.stringify(settings, null, 2)}`
|
|
|
32614
32600
|
window.URL.revokeObjectURL(url2);
|
|
32615
32601
|
}
|
|
32616
32602
|
async saveOnSession(session) {
|
|
32617
|
-
var _a2
|
|
32603
|
+
var _a2;
|
|
32618
32604
|
if (this.blobs != null)
|
|
32619
32605
|
trackers.registerSaveOnSession(
|
|
32620
32606
|
this.proctoringId,
|
|
@@ -32622,42 +32608,40 @@ Setting: ${JSON.stringify(settings, null, 2)}`
|
|
|
32622
32608
|
);
|
|
32623
32609
|
const settings = this.cameraStream.getVideoTracks()[0].getSettings();
|
|
32624
32610
|
const settingsAudio = this.cameraStream.getAudioTracks()[0].getSettings();
|
|
32625
|
-
|
|
32626
|
-
|
|
32627
|
-
if (this.
|
|
32628
|
-
|
|
32629
|
-
|
|
32630
|
-
|
|
32631
|
-
|
|
32632
|
-
|
|
32633
|
-
|
|
32634
|
-
|
|
32635
|
-
|
|
32636
|
-
|
|
32637
|
-
|
|
32638
|
-
|
|
32639
|
-
|
|
32640
|
-
|
|
32641
|
-
|
|
32642
|
-
|
|
32643
|
-
|
|
32644
|
-
|
|
32645
|
-
finalBlob = rawBlob;
|
|
32646
|
-
}
|
|
32647
|
-
} else {
|
|
32648
|
-
console.warn("fixWebmDuration n\xE3o dispon\xEDvel");
|
|
32611
|
+
let isUploaded = false;
|
|
32612
|
+
if (this.isChunkEnabled) {
|
|
32613
|
+
if (this.backend && this.backendToken && this.proctoringId) {
|
|
32614
|
+
const fileName = `EP_${this.proctoringId}_camera_0.webm`;
|
|
32615
|
+
const objectName = `${this.proctoringId}/${fileName}`;
|
|
32616
|
+
isUploaded = await this.backend.checkUpload(this.backendToken, objectName, "video/webm");
|
|
32617
|
+
this.chunkStorage && await this.chunkStorage.clearAllChunks(session.id);
|
|
32618
|
+
}
|
|
32619
|
+
}
|
|
32620
|
+
if (!isUploaded) {
|
|
32621
|
+
const rawBlob = new Blob(this.blobs, {
|
|
32622
|
+
type: ((_a2 = this.recorderOptions) == null ? void 0 : _a2.mimeType) || "video/webm"
|
|
32623
|
+
});
|
|
32624
|
+
let finalBlob = rawBlob;
|
|
32625
|
+
if (typeof fixWebmDuration === "function") {
|
|
32626
|
+
try {
|
|
32627
|
+
finalBlob = await fixWebmDuration(rawBlob, this.duration);
|
|
32628
|
+
} catch (e3) {
|
|
32629
|
+
console.warn("Erro ao corrigir a dura\xE7\xE3o do v\xEDdeo", e3);
|
|
32630
|
+
finalBlob = rawBlob;
|
|
32649
32631
|
}
|
|
32650
|
-
|
|
32651
|
-
|
|
32632
|
+
} else {
|
|
32633
|
+
console.warn("fixWebmDuration n\xE3o dispon\xEDvel");
|
|
32634
|
+
}
|
|
32635
|
+
session.addRecording({
|
|
32636
|
+
device: `Audio
|
|
32652
32637
|
Sample Rate: ${settingsAudio.sampleRate}
|
|
32653
32638
|
Sample Size: ${settingsAudio.sampleSize}
|
|
32654
32639
|
|
|
32655
32640
|
Video:
|
|
32656
32641
|
${JSON.stringify(this.recorderOptions)}`,
|
|
32657
|
-
|
|
32658
|
-
|
|
32659
|
-
|
|
32660
|
-
}
|
|
32642
|
+
arrayBuffer: await finalBlob.arrayBuffer(),
|
|
32643
|
+
origin: "Camera" /* Camera */
|
|
32644
|
+
});
|
|
32661
32645
|
}
|
|
32662
32646
|
}
|
|
32663
32647
|
async getFile(file, name, type) {
|
|
@@ -34842,7 +34826,7 @@ Error: ${e3.message}
|
|
|
34842
34826
|
|
|
34843
34827
|
// src/new-flow/recorders/AlertRecorder.ts
|
|
34844
34828
|
var AlertRecorder = class {
|
|
34845
|
-
constructor(options, optionsProctoring) {
|
|
34829
|
+
constructor(options, optionsProctoring, screenRecorder) {
|
|
34846
34830
|
this.alerts = [];
|
|
34847
34831
|
// Variáveis para controle de inatividade
|
|
34848
34832
|
this.lastActivityTime = Date.now();
|
|
@@ -34858,35 +34842,21 @@ var AlertRecorder = class {
|
|
|
34858
34842
|
this.handleLostFocus();
|
|
34859
34843
|
}
|
|
34860
34844
|
};
|
|
34861
|
-
this.
|
|
34845
|
+
this.isFocused = true;
|
|
34862
34846
|
this.handleLostFocus = () => {
|
|
34863
|
-
if (this.
|
|
34864
|
-
|
|
34865
|
-
|
|
34866
|
-
|
|
34867
|
-
|
|
34868
|
-
type: 3 /* Screen */
|
|
34869
|
-
};
|
|
34870
|
-
this.onLostFocusCallback(alertPayload);
|
|
34871
|
-
this.alerts.push(alertPayload);
|
|
34872
|
-
this.lastLostFocusTime = Date.now();
|
|
34847
|
+
if (this.screenRecorder && !this.screenRecorder.isRecording) {
|
|
34848
|
+
return;
|
|
34849
|
+
}
|
|
34850
|
+
if (this.getRelativeTime() > 1e4) {
|
|
34851
|
+
this.setFocus(false);
|
|
34873
34852
|
}
|
|
34874
34853
|
};
|
|
34875
|
-
this.lastReturnFocusTime = Date.now();
|
|
34876
34854
|
this.handleReturnFocus = () => {
|
|
34877
|
-
|
|
34878
|
-
|
|
34879
|
-
const lastAlert = this.alerts[this.alerts.length - 1];
|
|
34880
|
-
if (lastAlert) {
|
|
34881
|
-
this.onFocusCallback({
|
|
34882
|
-
begin: lastAlert.begin,
|
|
34883
|
-
end: this.getRelativeTime(),
|
|
34884
|
-
alert: 25 /* FocusOff */,
|
|
34885
|
-
type: 3 /* Screen */
|
|
34886
|
-
});
|
|
34887
|
-
lastAlert.end = this.getRelativeTime();
|
|
34855
|
+
if (this.screenRecorder && !this.screenRecorder.isRecording) {
|
|
34856
|
+
return;
|
|
34888
34857
|
}
|
|
34889
|
-
this.
|
|
34858
|
+
if (this.alerts.length === 0) return;
|
|
34859
|
+
this.setFocus(true);
|
|
34890
34860
|
};
|
|
34891
34861
|
// 2. SPLIT SCREEN DETECTION
|
|
34892
34862
|
this.handleResize = () => {
|
|
@@ -34945,6 +34915,7 @@ var AlertRecorder = class {
|
|
|
34945
34915
|
this.onFocusCallback = options.onFocusCallback;
|
|
34946
34916
|
this.onRealtimeAlertCallback = options.onRealtimeAlertCallback;
|
|
34947
34917
|
this.optionsProctoring = optionsProctoring;
|
|
34918
|
+
this.screenRecorder = screenRecorder;
|
|
34948
34919
|
}
|
|
34949
34920
|
async startRecording() {
|
|
34950
34921
|
this.startTime = new Date(Date.now());
|
|
@@ -34988,6 +34959,33 @@ var AlertRecorder = class {
|
|
|
34988
34959
|
window.document.removeEventListener("cut", this.handleCut);
|
|
34989
34960
|
window.document.removeEventListener("paste", this.handlePaste);
|
|
34990
34961
|
}
|
|
34962
|
+
setFocus(focused) {
|
|
34963
|
+
if (this.isFocused === focused) {
|
|
34964
|
+
return;
|
|
34965
|
+
}
|
|
34966
|
+
this.isFocused = focused;
|
|
34967
|
+
if (focused) {
|
|
34968
|
+
const lastAlert = this.alerts[this.alerts.length - 1];
|
|
34969
|
+
if (lastAlert) {
|
|
34970
|
+
this.onFocusCallback({
|
|
34971
|
+
begin: lastAlert.begin,
|
|
34972
|
+
end: this.getRelativeTime(),
|
|
34973
|
+
alert: 25 /* FocusOff */,
|
|
34974
|
+
type: 3 /* Screen */
|
|
34975
|
+
});
|
|
34976
|
+
lastAlert.end = this.getRelativeTime();
|
|
34977
|
+
}
|
|
34978
|
+
} else {
|
|
34979
|
+
const alertPayload = {
|
|
34980
|
+
begin: this.getRelativeTime(),
|
|
34981
|
+
end: 0,
|
|
34982
|
+
alert: 25 /* FocusOff */,
|
|
34983
|
+
type: 3 /* Screen */
|
|
34984
|
+
};
|
|
34985
|
+
this.onLostFocusCallback(alertPayload);
|
|
34986
|
+
this.alerts.push(alertPayload);
|
|
34987
|
+
}
|
|
34988
|
+
}
|
|
34991
34989
|
// private startIdleChecker() {
|
|
34992
34990
|
// this.stopIdleChecker(); // Garante que não tenha duplicação
|
|
34993
34991
|
// this.idleCheckInterval = setInterval(() => {
|
|
@@ -35028,7 +35026,11 @@ var AlertRecorder = class {
|
|
|
35028
35026
|
// HELPERS
|
|
35029
35027
|
// ==========================================
|
|
35030
35028
|
getRelativeTime() {
|
|
35031
|
-
|
|
35029
|
+
var _a2;
|
|
35030
|
+
if (this.screenRecorder) {
|
|
35031
|
+
return Date.now() - (((_a2 = this.screenRecorder.getStartTime()) == null ? void 0 : _a2.getTime()) || 0);
|
|
35032
|
+
}
|
|
35033
|
+
return Date.now() - (this.startTime.getTime() || 0);
|
|
35032
35034
|
}
|
|
35033
35035
|
createAlert(category, type, description) {
|
|
35034
35036
|
this.alerts.push({
|
|
@@ -37302,7 +37304,12 @@ var NoiseRecorder = class {
|
|
|
37302
37304
|
this.MAX_PRE_ROLL_CHUNKS = 4;
|
|
37303
37305
|
this.lastNoiseTime = 0;
|
|
37304
37306
|
this.SILENCE_THRESHOLD = 3e3;
|
|
37307
|
+
this.MAX_RECORD_DURATION = 3e4;
|
|
37308
|
+
// 30 segundos
|
|
37305
37309
|
this.filesToUpload = [];
|
|
37310
|
+
// logica do mute
|
|
37311
|
+
this.acumulatedMuteTime = 0;
|
|
37312
|
+
this.startMuteTime = 0;
|
|
37306
37313
|
this.optionsProctoring = optionsProctoring;
|
|
37307
37314
|
this.proctoringSession = proctoringSession;
|
|
37308
37315
|
this.paramsConfig = paramsConfig;
|
|
@@ -37337,7 +37344,7 @@ var NoiseRecorder = class {
|
|
|
37337
37344
|
async saveOnSession(session) {
|
|
37338
37345
|
}
|
|
37339
37346
|
async onNoiseDetectedRecord() {
|
|
37340
|
-
var _a2, _b, _c2, _d, _e3, _f, _g, _h, _i3;
|
|
37347
|
+
var _a2, _b, _c2, _d, _e3, _f, _g, _h, _i3, _j, _k, _l;
|
|
37341
37348
|
if (!this.volumeMeter && this.cameraRecorder.cameraStream) {
|
|
37342
37349
|
this.volumeMeter = new VolumeMeter(this.cameraRecorder.cameraStream);
|
|
37343
37350
|
this.volumeMeter.start().catch((e3) => {
|
|
@@ -37347,6 +37354,25 @@ var NoiseRecorder = class {
|
|
|
37347
37354
|
}
|
|
37348
37355
|
let noiseLimit = ((_a2 = this.paramsConfig.audioBehaviourParameters) == null ? void 0 : _a2.noiseLimit) || 40;
|
|
37349
37356
|
const currentVolume = ((_b = this.volumeMeter) == null ? void 0 : _b.getVolume()) || 0;
|
|
37357
|
+
if (this.optionsProctoring.proctoringType == "REALTIME") {
|
|
37358
|
+
let muteThreshold = ((_c2 = this.paramsConfig.audioBehaviourParameters) == null ? void 0 : _c2.muteThreshold) || 60;
|
|
37359
|
+
if (currentVolume == 0) {
|
|
37360
|
+
if (this.acumulatedMuteTime == 0) this.startMuteTime = Date.now() - (((_d = this.cameraRecorder.getStartTime()) == null ? void 0 : _d.getTime()) || 0);
|
|
37361
|
+
this.acumulatedMuteTime = this.acumulatedMuteTime + 200;
|
|
37362
|
+
} else
|
|
37363
|
+
this.acumulatedMuteTime = 0;
|
|
37364
|
+
if (this.acumulatedMuteTime / 1e3 >= muteThreshold) {
|
|
37365
|
+
this.acumulatedMuteTime = 0;
|
|
37366
|
+
this.onRealtimeAlertsCallback({
|
|
37367
|
+
begin: this.startMuteTime,
|
|
37368
|
+
end: Date.now() - (((_e3 = this.cameraRecorder.getStartTime()) == null ? void 0 : _e3.getTime()) || 0),
|
|
37369
|
+
status: "ALERT",
|
|
37370
|
+
description: "Microfone mutado",
|
|
37371
|
+
type: "audio_muted_on_stream",
|
|
37372
|
+
category: "audio_muted_on_stream"
|
|
37373
|
+
});
|
|
37374
|
+
}
|
|
37375
|
+
}
|
|
37350
37376
|
this.isSpeech = this.isSpeech || this.hasDesiredResult(this.audioClassificationResult);
|
|
37351
37377
|
if (!this.isSpeech && !this.recordingInProgress)
|
|
37352
37378
|
noiseLimit = noiseLimit * 1.25;
|
|
@@ -37359,27 +37385,28 @@ var NoiseRecorder = class {
|
|
|
37359
37385
|
this.recordingChunks = [...this.preRollBuffer];
|
|
37360
37386
|
const totalSamplesInBuffer = this.preRollBuffer.reduce((acc, chunk) => acc + chunk.length, 0);
|
|
37361
37387
|
const bufferDurationMs = totalSamplesInBuffer / this.SAMPLE_RATE * 1e3;
|
|
37362
|
-
const triggerTime = Date.now() - (((
|
|
37388
|
+
const triggerTime = Date.now() - (((_f = this.cameraRecorder.getStartTime()) == null ? void 0 : _f.getTime()) || 0);
|
|
37363
37389
|
this.recordingStartTime = triggerTime - bufferDurationMs;
|
|
37364
37390
|
if (this.recordingStartTime < 0) this.recordingStartTime = 0;
|
|
37365
37391
|
} else if (this.recordingInProgress) {
|
|
37366
37392
|
const silenceDuration = Date.now() - this.lastNoiseTime;
|
|
37367
37393
|
const currentRecordDuration = Date.now() - this.recordingStartTime;
|
|
37368
|
-
|
|
37394
|
+
const isMaxDurationReached = currentRecordDuration >= this.MAX_RECORD_DURATION;
|
|
37395
|
+
if (silenceDuration >= this.SILENCE_THRESHOLD && currentRecordDuration >= 3e3 && this.countLoopTimes > 4 || isMaxDurationReached) {
|
|
37369
37396
|
await this.stopSoundRecord();
|
|
37370
|
-
if (((
|
|
37397
|
+
if (((_g = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _g.detectNoise) && !this.isSpeech) {
|
|
37371
37398
|
this.onRealtimeAlertsCallback({
|
|
37372
|
-
begin: Date.now() - (((
|
|
37373
|
-
end: Date.now() - (((
|
|
37399
|
+
begin: Date.now() - (((_h = this.cameraRecorder.getStartTime()) == null ? void 0 : _h.getTime()) || 0),
|
|
37400
|
+
end: Date.now() - (((_i3 = this.cameraRecorder.getStartTime()) == null ? void 0 : _i3.getTime()) || 0),
|
|
37374
37401
|
status: "ALERT",
|
|
37375
37402
|
description: "Barulho detectado",
|
|
37376
37403
|
type: "audio_detection_on_stream"
|
|
37377
37404
|
});
|
|
37378
37405
|
}
|
|
37379
|
-
if (((
|
|
37406
|
+
if (((_j = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _j.detectSpeech) && this.isSpeech) {
|
|
37380
37407
|
this.onRealtimeAlertsCallback({
|
|
37381
|
-
begin: Date.now() - (((
|
|
37382
|
-
end: Date.now() - (((
|
|
37408
|
+
begin: Date.now() - (((_k = this.cameraRecorder.getStartTime()) == null ? void 0 : _k.getTime()) || 0),
|
|
37409
|
+
end: Date.now() - (((_l = this.cameraRecorder.getStartTime()) == null ? void 0 : _l.getTime()) || 0),
|
|
37383
37410
|
status: "ALERT",
|
|
37384
37411
|
description: "Fala detectada",
|
|
37385
37412
|
type: "audio_detection_on_stream"
|
|
@@ -37557,10 +37584,28 @@ registerProcessor("audio-processor", AudioProcessor);
|
|
|
37557
37584
|
var pkg2 = require_fix_webm_duration();
|
|
37558
37585
|
var fixWebmDuration2 = pkg2.default || pkg2;
|
|
37559
37586
|
var ScreenRecorder = class {
|
|
37560
|
-
constructor(options) {
|
|
37587
|
+
constructor(options, videoOptions, paramsConfig) {
|
|
37561
37588
|
this.blobs = [];
|
|
37562
37589
|
this.blobsFinal = [];
|
|
37590
|
+
this.isRecording = false;
|
|
37563
37591
|
this.duration = 0;
|
|
37592
|
+
this.videoOptions = {
|
|
37593
|
+
width: 640,
|
|
37594
|
+
height: 480,
|
|
37595
|
+
minWidth: 0,
|
|
37596
|
+
minHeight: 0
|
|
37597
|
+
};
|
|
37598
|
+
this.paramsConfig = {
|
|
37599
|
+
audioBehaviourParameters: {
|
|
37600
|
+
recordingBitrate: 128,
|
|
37601
|
+
noiseLimit: 40
|
|
37602
|
+
},
|
|
37603
|
+
videoBehaviourParameters: {
|
|
37604
|
+
screenVideoQuality: 3
|
|
37605
|
+
}
|
|
37606
|
+
};
|
|
37607
|
+
paramsConfig && (this.paramsConfig = paramsConfig);
|
|
37608
|
+
this.videoOptions = videoOptions;
|
|
37564
37609
|
this.options = options;
|
|
37565
37610
|
}
|
|
37566
37611
|
setProctoringId(proctoringId2) {
|
|
@@ -37568,15 +37613,16 @@ var ScreenRecorder = class {
|
|
|
37568
37613
|
setRecorderProctoringId(proctoringId2);
|
|
37569
37614
|
}
|
|
37570
37615
|
async startRecording() {
|
|
37571
|
-
|
|
37616
|
+
var _a2;
|
|
37572
37617
|
if (isMobileDevice()) return;
|
|
37573
37618
|
const { allowOnlyFirstMonitor, allowMultipleMonitors, onStopSharingScreenCallback, onBufferSizeErrorCallback } = this.options;
|
|
37574
37619
|
const complexConstraints = {
|
|
37575
37620
|
video: {
|
|
37576
37621
|
cursor: "always",
|
|
37577
|
-
width: this.
|
|
37578
|
-
height: this.
|
|
37579
|
-
displaySurface: "monitor"
|
|
37622
|
+
width: this.videoOptions.width,
|
|
37623
|
+
height: this.videoOptions.height,
|
|
37624
|
+
displaySurface: "monitor",
|
|
37625
|
+
frameRate: 15
|
|
37580
37626
|
},
|
|
37581
37627
|
audio: false
|
|
37582
37628
|
};
|
|
@@ -37632,10 +37678,24 @@ var ScreenRecorder = class {
|
|
|
37632
37678
|
});
|
|
37633
37679
|
throw NOT_SHARED_SCREEN;
|
|
37634
37680
|
}
|
|
37635
|
-
const {
|
|
37681
|
+
const {
|
|
37682
|
+
startRecording,
|
|
37683
|
+
stopRecording,
|
|
37684
|
+
getStartTime,
|
|
37685
|
+
getDuration
|
|
37686
|
+
} = recorder(
|
|
37687
|
+
this.screenStream,
|
|
37688
|
+
this.blobs,
|
|
37689
|
+
this.options.onBufferSizeError,
|
|
37690
|
+
onBufferSizeErrorCallback,
|
|
37691
|
+
{ quality: (_a2 = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _a2.screenVideoQuality }
|
|
37692
|
+
);
|
|
37636
37693
|
this.recordingStart = startRecording;
|
|
37637
37694
|
this.recordingStop = stopRecording;
|
|
37695
|
+
this.getStartTime = getStartTime;
|
|
37696
|
+
this.getDuration = getDuration;
|
|
37638
37697
|
this.recordingStart();
|
|
37698
|
+
this.isRecording = true;
|
|
37639
37699
|
}
|
|
37640
37700
|
async pauseRecording() {
|
|
37641
37701
|
}
|
|
@@ -37645,6 +37705,7 @@ var ScreenRecorder = class {
|
|
|
37645
37705
|
var _a2;
|
|
37646
37706
|
this.recordingStop && await this.recordingStop();
|
|
37647
37707
|
this.duration = Date.now() - ((_a2 = this.startTime) == null ? void 0 : _a2.getTime()) || 0;
|
|
37708
|
+
this.isRecording = false;
|
|
37648
37709
|
}
|
|
37649
37710
|
async saveOnSession(session) {
|
|
37650
37711
|
if (isMobileDevice()) return;
|
|
@@ -38619,11 +38680,6 @@ var Proctoring = class {
|
|
|
38619
38680
|
recordingBitrate: 128,
|
|
38620
38681
|
noiseLimit: 40
|
|
38621
38682
|
},
|
|
38622
|
-
imageBehaviourParameters: {
|
|
38623
|
-
useUploadImage: true,
|
|
38624
|
-
uploadInterval: 20,
|
|
38625
|
-
saveVideo: true
|
|
38626
|
-
},
|
|
38627
38683
|
videoBehaviourParameters: {
|
|
38628
38684
|
detectFace: false,
|
|
38629
38685
|
detectPerson: false,
|
|
@@ -38631,7 +38687,9 @@ var Proctoring = class {
|
|
|
38631
38687
|
detectNoise: false,
|
|
38632
38688
|
detectSpeech: false,
|
|
38633
38689
|
realtimePackageSize: 10,
|
|
38634
|
-
realtimeCaptureInterval: 2
|
|
38690
|
+
realtimeCaptureInterval: 2,
|
|
38691
|
+
cameraVideoQuality: 1,
|
|
38692
|
+
screenVideoQuality: 4
|
|
38635
38693
|
}
|
|
38636
38694
|
};
|
|
38637
38695
|
this.proctoringId = "";
|
|
@@ -38767,6 +38825,8 @@ var Proctoring = class {
|
|
|
38767
38825
|
return 25 /* FocusOff */;
|
|
38768
38826
|
case "error_upload_package":
|
|
38769
38827
|
return 44 /* RealtimeOffline */;
|
|
38828
|
+
case "audio_muted_on_stream":
|
|
38829
|
+
return 95 /* NoAudioFound */;
|
|
38770
38830
|
default:
|
|
38771
38831
|
return null;
|
|
38772
38832
|
}
|
|
@@ -38830,7 +38890,7 @@ var Proctoring = class {
|
|
|
38830
38890
|
}
|
|
38831
38891
|
}
|
|
38832
38892
|
async internalOnRealtimeAlerts(response) {
|
|
38833
|
-
if (this.sessionOptions.proctoringType === "REALTIME" && (response.type === "face_detection_on_stream" || response.type === "person_detection_on_stream" || response.type === "lost_focus" || response.type === "focus" || response.type === "error_upload_package")) {
|
|
38893
|
+
if (this.sessionOptions.proctoringType === "REALTIME" && (response.type === "face_detection_on_stream" || response.type === "person_detection_on_stream" || response.type === "lost_focus" || response.type === "focus" || response.type === "error_upload_package" || response.type === "audio_muted_on_stream")) {
|
|
38834
38894
|
await this.sendPendingRealtimeAlerts();
|
|
38835
38895
|
if (response.status === "ALERT") {
|
|
38836
38896
|
if (this.allRecorders.cameraRecorder.stopped) return;
|
|
@@ -38904,18 +38964,18 @@ var Proctoring = class {
|
|
|
38904
38964
|
const screenRecorder = this.sessionOptions.captureScreen ? new ScreenRecorder({
|
|
38905
38965
|
allowOnlyFirstMonitor: (_b = this.sessionOptions.allowOnlyFirstMonitor) != null ? _b : true,
|
|
38906
38966
|
allowMultipleMonitors: (_c2 = this.sessionOptions.allowMultipleMonitors) != null ? _c2 : true,
|
|
38907
|
-
screenRecorderOptions: this.sessionOptions.screenRecorderOptions,
|
|
38908
38967
|
onStopSharingScreenCallback: () => this.onStopSharingScreenCallback(),
|
|
38909
38968
|
onBufferSizeError: this.sessionOptions.onBufferSizeError,
|
|
38910
38969
|
onBufferSizeErrorCallback: () => this.onBufferSizeErrorCallback()
|
|
38911
|
-
}) : void 0;
|
|
38970
|
+
}, this.videoOptions, this.paramsConfig) : void 0;
|
|
38912
38971
|
const alertRecorder = new AlertRecorder(
|
|
38913
38972
|
{
|
|
38914
38973
|
onFocusCallback: (response) => this.onFocusAlertRecorderCallback(response),
|
|
38915
38974
|
onLostFocusCallback: (response) => this.onLostFocusAlertRecorderCallback(response),
|
|
38916
38975
|
onRealtimeAlertCallback: (response) => this.onRealtimeAlertsCallback(response)
|
|
38917
38976
|
},
|
|
38918
|
-
options
|
|
38977
|
+
options,
|
|
38978
|
+
screenRecorder
|
|
38919
38979
|
);
|
|
38920
38980
|
const noiseRecorder = new NoiseRecorder(
|
|
38921
38981
|
options,
|
|
@@ -39099,9 +39159,7 @@ Error: ${error}`
|
|
|
39099
39159
|
this.appChecker && await this.appChecker.disconnectWebSocket();
|
|
39100
39160
|
await this.recorder.saveAllOnSession();
|
|
39101
39161
|
await this.sendPendingRealtimeAlerts();
|
|
39102
|
-
trackers.registerError(this.proctoringId, `finish this.repository.save starting`);
|
|
39103
39162
|
await this.repository.save(this.proctoringSession);
|
|
39104
|
-
trackers.registerError(this.proctoringId, `finish this.repository.save finished`);
|
|
39105
39163
|
let uploader;
|
|
39106
39164
|
let uploaderServices;
|
|
39107
39165
|
if (versionVerify() !== "1.0.0.0") {
|
|
@@ -39255,10 +39313,6 @@ Error: ` + error
|
|
|
39255
39313
|
...this.paramsConfig.audioBehaviourParameters,
|
|
39256
39314
|
...paramsConfig.audioBehaviourParameters
|
|
39257
39315
|
},
|
|
39258
|
-
imageBehaviourParameters: {
|
|
39259
|
-
...this.paramsConfig.imageBehaviourParameters,
|
|
39260
|
-
...paramsConfig.imageBehaviourParameters
|
|
39261
|
-
},
|
|
39262
39316
|
videoBehaviourParameters: {
|
|
39263
39317
|
...this.paramsConfig.videoBehaviourParameters,
|
|
39264
39318
|
...paramsConfig.videoBehaviourParameters
|
|
@@ -3,11 +3,7 @@ export type AudioBehaviourParameters = {
|
|
|
3
3
|
onlyTranscribedAudio?: boolean;
|
|
4
4
|
recordingBitrate?: number;
|
|
5
5
|
noiseLimit?: number;
|
|
6
|
-
|
|
7
|
-
export type ImageBehaviourParameters = {
|
|
8
|
-
useUploadImage?: boolean;
|
|
9
|
-
uploadInterval?: number;
|
|
10
|
-
saveVideo?: boolean;
|
|
6
|
+
muteThreshold?: number;
|
|
11
7
|
};
|
|
12
8
|
export type VideoBehaviourParameters = {
|
|
13
9
|
minAlertTimePitch?: number;
|
|
@@ -26,10 +22,11 @@ export type VideoBehaviourParameters = {
|
|
|
26
22
|
maxRetries?: number;
|
|
27
23
|
realtimePackageSize?: number;
|
|
28
24
|
realtimeCaptureInterval?: number;
|
|
25
|
+
cameraVideoQuality?: number;
|
|
26
|
+
screenVideoQuality?: number;
|
|
29
27
|
};
|
|
30
28
|
export default interface IParamsConfig {
|
|
31
29
|
audioBehaviourParameters?: AudioBehaviourParameters;
|
|
32
|
-
imageBehaviourParameters?: ImageBehaviourParameters;
|
|
33
30
|
videoBehaviourParameters?: VideoBehaviourParameters;
|
|
34
31
|
spyScanInterval?: number;
|
|
35
32
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ProctoringSessionOptions } from "../../proctoring/options/ProctoringOptions";
|
|
2
2
|
import { AlertCategory, AlertType, ProctoringSession } from "../proctoring/ProctoringSession";
|
|
3
3
|
import { IRecorder } from "./IRecorder";
|
|
4
|
+
import { ScreenRecorder } from "./ScreenRecorder";
|
|
4
5
|
export declare class AlertRecorder implements IRecorder {
|
|
5
6
|
private alerts;
|
|
6
7
|
private startTime;
|
|
@@ -12,11 +13,12 @@ export declare class AlertRecorder implements IRecorder {
|
|
|
12
13
|
private idleCheckInterval;
|
|
13
14
|
private readonly IDLE_THRESHOLD_MS;
|
|
14
15
|
private resizeTimeout;
|
|
16
|
+
private screenRecorder?;
|
|
15
17
|
constructor(options: {
|
|
16
18
|
onLostFocusCallback: (response: any) => void;
|
|
17
19
|
onFocusCallback: (response: any) => void;
|
|
18
20
|
onRealtimeAlertCallback?: (response: any) => void;
|
|
19
|
-
}, optionsProctoring: ProctoringSessionOptions);
|
|
21
|
+
}, optionsProctoring: ProctoringSessionOptions, screenRecorder?: ScreenRecorder);
|
|
20
22
|
startRecording(): Promise<void>;
|
|
21
23
|
pauseRecording(): Promise<void>;
|
|
22
24
|
resumeRecording(): Promise<void>;
|
|
@@ -25,10 +27,10 @@ export declare class AlertRecorder implements IRecorder {
|
|
|
25
27
|
private attachListeners;
|
|
26
28
|
private detachListeners;
|
|
27
29
|
private handleVisibilityChange;
|
|
28
|
-
|
|
30
|
+
isFocused: boolean;
|
|
29
31
|
private handleLostFocus;
|
|
30
|
-
lastReturnFocusTime: number;
|
|
31
32
|
private handleReturnFocus;
|
|
33
|
+
setFocus(focused: boolean): void;
|
|
32
34
|
private handleResize;
|
|
33
35
|
private handleUserActivity;
|
|
34
36
|
addBackgroundEvent(description: string, category?: AlertCategory): void;
|
|
@@ -56,7 +56,7 @@ export declare class CameraRecorder implements IRecorder {
|
|
|
56
56
|
microphoneId?: string;
|
|
57
57
|
onBufferSizeError?: boolean;
|
|
58
58
|
onBufferSizeErrorCallback: (cameraStream?: any) => void;
|
|
59
|
-
proctoringType?: "VIDEO" | "
|
|
59
|
+
proctoringType?: "VIDEO" | "REALTIME";
|
|
60
60
|
onChangeDevicesCallback?: (devices: DevicesChanged) => void;
|
|
61
61
|
onRealtimeAlertsCallback?: (response: any) => void;
|
|
62
62
|
}, videoOptions: ProctoringVideoOptions, paramsConfig?: IParamsConfig, backend?: BackendService, backendToken?: string);
|