easyproctor-hml 3.1.0 → 3.2.1
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 +38 -0
- package/esm/index.js +175 -119
- package/index.js +175 -119
- package/interfaces/ParamsConfig.d.ts +4 -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 +3 -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
|
+
}, 1e4 * ((recorderOpts == null ? void 0 : recorderOpts.timeoutMultiplierFactor) || 1));
|
|
30970
30965
|
});
|
|
30971
30966
|
}
|
|
30972
30967
|
async function startRecording() {
|
|
@@ -31988,29 +31983,21 @@ 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,
|
|
31991
|
+
timeoutMultiplierFactor: 1
|
|
32000
31992
|
}
|
|
32001
31993
|
};
|
|
32002
|
-
// private imageParams: ImageParameters = {
|
|
32003
|
-
// useUploadImage: true,
|
|
32004
|
-
// uploadInterval: 20,
|
|
32005
|
-
// saveVideo: true
|
|
32006
|
-
// };
|
|
32007
31994
|
this.options = {
|
|
32008
31995
|
cameraId: void 0,
|
|
32009
31996
|
microphoneId: void 0,
|
|
32010
31997
|
onBufferSizeError: false,
|
|
32011
31998
|
onBufferSizeErrorCallback: (cameraStream) => {
|
|
32012
31999
|
},
|
|
32013
|
-
proctoringType: "
|
|
32000
|
+
proctoringType: "VIDEO",
|
|
32014
32001
|
onChangeDevicesCallback: (devices) => {
|
|
32015
32002
|
},
|
|
32016
32003
|
onRealtimeAlertsCallback: (response) => {
|
|
@@ -32317,14 +32304,16 @@ Setting: ${JSON.stringify(settings, null, 2)}`
|
|
|
32317
32304
|
await new Promise((r3) => setTimeout(r3, 300));
|
|
32318
32305
|
}
|
|
32319
32306
|
async startRecording() {
|
|
32320
|
-
var _a2, _b, _c2, _d, _e3, _f, _g, _h;
|
|
32307
|
+
var _a2, _b, _c2, _d, _e3, _f, _g, _h, _i3, _j;
|
|
32321
32308
|
await this.startStream();
|
|
32322
32309
|
await this.attachAndWarmup(this.cameraStream);
|
|
32323
32310
|
const recorderOpts = this.isChunkEnabled ? {
|
|
32324
32311
|
timeslice: _CameraRecorder.CHUNK_TIMESLICE_MS,
|
|
32325
32312
|
onChunkAvailable: (blob, idx) => {
|
|
32326
32313
|
this.handleNewChunk(blob, idx);
|
|
32327
|
-
}
|
|
32314
|
+
},
|
|
32315
|
+
quality: (_a2 = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _a2.cameraVideoQuality,
|
|
32316
|
+
timeoutMultiplierFactor: ((_b = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _b.timeoutMultiplierFactor) || 1
|
|
32328
32317
|
} : {};
|
|
32329
32318
|
const {
|
|
32330
32319
|
startRecording,
|
|
@@ -32341,7 +32330,6 @@ Setting: ${JSON.stringify(settings, null, 2)}`
|
|
|
32341
32330
|
this.blobs,
|
|
32342
32331
|
this.options.onBufferSizeError,
|
|
32343
32332
|
(e3) => this.bufferError(e3),
|
|
32344
|
-
false,
|
|
32345
32333
|
recorderOpts
|
|
32346
32334
|
);
|
|
32347
32335
|
this.recordingStart = startRecording;
|
|
@@ -32354,7 +32342,7 @@ Setting: ${JSON.stringify(settings, null, 2)}`
|
|
|
32354
32342
|
this.getDuration = getDuration;
|
|
32355
32343
|
this.chunkIndex = 0;
|
|
32356
32344
|
if (this.isChunkEnabled) {
|
|
32357
|
-
(
|
|
32345
|
+
(_c2 = this.backgroundUpload) == null ? void 0 : _c2.start();
|
|
32358
32346
|
this.setupLifecycleListeners();
|
|
32359
32347
|
}
|
|
32360
32348
|
try {
|
|
@@ -32363,7 +32351,7 @@ Setting: ${JSON.stringify(settings, null, 2)}`
|
|
|
32363
32351
|
} catch (error) {
|
|
32364
32352
|
console.log("Camera Recorder error", error);
|
|
32365
32353
|
this.stopRecording();
|
|
32366
|
-
const maxRetries = ((
|
|
32354
|
+
const maxRetries = ((_d = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _d.maxRetries) || 3;
|
|
32367
32355
|
if (this.currentRetries < maxRetries) {
|
|
32368
32356
|
console.log("Camera Recorder retry", this.currentRetries);
|
|
32369
32357
|
this.currentRetries++;
|
|
@@ -32373,13 +32361,13 @@ Setting: ${JSON.stringify(settings, null, 2)}`
|
|
|
32373
32361
|
}
|
|
32374
32362
|
}
|
|
32375
32363
|
this.stopped = false;
|
|
32376
|
-
if (((
|
|
32364
|
+
if (((_e3 = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _e3.detectPerson) || ((_f = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _f.detectCellPhone) || ((_g = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _g.detectFace)) {
|
|
32377
32365
|
await this.initializeDetectors();
|
|
32378
32366
|
}
|
|
32379
|
-
if ((
|
|
32367
|
+
if ((_h = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _h.detectFace) {
|
|
32380
32368
|
await this.faceDetection.enableCam(this.cameraStream);
|
|
32381
32369
|
}
|
|
32382
|
-
if (((
|
|
32370
|
+
if (((_i3 = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _i3.detectPerson) || ((_j = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _j.detectCellPhone)) {
|
|
32383
32371
|
await this.objectDetection.enableCam(this.cameraStream);
|
|
32384
32372
|
}
|
|
32385
32373
|
this.filesToUpload = [];
|
|
@@ -32614,7 +32602,7 @@ Setting: ${JSON.stringify(settings, null, 2)}`
|
|
|
32614
32602
|
window.URL.revokeObjectURL(url2);
|
|
32615
32603
|
}
|
|
32616
32604
|
async saveOnSession(session) {
|
|
32617
|
-
var _a2
|
|
32605
|
+
var _a2;
|
|
32618
32606
|
if (this.blobs != null)
|
|
32619
32607
|
trackers.registerSaveOnSession(
|
|
32620
32608
|
this.proctoringId,
|
|
@@ -32622,42 +32610,40 @@ Setting: ${JSON.stringify(settings, null, 2)}`
|
|
|
32622
32610
|
);
|
|
32623
32611
|
const settings = this.cameraStream.getVideoTracks()[0].getSettings();
|
|
32624
32612
|
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");
|
|
32613
|
+
let isUploaded = false;
|
|
32614
|
+
if (this.isChunkEnabled) {
|
|
32615
|
+
if (this.backend && this.backendToken && this.proctoringId) {
|
|
32616
|
+
const fileName = `EP_${this.proctoringId}_camera_0.webm`;
|
|
32617
|
+
const objectName = `${this.proctoringId}/${fileName}`;
|
|
32618
|
+
isUploaded = await this.backend.checkUpload(this.backendToken, objectName, "video/webm");
|
|
32619
|
+
this.chunkStorage && await this.chunkStorage.clearAllChunks(session.id);
|
|
32620
|
+
}
|
|
32621
|
+
}
|
|
32622
|
+
if (!isUploaded) {
|
|
32623
|
+
const rawBlob = new Blob(this.blobs, {
|
|
32624
|
+
type: ((_a2 = this.recorderOptions) == null ? void 0 : _a2.mimeType) || "video/webm"
|
|
32625
|
+
});
|
|
32626
|
+
let finalBlob = rawBlob;
|
|
32627
|
+
if (typeof fixWebmDuration === "function") {
|
|
32628
|
+
try {
|
|
32629
|
+
finalBlob = await fixWebmDuration(rawBlob, this.duration);
|
|
32630
|
+
} catch (e3) {
|
|
32631
|
+
console.warn("Erro ao corrigir a dura\xE7\xE3o do v\xEDdeo", e3);
|
|
32632
|
+
finalBlob = rawBlob;
|
|
32649
32633
|
}
|
|
32650
|
-
|
|
32651
|
-
|
|
32634
|
+
} else {
|
|
32635
|
+
console.warn("fixWebmDuration n\xE3o dispon\xEDvel");
|
|
32636
|
+
}
|
|
32637
|
+
session.addRecording({
|
|
32638
|
+
device: `Audio
|
|
32652
32639
|
Sample Rate: ${settingsAudio.sampleRate}
|
|
32653
32640
|
Sample Size: ${settingsAudio.sampleSize}
|
|
32654
32641
|
|
|
32655
32642
|
Video:
|
|
32656
32643
|
${JSON.stringify(this.recorderOptions)}`,
|
|
32657
|
-
|
|
32658
|
-
|
|
32659
|
-
|
|
32660
|
-
}
|
|
32644
|
+
arrayBuffer: await finalBlob.arrayBuffer(),
|
|
32645
|
+
origin: "Camera" /* Camera */
|
|
32646
|
+
});
|
|
32661
32647
|
}
|
|
32662
32648
|
}
|
|
32663
32649
|
async getFile(file, name, type) {
|
|
@@ -34842,7 +34828,7 @@ Error: ${e3.message}
|
|
|
34842
34828
|
|
|
34843
34829
|
// src/new-flow/recorders/AlertRecorder.ts
|
|
34844
34830
|
var AlertRecorder = class {
|
|
34845
|
-
constructor(options, optionsProctoring) {
|
|
34831
|
+
constructor(options, optionsProctoring, screenRecorder) {
|
|
34846
34832
|
this.alerts = [];
|
|
34847
34833
|
// Variáveis para controle de inatividade
|
|
34848
34834
|
this.lastActivityTime = Date.now();
|
|
@@ -34858,35 +34844,21 @@ var AlertRecorder = class {
|
|
|
34858
34844
|
this.handleLostFocus();
|
|
34859
34845
|
}
|
|
34860
34846
|
};
|
|
34861
|
-
this.
|
|
34847
|
+
this.isFocused = true;
|
|
34862
34848
|
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();
|
|
34849
|
+
if (this.screenRecorder && !this.screenRecorder.isRecording) {
|
|
34850
|
+
return;
|
|
34851
|
+
}
|
|
34852
|
+
if (this.getRelativeTime() > 1e4) {
|
|
34853
|
+
this.setFocus(false);
|
|
34873
34854
|
}
|
|
34874
34855
|
};
|
|
34875
|
-
this.lastReturnFocusTime = Date.now();
|
|
34876
34856
|
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();
|
|
34857
|
+
if (this.screenRecorder && !this.screenRecorder.isRecording) {
|
|
34858
|
+
return;
|
|
34888
34859
|
}
|
|
34889
|
-
this.
|
|
34860
|
+
if (this.alerts.length === 0) return;
|
|
34861
|
+
this.setFocus(true);
|
|
34890
34862
|
};
|
|
34891
34863
|
// 2. SPLIT SCREEN DETECTION
|
|
34892
34864
|
this.handleResize = () => {
|
|
@@ -34945,6 +34917,7 @@ var AlertRecorder = class {
|
|
|
34945
34917
|
this.onFocusCallback = options.onFocusCallback;
|
|
34946
34918
|
this.onRealtimeAlertCallback = options.onRealtimeAlertCallback;
|
|
34947
34919
|
this.optionsProctoring = optionsProctoring;
|
|
34920
|
+
this.screenRecorder = screenRecorder;
|
|
34948
34921
|
}
|
|
34949
34922
|
async startRecording() {
|
|
34950
34923
|
this.startTime = new Date(Date.now());
|
|
@@ -34988,6 +34961,33 @@ var AlertRecorder = class {
|
|
|
34988
34961
|
window.document.removeEventListener("cut", this.handleCut);
|
|
34989
34962
|
window.document.removeEventListener("paste", this.handlePaste);
|
|
34990
34963
|
}
|
|
34964
|
+
setFocus(focused) {
|
|
34965
|
+
if (this.isFocused === focused) {
|
|
34966
|
+
return;
|
|
34967
|
+
}
|
|
34968
|
+
this.isFocused = focused;
|
|
34969
|
+
if (focused) {
|
|
34970
|
+
const lastAlert = this.alerts[this.alerts.length - 1];
|
|
34971
|
+
if (lastAlert) {
|
|
34972
|
+
this.onFocusCallback({
|
|
34973
|
+
begin: lastAlert.begin,
|
|
34974
|
+
end: this.getRelativeTime(),
|
|
34975
|
+
alert: 25 /* FocusOff */,
|
|
34976
|
+
type: 3 /* Screen */
|
|
34977
|
+
});
|
|
34978
|
+
lastAlert.end = this.getRelativeTime();
|
|
34979
|
+
}
|
|
34980
|
+
} else {
|
|
34981
|
+
const alertPayload = {
|
|
34982
|
+
begin: this.getRelativeTime(),
|
|
34983
|
+
end: 0,
|
|
34984
|
+
alert: 25 /* FocusOff */,
|
|
34985
|
+
type: 3 /* Screen */
|
|
34986
|
+
};
|
|
34987
|
+
this.onLostFocusCallback(alertPayload);
|
|
34988
|
+
this.alerts.push(alertPayload);
|
|
34989
|
+
}
|
|
34990
|
+
}
|
|
34991
34991
|
// private startIdleChecker() {
|
|
34992
34992
|
// this.stopIdleChecker(); // Garante que não tenha duplicação
|
|
34993
34993
|
// this.idleCheckInterval = setInterval(() => {
|
|
@@ -35028,7 +35028,11 @@ var AlertRecorder = class {
|
|
|
35028
35028
|
// HELPERS
|
|
35029
35029
|
// ==========================================
|
|
35030
35030
|
getRelativeTime() {
|
|
35031
|
-
|
|
35031
|
+
var _a2;
|
|
35032
|
+
if (this.screenRecorder) {
|
|
35033
|
+
return Date.now() - (((_a2 = this.screenRecorder.getStartTime()) == null ? void 0 : _a2.getTime()) || 0);
|
|
35034
|
+
}
|
|
35035
|
+
return Date.now() - (this.startTime.getTime() || 0);
|
|
35032
35036
|
}
|
|
35033
35037
|
createAlert(category, type, description) {
|
|
35034
35038
|
this.alerts.push({
|
|
@@ -37302,7 +37306,12 @@ var NoiseRecorder = class {
|
|
|
37302
37306
|
this.MAX_PRE_ROLL_CHUNKS = 4;
|
|
37303
37307
|
this.lastNoiseTime = 0;
|
|
37304
37308
|
this.SILENCE_THRESHOLD = 3e3;
|
|
37309
|
+
this.MAX_RECORD_DURATION = 3e4;
|
|
37310
|
+
// 30 segundos
|
|
37305
37311
|
this.filesToUpload = [];
|
|
37312
|
+
// logica do mute
|
|
37313
|
+
this.acumulatedMuteTime = 0;
|
|
37314
|
+
this.startMuteTime = 0;
|
|
37306
37315
|
this.optionsProctoring = optionsProctoring;
|
|
37307
37316
|
this.proctoringSession = proctoringSession;
|
|
37308
37317
|
this.paramsConfig = paramsConfig;
|
|
@@ -37337,7 +37346,7 @@ var NoiseRecorder = class {
|
|
|
37337
37346
|
async saveOnSession(session) {
|
|
37338
37347
|
}
|
|
37339
37348
|
async onNoiseDetectedRecord() {
|
|
37340
|
-
var _a2, _b, _c2, _d, _e3, _f, _g, _h, _i3;
|
|
37349
|
+
var _a2, _b, _c2, _d, _e3, _f, _g, _h, _i3, _j, _k, _l;
|
|
37341
37350
|
if (!this.volumeMeter && this.cameraRecorder.cameraStream) {
|
|
37342
37351
|
this.volumeMeter = new VolumeMeter(this.cameraRecorder.cameraStream);
|
|
37343
37352
|
this.volumeMeter.start().catch((e3) => {
|
|
@@ -37347,6 +37356,25 @@ var NoiseRecorder = class {
|
|
|
37347
37356
|
}
|
|
37348
37357
|
let noiseLimit = ((_a2 = this.paramsConfig.audioBehaviourParameters) == null ? void 0 : _a2.noiseLimit) || 40;
|
|
37349
37358
|
const currentVolume = ((_b = this.volumeMeter) == null ? void 0 : _b.getVolume()) || 0;
|
|
37359
|
+
if (this.optionsProctoring.proctoringType == "REALTIME") {
|
|
37360
|
+
let muteThreshold = ((_c2 = this.paramsConfig.audioBehaviourParameters) == null ? void 0 : _c2.muteThreshold) || 60;
|
|
37361
|
+
if (currentVolume == 0) {
|
|
37362
|
+
if (this.acumulatedMuteTime == 0) this.startMuteTime = Date.now() - (((_d = this.cameraRecorder.getStartTime()) == null ? void 0 : _d.getTime()) || 0);
|
|
37363
|
+
this.acumulatedMuteTime = this.acumulatedMuteTime + 200;
|
|
37364
|
+
} else
|
|
37365
|
+
this.acumulatedMuteTime = 0;
|
|
37366
|
+
if (this.acumulatedMuteTime / 1e3 >= muteThreshold) {
|
|
37367
|
+
this.acumulatedMuteTime = 0;
|
|
37368
|
+
this.onRealtimeAlertsCallback({
|
|
37369
|
+
begin: this.startMuteTime,
|
|
37370
|
+
end: Date.now() - (((_e3 = this.cameraRecorder.getStartTime()) == null ? void 0 : _e3.getTime()) || 0),
|
|
37371
|
+
status: "ALERT",
|
|
37372
|
+
description: "Microfone mutado",
|
|
37373
|
+
type: "audio_muted_on_stream",
|
|
37374
|
+
category: "audio_muted_on_stream"
|
|
37375
|
+
});
|
|
37376
|
+
}
|
|
37377
|
+
}
|
|
37350
37378
|
this.isSpeech = this.isSpeech || this.hasDesiredResult(this.audioClassificationResult);
|
|
37351
37379
|
if (!this.isSpeech && !this.recordingInProgress)
|
|
37352
37380
|
noiseLimit = noiseLimit * 1.25;
|
|
@@ -37359,27 +37387,28 @@ var NoiseRecorder = class {
|
|
|
37359
37387
|
this.recordingChunks = [...this.preRollBuffer];
|
|
37360
37388
|
const totalSamplesInBuffer = this.preRollBuffer.reduce((acc, chunk) => acc + chunk.length, 0);
|
|
37361
37389
|
const bufferDurationMs = totalSamplesInBuffer / this.SAMPLE_RATE * 1e3;
|
|
37362
|
-
const triggerTime = Date.now() - (((
|
|
37390
|
+
const triggerTime = Date.now() - (((_f = this.cameraRecorder.getStartTime()) == null ? void 0 : _f.getTime()) || 0);
|
|
37363
37391
|
this.recordingStartTime = triggerTime - bufferDurationMs;
|
|
37364
37392
|
if (this.recordingStartTime < 0) this.recordingStartTime = 0;
|
|
37365
37393
|
} else if (this.recordingInProgress) {
|
|
37366
37394
|
const silenceDuration = Date.now() - this.lastNoiseTime;
|
|
37367
37395
|
const currentRecordDuration = Date.now() - this.recordingStartTime;
|
|
37368
|
-
|
|
37396
|
+
const isMaxDurationReached = currentRecordDuration >= this.MAX_RECORD_DURATION;
|
|
37397
|
+
if (silenceDuration >= this.SILENCE_THRESHOLD && currentRecordDuration >= 3e3 && this.countLoopTimes > 4 || isMaxDurationReached) {
|
|
37369
37398
|
await this.stopSoundRecord();
|
|
37370
|
-
if (((
|
|
37399
|
+
if (((_g = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _g.detectNoise) && !this.isSpeech) {
|
|
37371
37400
|
this.onRealtimeAlertsCallback({
|
|
37372
|
-
begin: Date.now() - (((
|
|
37373
|
-
end: Date.now() - (((
|
|
37401
|
+
begin: Date.now() - (((_h = this.cameraRecorder.getStartTime()) == null ? void 0 : _h.getTime()) || 0),
|
|
37402
|
+
end: Date.now() - (((_i3 = this.cameraRecorder.getStartTime()) == null ? void 0 : _i3.getTime()) || 0),
|
|
37374
37403
|
status: "ALERT",
|
|
37375
37404
|
description: "Barulho detectado",
|
|
37376
37405
|
type: "audio_detection_on_stream"
|
|
37377
37406
|
});
|
|
37378
37407
|
}
|
|
37379
|
-
if (((
|
|
37408
|
+
if (((_j = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _j.detectSpeech) && this.isSpeech) {
|
|
37380
37409
|
this.onRealtimeAlertsCallback({
|
|
37381
|
-
begin: Date.now() - (((
|
|
37382
|
-
end: Date.now() - (((
|
|
37410
|
+
begin: Date.now() - (((_k = this.cameraRecorder.getStartTime()) == null ? void 0 : _k.getTime()) || 0),
|
|
37411
|
+
end: Date.now() - (((_l = this.cameraRecorder.getStartTime()) == null ? void 0 : _l.getTime()) || 0),
|
|
37383
37412
|
status: "ALERT",
|
|
37384
37413
|
description: "Fala detectada",
|
|
37385
37414
|
type: "audio_detection_on_stream"
|
|
@@ -37557,10 +37586,28 @@ registerProcessor("audio-processor", AudioProcessor);
|
|
|
37557
37586
|
var pkg2 = require_fix_webm_duration();
|
|
37558
37587
|
var fixWebmDuration2 = pkg2.default || pkg2;
|
|
37559
37588
|
var ScreenRecorder = class {
|
|
37560
|
-
constructor(options) {
|
|
37589
|
+
constructor(options, videoOptions, paramsConfig) {
|
|
37561
37590
|
this.blobs = [];
|
|
37562
37591
|
this.blobsFinal = [];
|
|
37592
|
+
this.isRecording = false;
|
|
37563
37593
|
this.duration = 0;
|
|
37594
|
+
this.videoOptions = {
|
|
37595
|
+
width: 640,
|
|
37596
|
+
height: 480,
|
|
37597
|
+
minWidth: 0,
|
|
37598
|
+
minHeight: 0
|
|
37599
|
+
};
|
|
37600
|
+
this.paramsConfig = {
|
|
37601
|
+
audioBehaviourParameters: {
|
|
37602
|
+
recordingBitrate: 128,
|
|
37603
|
+
noiseLimit: 40
|
|
37604
|
+
},
|
|
37605
|
+
videoBehaviourParameters: {
|
|
37606
|
+
screenVideoQuality: 3
|
|
37607
|
+
}
|
|
37608
|
+
};
|
|
37609
|
+
paramsConfig && (this.paramsConfig = paramsConfig);
|
|
37610
|
+
this.videoOptions = videoOptions;
|
|
37564
37611
|
this.options = options;
|
|
37565
37612
|
}
|
|
37566
37613
|
setProctoringId(proctoringId2) {
|
|
@@ -37568,15 +37615,16 @@ var ScreenRecorder = class {
|
|
|
37568
37615
|
setRecorderProctoringId(proctoringId2);
|
|
37569
37616
|
}
|
|
37570
37617
|
async startRecording() {
|
|
37571
|
-
|
|
37618
|
+
var _a2;
|
|
37572
37619
|
if (isMobileDevice()) return;
|
|
37573
37620
|
const { allowOnlyFirstMonitor, allowMultipleMonitors, onStopSharingScreenCallback, onBufferSizeErrorCallback } = this.options;
|
|
37574
37621
|
const complexConstraints = {
|
|
37575
37622
|
video: {
|
|
37576
37623
|
cursor: "always",
|
|
37577
|
-
width: this.
|
|
37578
|
-
height: this.
|
|
37579
|
-
displaySurface: "monitor"
|
|
37624
|
+
width: this.videoOptions.width,
|
|
37625
|
+
height: this.videoOptions.height,
|
|
37626
|
+
displaySurface: "monitor",
|
|
37627
|
+
frameRate: 15
|
|
37580
37628
|
},
|
|
37581
37629
|
audio: false
|
|
37582
37630
|
};
|
|
@@ -37632,10 +37680,24 @@ var ScreenRecorder = class {
|
|
|
37632
37680
|
});
|
|
37633
37681
|
throw NOT_SHARED_SCREEN;
|
|
37634
37682
|
}
|
|
37635
|
-
const {
|
|
37683
|
+
const {
|
|
37684
|
+
startRecording,
|
|
37685
|
+
stopRecording,
|
|
37686
|
+
getStartTime,
|
|
37687
|
+
getDuration
|
|
37688
|
+
} = recorder(
|
|
37689
|
+
this.screenStream,
|
|
37690
|
+
this.blobs,
|
|
37691
|
+
this.options.onBufferSizeError,
|
|
37692
|
+
onBufferSizeErrorCallback,
|
|
37693
|
+
{ quality: (_a2 = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _a2.screenVideoQuality }
|
|
37694
|
+
);
|
|
37636
37695
|
this.recordingStart = startRecording;
|
|
37637
37696
|
this.recordingStop = stopRecording;
|
|
37697
|
+
this.getStartTime = getStartTime;
|
|
37698
|
+
this.getDuration = getDuration;
|
|
37638
37699
|
this.recordingStart();
|
|
37700
|
+
this.isRecording = true;
|
|
37639
37701
|
}
|
|
37640
37702
|
async pauseRecording() {
|
|
37641
37703
|
}
|
|
@@ -37645,6 +37707,7 @@ var ScreenRecorder = class {
|
|
|
37645
37707
|
var _a2;
|
|
37646
37708
|
this.recordingStop && await this.recordingStop();
|
|
37647
37709
|
this.duration = Date.now() - ((_a2 = this.startTime) == null ? void 0 : _a2.getTime()) || 0;
|
|
37710
|
+
this.isRecording = false;
|
|
37648
37711
|
}
|
|
37649
37712
|
async saveOnSession(session) {
|
|
37650
37713
|
if (isMobileDevice()) return;
|
|
@@ -38619,11 +38682,6 @@ var Proctoring = class {
|
|
|
38619
38682
|
recordingBitrate: 128,
|
|
38620
38683
|
noiseLimit: 40
|
|
38621
38684
|
},
|
|
38622
|
-
imageBehaviourParameters: {
|
|
38623
|
-
useUploadImage: true,
|
|
38624
|
-
uploadInterval: 20,
|
|
38625
|
-
saveVideo: true
|
|
38626
|
-
},
|
|
38627
38685
|
videoBehaviourParameters: {
|
|
38628
38686
|
detectFace: false,
|
|
38629
38687
|
detectPerson: false,
|
|
@@ -38631,7 +38689,9 @@ var Proctoring = class {
|
|
|
38631
38689
|
detectNoise: false,
|
|
38632
38690
|
detectSpeech: false,
|
|
38633
38691
|
realtimePackageSize: 10,
|
|
38634
|
-
realtimeCaptureInterval: 2
|
|
38692
|
+
realtimeCaptureInterval: 2,
|
|
38693
|
+
cameraVideoQuality: 1,
|
|
38694
|
+
screenVideoQuality: 4
|
|
38635
38695
|
}
|
|
38636
38696
|
};
|
|
38637
38697
|
this.proctoringId = "";
|
|
@@ -38767,6 +38827,8 @@ var Proctoring = class {
|
|
|
38767
38827
|
return 25 /* FocusOff */;
|
|
38768
38828
|
case "error_upload_package":
|
|
38769
38829
|
return 44 /* RealtimeOffline */;
|
|
38830
|
+
case "audio_muted_on_stream":
|
|
38831
|
+
return 95 /* NoAudioFound */;
|
|
38770
38832
|
default:
|
|
38771
38833
|
return null;
|
|
38772
38834
|
}
|
|
@@ -38830,7 +38892,7 @@ var Proctoring = class {
|
|
|
38830
38892
|
}
|
|
38831
38893
|
}
|
|
38832
38894
|
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")) {
|
|
38895
|
+
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
38896
|
await this.sendPendingRealtimeAlerts();
|
|
38835
38897
|
if (response.status === "ALERT") {
|
|
38836
38898
|
if (this.allRecorders.cameraRecorder.stopped) return;
|
|
@@ -38904,18 +38966,18 @@ var Proctoring = class {
|
|
|
38904
38966
|
const screenRecorder = this.sessionOptions.captureScreen ? new ScreenRecorder({
|
|
38905
38967
|
allowOnlyFirstMonitor: (_b = this.sessionOptions.allowOnlyFirstMonitor) != null ? _b : true,
|
|
38906
38968
|
allowMultipleMonitors: (_c2 = this.sessionOptions.allowMultipleMonitors) != null ? _c2 : true,
|
|
38907
|
-
screenRecorderOptions: this.sessionOptions.screenRecorderOptions,
|
|
38908
38969
|
onStopSharingScreenCallback: () => this.onStopSharingScreenCallback(),
|
|
38909
38970
|
onBufferSizeError: this.sessionOptions.onBufferSizeError,
|
|
38910
38971
|
onBufferSizeErrorCallback: () => this.onBufferSizeErrorCallback()
|
|
38911
|
-
}) : void 0;
|
|
38972
|
+
}, this.videoOptions, this.paramsConfig) : void 0;
|
|
38912
38973
|
const alertRecorder = new AlertRecorder(
|
|
38913
38974
|
{
|
|
38914
38975
|
onFocusCallback: (response) => this.onFocusAlertRecorderCallback(response),
|
|
38915
38976
|
onLostFocusCallback: (response) => this.onLostFocusAlertRecorderCallback(response),
|
|
38916
38977
|
onRealtimeAlertCallback: (response) => this.onRealtimeAlertsCallback(response)
|
|
38917
38978
|
},
|
|
38918
|
-
options
|
|
38979
|
+
options,
|
|
38980
|
+
screenRecorder
|
|
38919
38981
|
);
|
|
38920
38982
|
const noiseRecorder = new NoiseRecorder(
|
|
38921
38983
|
options,
|
|
@@ -39099,9 +39161,7 @@ Error: ${error}`
|
|
|
39099
39161
|
this.appChecker && await this.appChecker.disconnectWebSocket();
|
|
39100
39162
|
await this.recorder.saveAllOnSession();
|
|
39101
39163
|
await this.sendPendingRealtimeAlerts();
|
|
39102
|
-
trackers.registerError(this.proctoringId, `finish this.repository.save starting`);
|
|
39103
39164
|
await this.repository.save(this.proctoringSession);
|
|
39104
|
-
trackers.registerError(this.proctoringId, `finish this.repository.save finished`);
|
|
39105
39165
|
let uploader;
|
|
39106
39166
|
let uploaderServices;
|
|
39107
39167
|
if (versionVerify() !== "1.0.0.0") {
|
|
@@ -39255,10 +39315,6 @@ Error: ` + error
|
|
|
39255
39315
|
...this.paramsConfig.audioBehaviourParameters,
|
|
39256
39316
|
...paramsConfig.audioBehaviourParameters
|
|
39257
39317
|
},
|
|
39258
|
-
imageBehaviourParameters: {
|
|
39259
|
-
...this.paramsConfig.imageBehaviourParameters,
|
|
39260
|
-
...paramsConfig.imageBehaviourParameters
|
|
39261
|
-
},
|
|
39262
39318
|
videoBehaviourParameters: {
|
|
39263
39319
|
...this.paramsConfig.videoBehaviourParameters,
|
|
39264
39320
|
...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,12 @@ export type VideoBehaviourParameters = {
|
|
|
26
22
|
maxRetries?: number;
|
|
27
23
|
realtimePackageSize?: number;
|
|
28
24
|
realtimeCaptureInterval?: number;
|
|
25
|
+
cameraVideoQuality?: number;
|
|
26
|
+
screenVideoQuality?: number;
|
|
27
|
+
timeoutMultiplierFactor?: number;
|
|
29
28
|
};
|
|
30
29
|
export default interface IParamsConfig {
|
|
31
30
|
audioBehaviourParameters?: AudioBehaviourParameters;
|
|
32
|
-
imageBehaviourParameters?: ImageBehaviourParameters;
|
|
33
31
|
videoBehaviourParameters?: VideoBehaviourParameters;
|
|
34
32
|
spyScanInterval?: number;
|
|
35
33
|
}
|
|
@@ -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);
|