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/index.js CHANGED
@@ -30792,14 +30792,13 @@ var getDefaultProctoringOptions = {
30792
30792
  captureScreen: true,
30793
30793
  noiseLimit: 40,
30794
30794
  // deprecated
30795
- proctoringType: "IMAGE",
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, audio = false, recorderOpts) {
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: 128e3,
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
- }, 2e3);
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: "IMAGE",
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
- (_a2 = this.backgroundUpload) == null ? void 0 : _a2.start();
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 = ((_b = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _b.maxRetries) || 3;
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 (((_c2 = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _c2.detectPerson) || ((_d = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _d.detectCellPhone) || ((_e3 = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _e3.detectFace)) {
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 ((_f = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _f.detectFace) {
32367
+ if ((_h = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _h.detectFace) {
32380
32368
  await this.faceDetection.enableCam(this.cameraStream);
32381
32369
  }
32382
- if (((_g = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _g.detectPerson) || ((_h = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _h.detectCellPhone)) {
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, _b;
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
- if (this.options.proctoringType == "VIDEO" || this.options.proctoringType == "REALTIME" || this.options.proctoringType == "IMAGE" && ((_a2 = this.paramsConfig.imageBehaviourParameters) == null ? void 0 : _a2.saveVideo)) {
32626
- let isUploaded = false;
32627
- if (this.isChunkEnabled) {
32628
- if (this.backend && this.backendToken && this.proctoringId) {
32629
- const fileName = `EP_${this.proctoringId}_camera_0.webm`;
32630
- const objectName = `${this.proctoringId}/${fileName}`;
32631
- isUploaded = await this.backend.checkUpload(this.backendToken, objectName, "video/webm");
32632
- this.chunkStorage && await this.chunkStorage.clearAllChunks(session.id);
32633
- }
32634
- }
32635
- if (!isUploaded) {
32636
- const rawBlob = new Blob(this.blobs, {
32637
- type: ((_b = this.recorderOptions) == null ? void 0 : _b.mimeType) || "video/webm"
32638
- });
32639
- let finalBlob = rawBlob;
32640
- if (typeof fixWebmDuration === "function") {
32641
- try {
32642
- finalBlob = await fixWebmDuration(rawBlob, this.duration);
32643
- } catch (e3) {
32644
- console.warn("Erro ao corrigir a dura\xE7\xE3o do v\xEDdeo", e3);
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
- session.addRecording({
32651
- device: `Audio
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
- arrayBuffer: await finalBlob.arrayBuffer(),
32658
- origin: "Camera" /* Camera */
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.lastLostFocusTime = Date.now();
34847
+ this.isFocused = true;
34862
34848
  this.handleLostFocus = () => {
34863
- if (this.getRelativeTime() > 1e4 && Date.now() - this.lastLostFocusTime > 1e3) {
34864
- const alertPayload = {
34865
- begin: this.getRelativeTime(),
34866
- end: 0,
34867
- alert: 25 /* FocusOff */,
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
- const diffTime = Date.now() - this.lastReturnFocusTime;
34878
- if (diffTime < 1e3) return;
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.lastReturnFocusTime = Date.now();
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
- return Date.now() - this.startTime.getTime();
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() - (((_c2 = this.cameraRecorder.getStartTime()) == null ? void 0 : _c2.getTime()) || 0);
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
- if (silenceDuration >= this.SILENCE_THRESHOLD && currentRecordDuration >= 3e3 && this.countLoopTimes > 4) {
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 (((_d = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _d.detectNoise) && !this.isSpeech) {
37399
+ if (((_g = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _g.detectNoise) && !this.isSpeech) {
37371
37400
  this.onRealtimeAlertsCallback({
37372
- begin: Date.now() - (((_e3 = this.cameraRecorder.getStartTime()) == null ? void 0 : _e3.getTime()) || 0),
37373
- end: Date.now() - (((_f = this.cameraRecorder.getStartTime()) == null ? void 0 : _f.getTime()) || 0),
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 (((_g = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _g.detectSpeech) && this.isSpeech) {
37408
+ if (((_j = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _j.detectSpeech) && this.isSpeech) {
37380
37409
  this.onRealtimeAlertsCallback({
37381
- begin: Date.now() - (((_h = this.cameraRecorder.getStartTime()) == null ? void 0 : _h.getTime()) || 0),
37382
- end: Date.now() - (((_i3 = this.cameraRecorder.getStartTime()) == null ? void 0 : _i3.getTime()) || 0),
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
- this.startTime = new Date(Date.now());
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.options.screenRecorderOptions.width,
37578
- height: this.options.screenRecorderOptions.height,
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 { startRecording, stopRecording } = recorder(this.screenStream, this.blobs, this.options.onBufferSizeError, onBufferSizeErrorCallback);
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
  }
@@ -28,6 +28,7 @@ export declare enum AlertCategory {
28
28
  ClipBoardUse = 42,
29
29
  SplitScreen = 43,
30
30
  RealtimeOffline = 44,
31
+ NoAudioFound = 95,
31
32
  System = 200
32
33
  }
33
34
  export declare enum FinishRealtimeWarningCategory {
@@ -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
- lastLostFocusTime: number;
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" | "IMAGE" | "REALTIME";
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);