easyproctor-hml 2.8.0 → 3.1.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 CHANGED
@@ -263,6 +263,12 @@ const {
263
263
  token: "...",
264
264
  });
265
265
  ```
266
+
267
+ ## Release Note V 3.0.0
268
+ - Envio do vídeo por partes durante o exame para o proctoring REALTIME
269
+ - Fix: correção do bug do import pacote fix-webm-duration
270
+ - Possibilidade de check automático no check devices através do parametro 'auto'
271
+
266
272
  ## Release Note V 2.7.0
267
273
  - Implementação da comunicação com a API para o proctoring do tipo realtime
268
274
  - Envio do vídeo durante o exame
package/esm/index.js CHANGED
@@ -12771,7 +12771,7 @@ var proctoringId;
12771
12771
  function setRecorderProctoringId(id) {
12772
12772
  proctoringId = id;
12773
12773
  }
12774
- function recorder(stream, buffer, onBufferSizeError = false, onBufferSizeErrorCallback, audio = false) {
12774
+ function recorder(stream, buffer, onBufferSizeError = false, onBufferSizeErrorCallback, audio = false, recorderOpts) {
12775
12775
  let resolvePromise;
12776
12776
  let onBufferSizeInterval;
12777
12777
  let lastEvent;
@@ -12779,6 +12779,7 @@ function recorder(stream, buffer, onBufferSizeError = false, onBufferSizeErrorCa
12779
12779
  bufferSize = 0;
12780
12780
  let startTime;
12781
12781
  let duration = 0;
12782
+ let chunkIndex = 0;
12782
12783
  let recorderOptions = {
12783
12784
  // eslint-disable-next-line no-useless-escape
12784
12785
  mimeType: "video/webm",
@@ -12813,6 +12814,10 @@ function recorder(stream, buffer, onBufferSizeError = false, onBufferSizeErrorCa
12813
12814
  mediaRecorder2.ondataavailable = (e3) => {
12814
12815
  bufferSize = bufferSize + e3.data.size;
12815
12816
  if (e3.data.size > 0) {
12817
+ if (recorderOpts == null ? void 0 : recorderOpts.onChunkAvailable) {
12818
+ recorderOpts.onChunkAvailable(e3.data, chunkIndex);
12819
+ chunkIndex++;
12820
+ }
12816
12821
  buffer.push(e3.data);
12817
12822
  }
12818
12823
  };
@@ -12844,7 +12849,13 @@ function recorder(stream, buffer, onBufferSizeError = false, onBufferSizeErrorCa
12844
12849
  };
12845
12850
  try {
12846
12851
  console.log("State antes do start:", recorder2.state);
12847
- recorder2.start(1e4);
12852
+ chunkIndex = 0;
12853
+ if ((recorderOpts == null ? void 0 : recorderOpts.timeslice) && (recorderOpts == null ? void 0 : recorderOpts.timeslice) > 0) {
12854
+ recorder2.start(recorderOpts.timeslice);
12855
+ } else {
12856
+ recorder2.start(1e4);
12857
+ }
12858
+ bufferSize = 0;
12848
12859
  startTime = new Date(Date.now());
12849
12860
  } catch (e3) {
12850
12861
  console.error("Recorder erro ao chamar start event:", e3);
@@ -13258,9 +13269,6 @@ var ObjectDetection = class extends BaseDetection {
13258
13269
  }
13259
13270
  };
13260
13271
 
13261
- // src/new-flow/recorders/CameraRecorder.ts
13262
- var import_jszip_min = __toESM(require_jszip_min());
13263
-
13264
13272
  // src/new-flow/chunk/ChunkStorageService.ts
13265
13273
  var _ChunkStorageService = class _ChunkStorageService {
13266
13274
  constructor() {
@@ -13872,6 +13880,7 @@ var BackgroundUploadService = class _BackgroundUploadService {
13872
13880
  };
13873
13881
 
13874
13882
  // src/new-flow/recorders/CameraRecorder.ts
13883
+ var import_jszip_min = __toESM(require_jszip_min());
13875
13884
  var pkg = require_fix_webm_duration();
13876
13885
  var fixWebmDuration = pkg.default || pkg;
13877
13886
  var _CameraRecorder = class _CameraRecorder {
@@ -13944,11 +13953,11 @@ var _CameraRecorder = class _CameraRecorder {
13944
13953
  paramsConfig && (this.paramsConfig = paramsConfig);
13945
13954
  }
13946
13955
  /**
13947
- * Determina se o fluxo de chunks e lifecycle deve estar ativo.
13948
- * Retorna true se:
13949
- * 1. O proctoringId já foi definido (ou seja, estamos em uma sessão real, NÃO no checkDevices)
13950
- * 2. E (`useChunkRecording` foi explicitamente setado como true OU o dispositivo é mobile)
13951
- */
13956
+ * Determina se o fluxo de chunks e lifecycle deve estar ativo.
13957
+ * Retorna true se:
13958
+ * 1. O proctoringId já foi definido (ou seja, estamos em uma sessão real, NÃO no checkDevices)
13959
+ * 2. E (`useChunkRecording` foi explicitamente setado como true OU o dispositivo é mobile)
13960
+ */
13952
13961
  get isChunkEnabled() {
13953
13962
  return !!this.proctoringId && this.options.proctoringType === "REALTIME" && !isSafeBrowser();
13954
13963
  }
@@ -14211,9 +14220,15 @@ Setting: ${JSON.stringify(settings, null, 2)}`
14211
14220
  await new Promise((r3) => setTimeout(r3, 300));
14212
14221
  }
14213
14222
  async startRecording() {
14214
- var _a2, _b, _c2, _d, _e3, _f, _g;
14223
+ var _a2, _b, _c2, _d, _e3, _f, _g, _h;
14215
14224
  await this.startStream();
14216
14225
  await this.attachAndWarmup(this.cameraStream);
14226
+ const recorderOpts = this.isChunkEnabled ? {
14227
+ timeslice: _CameraRecorder.CHUNK_TIMESLICE_MS,
14228
+ onChunkAvailable: (blob, idx) => {
14229
+ this.handleNewChunk(blob, idx);
14230
+ }
14231
+ } : {};
14217
14232
  const {
14218
14233
  startRecording,
14219
14234
  stopRecording,
@@ -14229,7 +14244,8 @@ Setting: ${JSON.stringify(settings, null, 2)}`
14229
14244
  this.blobs,
14230
14245
  this.options.onBufferSizeError,
14231
14246
  (e3) => this.bufferError(e3),
14232
- false
14247
+ false,
14248
+ recorderOpts
14233
14249
  );
14234
14250
  this.recordingStart = startRecording;
14235
14251
  this.recordingStop = stopRecording;
@@ -14239,13 +14255,18 @@ Setting: ${JSON.stringify(settings, null, 2)}`
14239
14255
  this.getBufferSize = getBufferSize;
14240
14256
  this.getStartTime = getStartTime;
14241
14257
  this.getDuration = getDuration;
14258
+ this.chunkIndex = 0;
14259
+ if (this.isChunkEnabled) {
14260
+ (_a2 = this.backgroundUpload) == null ? void 0 : _a2.start();
14261
+ this.setupLifecycleListeners();
14262
+ }
14242
14263
  try {
14243
14264
  await new Promise((r3) => setTimeout(r3, 500));
14244
14265
  await this.recordingStart();
14245
14266
  } catch (error) {
14246
14267
  console.log("Camera Recorder error", error);
14247
14268
  this.stopRecording();
14248
- const maxRetries = ((_a2 = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _a2.maxRetries) || 3;
14269
+ const maxRetries = ((_b = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _b.maxRetries) || 3;
14249
14270
  if (this.currentRetries < maxRetries) {
14250
14271
  console.log("Camera Recorder retry", this.currentRetries);
14251
14272
  this.currentRetries++;
@@ -14255,13 +14276,13 @@ Setting: ${JSON.stringify(settings, null, 2)}`
14255
14276
  }
14256
14277
  }
14257
14278
  this.stopped = false;
14258
- if (((_b = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _b.detectPerson) || ((_c2 = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _c2.detectCellPhone) || ((_d = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _d.detectFace)) {
14279
+ 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)) {
14259
14280
  await this.initializeDetectors();
14260
14281
  }
14261
- if ((_e3 = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _e3.detectFace) {
14282
+ if ((_f = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _f.detectFace) {
14262
14283
  await this.faceDetection.enableCam(this.cameraStream);
14263
14284
  }
14264
- if (((_f = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _f.detectPerson) || ((_g = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _g.detectCellPhone)) {
14285
+ if (((_g = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _g.detectPerson) || ((_h = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _h.detectCellPhone)) {
14265
14286
  await this.objectDetection.enableCam(this.cameraStream);
14266
14287
  }
14267
14288
  this.filesToUpload = [];
@@ -14500,7 +14521,7 @@ Setting: ${JSON.stringify(settings, null, 2)}`
14500
14521
  if (this.blobs != null)
14501
14522
  trackers.registerSaveOnSession(
14502
14523
  this.proctoringId,
14503
- `Blobs Length: ${this.blobs.length} Buffer Size: ${this.getBufferSize()} `
14524
+ `Blobs Length: ${this.blobs.length} Buffer Size: ${this.getBufferSize()} ChunkEnabled: ${this.isChunkEnabled}`
14504
14525
  );
14505
14526
  const settings = this.cameraStream.getVideoTracks()[0].getSettings();
14506
14527
  const settingsAudio = this.cameraStream.getAudioTracks()[0].getSettings();
@@ -14520,7 +14541,12 @@ Setting: ${JSON.stringify(settings, null, 2)}`
14520
14541
  });
14521
14542
  let finalBlob = rawBlob;
14522
14543
  if (typeof fixWebmDuration === "function") {
14523
- finalBlob = await fixWebmDuration(rawBlob, this.duration);
14544
+ try {
14545
+ finalBlob = await fixWebmDuration(rawBlob, this.duration);
14546
+ } catch (e3) {
14547
+ console.warn("Erro ao corrigir a dura\xE7\xE3o do v\xEDdeo", e3);
14548
+ finalBlob = rawBlob;
14549
+ }
14524
14550
  } else {
14525
14551
  console.warn("fixWebmDuration n\xE3o dispon\xEDvel");
14526
14552
  }
@@ -16666,19 +16692,9 @@ var ProctoringUploader = class {
16666
16692
  }
16667
16693
  toFile(rec) {
16668
16694
  const suffix = rec.origin === "Screen" /* Screen */ ? "screen" : rec.origin === "Camera" /* Camera */ ? "camera" : "audio";
16669
- const name = `EP_${this.proctoringId}_${suffix}_0.webm`;
16695
+ const name = `EP_${this.session.id}_${suffix}_0.webm`;
16670
16696
  return new File([rec.arrayBuffer], name, { type: "video/webm" });
16671
16697
  }
16672
- getFileType(origin2) {
16673
- switch (origin2) {
16674
- case "Camera" /* Camera */:
16675
- return "Camera";
16676
- case "Screen" /* Screen */:
16677
- return "Screen";
16678
- case "Mic" /* Mic */:
16679
- return "Audio";
16680
- }
16681
- }
16682
16698
  async uploadFile(rec, token, onProgress) {
16683
16699
  const file = this.toFile(rec);
16684
16700
  for await (const uploadService of this.uploadServices) {
@@ -16690,24 +16706,23 @@ var ProctoringUploader = class {
16690
16706
  }
16691
16707
  },
16692
16708
  token
16693
- ).catch(async (e3) => {
16694
- console.log("Upload File Error", e3), trackers.registerError(
16695
- this.proctoringId,
16696
- `Upload File
16709
+ ).catch(
16710
+ async (e3) => {
16711
+ console.log("Upload File Error", e3), trackers.registerError(this.proctoringId, `Upload File
16697
16712
  Name: ${file.name}
16698
16713
  Error: ${e3.message}
16699
- Size: ${e3.error}`
16700
- );
16701
- await uploadService.upload(
16702
- {
16703
- file,
16704
- onProgress: (progress) => {
16705
- if (onProgress) onProgress(progress);
16706
- }
16707
- },
16708
- token
16709
- );
16710
- });
16714
+ Size: ${e3.error}`);
16715
+ await uploadService.upload(
16716
+ {
16717
+ file,
16718
+ onProgress: (progress) => {
16719
+ if (onProgress) onProgress(progress);
16720
+ }
16721
+ },
16722
+ token
16723
+ );
16724
+ }
16725
+ );
16711
16726
  if (result) {
16712
16727
  let fileType = "";
16713
16728
  if (rec.origin === "Camera" /* Camera */) {
@@ -16746,8 +16761,9 @@ var AlertRecorder = class {
16746
16761
  this.handleLostFocus();
16747
16762
  }
16748
16763
  };
16764
+ this.lastLostFocusTime = Date.now();
16749
16765
  this.handleLostFocus = () => {
16750
- if (this.getRelativeTime() > 1e4) {
16766
+ if (this.getRelativeTime() > 1e4 && Date.now() - this.lastLostFocusTime > 1e3) {
16751
16767
  const alertPayload = {
16752
16768
  begin: this.getRelativeTime(),
16753
16769
  end: 0,
@@ -16756,9 +16772,13 @@ var AlertRecorder = class {
16756
16772
  };
16757
16773
  this.onLostFocusCallback(alertPayload);
16758
16774
  this.alerts.push(alertPayload);
16775
+ this.lastLostFocusTime = Date.now();
16759
16776
  }
16760
16777
  };
16778
+ this.lastReturnFocusTime = Date.now();
16761
16779
  this.handleReturnFocus = () => {
16780
+ const diffTime = Date.now() - this.lastReturnFocusTime;
16781
+ if (diffTime < 1e3) return;
16762
16782
  const lastAlert = this.alerts[this.alerts.length - 1];
16763
16783
  if (lastAlert) {
16764
16784
  this.onFocusCallback({
@@ -16769,6 +16789,7 @@ var AlertRecorder = class {
16769
16789
  });
16770
16790
  lastAlert.end = this.getRelativeTime();
16771
16791
  }
16792
+ this.lastReturnFocusTime = Date.now();
16772
16793
  };
16773
16794
  // 2. SPLIT SCREEN DETECTION
16774
16795
  this.handleResize = () => {
@@ -16853,6 +16874,8 @@ var AlertRecorder = class {
16853
16874
  attachListeners() {
16854
16875
  if (this.optionsProctoring.captureScreen) {
16855
16876
  window.addEventListener("visibilitychange", this.handleVisibilityChange);
16877
+ window.addEventListener("blur", this.handleLostFocus);
16878
+ window.addEventListener("focus", this.handleReturnFocus);
16856
16879
  window.addEventListener("resize", this.handleResize);
16857
16880
  window.document.addEventListener("copy", this.handleCopy);
16858
16881
  window.document.addEventListener("cut", this.handleCut);
@@ -16861,6 +16884,8 @@ var AlertRecorder = class {
16861
16884
  }
16862
16885
  detachListeners() {
16863
16886
  window.removeEventListener("visibilitychange", this.handleVisibilityChange);
16887
+ window.removeEventListener("blur", this.handleLostFocus);
16888
+ window.removeEventListener("focus", this.handleReturnFocus);
16864
16889
  window.removeEventListener("resize", this.handleResize);
16865
16890
  window.document.removeEventListener("copy", this.handleCopy);
16866
16891
  window.document.removeEventListener("cut", this.handleCut);
@@ -19531,7 +19556,12 @@ var ScreenRecorder = class {
19531
19556
  });
19532
19557
  let finalBlob = rawBlob;
19533
19558
  if (typeof fixWebmDuration2 === "function") {
19534
- finalBlob = await fixWebmDuration2(rawBlob, this.duration);
19559
+ try {
19560
+ finalBlob = await fixWebmDuration2(rawBlob, this.duration);
19561
+ } catch (e3) {
19562
+ console.warn("Erro ao corrigir a dura\xE7\xE3o do v\xEDdeo", e3);
19563
+ finalBlob = rawBlob;
19564
+ }
19535
19565
  } else {
19536
19566
  console.warn("fixWebmDuration n\xE3o dispon\xEDvel");
19537
19567
  }
package/index.js CHANGED
@@ -30868,7 +30868,7 @@ var proctoringId;
30868
30868
  function setRecorderProctoringId(id) {
30869
30869
  proctoringId = id;
30870
30870
  }
30871
- function recorder(stream4, buffer, onBufferSizeError = false, onBufferSizeErrorCallback, audio = false) {
30871
+ function recorder(stream4, buffer, onBufferSizeError = false, onBufferSizeErrorCallback, audio = false, recorderOpts) {
30872
30872
  let resolvePromise;
30873
30873
  let onBufferSizeInterval;
30874
30874
  let lastEvent;
@@ -30876,6 +30876,7 @@ function recorder(stream4, buffer, onBufferSizeError = false, onBufferSizeErrorC
30876
30876
  bufferSize = 0;
30877
30877
  let startTime;
30878
30878
  let duration = 0;
30879
+ let chunkIndex = 0;
30879
30880
  let recorderOptions = {
30880
30881
  // eslint-disable-next-line no-useless-escape
30881
30882
  mimeType: "video/webm",
@@ -30910,6 +30911,10 @@ function recorder(stream4, buffer, onBufferSizeError = false, onBufferSizeErrorC
30910
30911
  mediaRecorder2.ondataavailable = (e3) => {
30911
30912
  bufferSize = bufferSize + e3.data.size;
30912
30913
  if (e3.data.size > 0) {
30914
+ if (recorderOpts == null ? void 0 : recorderOpts.onChunkAvailable) {
30915
+ recorderOpts.onChunkAvailable(e3.data, chunkIndex);
30916
+ chunkIndex++;
30917
+ }
30913
30918
  buffer.push(e3.data);
30914
30919
  }
30915
30920
  };
@@ -30941,7 +30946,13 @@ function recorder(stream4, buffer, onBufferSizeError = false, onBufferSizeErrorC
30941
30946
  };
30942
30947
  try {
30943
30948
  console.log("State antes do start:", recorder2.state);
30944
- recorder2.start(1e4);
30949
+ chunkIndex = 0;
30950
+ if ((recorderOpts == null ? void 0 : recorderOpts.timeslice) && (recorderOpts == null ? void 0 : recorderOpts.timeslice) > 0) {
30951
+ recorder2.start(recorderOpts.timeslice);
30952
+ } else {
30953
+ recorder2.start(1e4);
30954
+ }
30955
+ bufferSize = 0;
30945
30956
  startTime = new Date(Date.now());
30946
30957
  } catch (e3) {
30947
30958
  console.error("Recorder erro ao chamar start event:", e3);
@@ -31355,9 +31366,6 @@ var ObjectDetection = class extends BaseDetection {
31355
31366
  }
31356
31367
  };
31357
31368
 
31358
- // src/new-flow/recorders/CameraRecorder.ts
31359
- var import_jszip_min = __toESM(require_jszip_min());
31360
-
31361
31369
  // src/new-flow/chunk/ChunkStorageService.ts
31362
31370
  var _ChunkStorageService = class _ChunkStorageService {
31363
31371
  constructor() {
@@ -31969,6 +31977,7 @@ var BackgroundUploadService = class _BackgroundUploadService {
31969
31977
  };
31970
31978
 
31971
31979
  // src/new-flow/recorders/CameraRecorder.ts
31980
+ var import_jszip_min = __toESM(require_jszip_min());
31972
31981
  var pkg = require_fix_webm_duration();
31973
31982
  var fixWebmDuration = pkg.default || pkg;
31974
31983
  var _CameraRecorder = class _CameraRecorder {
@@ -32041,11 +32050,11 @@ var _CameraRecorder = class _CameraRecorder {
32041
32050
  paramsConfig && (this.paramsConfig = paramsConfig);
32042
32051
  }
32043
32052
  /**
32044
- * Determina se o fluxo de chunks e lifecycle deve estar ativo.
32045
- * Retorna true se:
32046
- * 1. O proctoringId já foi definido (ou seja, estamos em uma sessão real, NÃO no checkDevices)
32047
- * 2. E (`useChunkRecording` foi explicitamente setado como true OU o dispositivo é mobile)
32048
- */
32053
+ * Determina se o fluxo de chunks e lifecycle deve estar ativo.
32054
+ * Retorna true se:
32055
+ * 1. O proctoringId já foi definido (ou seja, estamos em uma sessão real, NÃO no checkDevices)
32056
+ * 2. E (`useChunkRecording` foi explicitamente setado como true OU o dispositivo é mobile)
32057
+ */
32049
32058
  get isChunkEnabled() {
32050
32059
  return !!this.proctoringId && this.options.proctoringType === "REALTIME" && !isSafeBrowser();
32051
32060
  }
@@ -32308,9 +32317,15 @@ Setting: ${JSON.stringify(settings, null, 2)}`
32308
32317
  await new Promise((r3) => setTimeout(r3, 300));
32309
32318
  }
32310
32319
  async startRecording() {
32311
- var _a2, _b, _c2, _d, _e3, _f, _g;
32320
+ var _a2, _b, _c2, _d, _e3, _f, _g, _h;
32312
32321
  await this.startStream();
32313
32322
  await this.attachAndWarmup(this.cameraStream);
32323
+ const recorderOpts = this.isChunkEnabled ? {
32324
+ timeslice: _CameraRecorder.CHUNK_TIMESLICE_MS,
32325
+ onChunkAvailable: (blob, idx) => {
32326
+ this.handleNewChunk(blob, idx);
32327
+ }
32328
+ } : {};
32314
32329
  const {
32315
32330
  startRecording,
32316
32331
  stopRecording,
@@ -32326,7 +32341,8 @@ Setting: ${JSON.stringify(settings, null, 2)}`
32326
32341
  this.blobs,
32327
32342
  this.options.onBufferSizeError,
32328
32343
  (e3) => this.bufferError(e3),
32329
- false
32344
+ false,
32345
+ recorderOpts
32330
32346
  );
32331
32347
  this.recordingStart = startRecording;
32332
32348
  this.recordingStop = stopRecording;
@@ -32336,13 +32352,18 @@ Setting: ${JSON.stringify(settings, null, 2)}`
32336
32352
  this.getBufferSize = getBufferSize;
32337
32353
  this.getStartTime = getStartTime;
32338
32354
  this.getDuration = getDuration;
32355
+ this.chunkIndex = 0;
32356
+ if (this.isChunkEnabled) {
32357
+ (_a2 = this.backgroundUpload) == null ? void 0 : _a2.start();
32358
+ this.setupLifecycleListeners();
32359
+ }
32339
32360
  try {
32340
32361
  await new Promise((r3) => setTimeout(r3, 500));
32341
32362
  await this.recordingStart();
32342
32363
  } catch (error) {
32343
32364
  console.log("Camera Recorder error", error);
32344
32365
  this.stopRecording();
32345
- const maxRetries = ((_a2 = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _a2.maxRetries) || 3;
32366
+ const maxRetries = ((_b = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _b.maxRetries) || 3;
32346
32367
  if (this.currentRetries < maxRetries) {
32347
32368
  console.log("Camera Recorder retry", this.currentRetries);
32348
32369
  this.currentRetries++;
@@ -32352,13 +32373,13 @@ Setting: ${JSON.stringify(settings, null, 2)}`
32352
32373
  }
32353
32374
  }
32354
32375
  this.stopped = false;
32355
- if (((_b = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _b.detectPerson) || ((_c2 = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _c2.detectCellPhone) || ((_d = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _d.detectFace)) {
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)) {
32356
32377
  await this.initializeDetectors();
32357
32378
  }
32358
- if ((_e3 = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _e3.detectFace) {
32379
+ if ((_f = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _f.detectFace) {
32359
32380
  await this.faceDetection.enableCam(this.cameraStream);
32360
32381
  }
32361
- if (((_f = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _f.detectPerson) || ((_g = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _g.detectCellPhone)) {
32382
+ if (((_g = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _g.detectPerson) || ((_h = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _h.detectCellPhone)) {
32362
32383
  await this.objectDetection.enableCam(this.cameraStream);
32363
32384
  }
32364
32385
  this.filesToUpload = [];
@@ -32597,7 +32618,7 @@ Setting: ${JSON.stringify(settings, null, 2)}`
32597
32618
  if (this.blobs != null)
32598
32619
  trackers.registerSaveOnSession(
32599
32620
  this.proctoringId,
32600
- `Blobs Length: ${this.blobs.length} Buffer Size: ${this.getBufferSize()} `
32621
+ `Blobs Length: ${this.blobs.length} Buffer Size: ${this.getBufferSize()} ChunkEnabled: ${this.isChunkEnabled}`
32601
32622
  );
32602
32623
  const settings = this.cameraStream.getVideoTracks()[0].getSettings();
32603
32624
  const settingsAudio = this.cameraStream.getAudioTracks()[0].getSettings();
@@ -32617,7 +32638,12 @@ Setting: ${JSON.stringify(settings, null, 2)}`
32617
32638
  });
32618
32639
  let finalBlob = rawBlob;
32619
32640
  if (typeof fixWebmDuration === "function") {
32620
- finalBlob = await fixWebmDuration(rawBlob, this.duration);
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
+ }
32621
32647
  } else {
32622
32648
  console.warn("fixWebmDuration n\xE3o dispon\xEDvel");
32623
32649
  }
@@ -34763,19 +34789,9 @@ var ProctoringUploader = class {
34763
34789
  }
34764
34790
  toFile(rec) {
34765
34791
  const suffix = rec.origin === "Screen" /* Screen */ ? "screen" : rec.origin === "Camera" /* Camera */ ? "camera" : "audio";
34766
- const name = `EP_${this.proctoringId}_${suffix}_0.webm`;
34792
+ const name = `EP_${this.session.id}_${suffix}_0.webm`;
34767
34793
  return new File([rec.arrayBuffer], name, { type: "video/webm" });
34768
34794
  }
34769
- getFileType(origin2) {
34770
- switch (origin2) {
34771
- case "Camera" /* Camera */:
34772
- return "Camera";
34773
- case "Screen" /* Screen */:
34774
- return "Screen";
34775
- case "Mic" /* Mic */:
34776
- return "Audio";
34777
- }
34778
- }
34779
34795
  async uploadFile(rec, token, onProgress) {
34780
34796
  const file = this.toFile(rec);
34781
34797
  for await (const uploadService of this.uploadServices) {
@@ -34787,24 +34803,23 @@ var ProctoringUploader = class {
34787
34803
  }
34788
34804
  },
34789
34805
  token
34790
- ).catch(async (e3) => {
34791
- console.log("Upload File Error", e3), trackers.registerError(
34792
- this.proctoringId,
34793
- `Upload File
34806
+ ).catch(
34807
+ async (e3) => {
34808
+ console.log("Upload File Error", e3), trackers.registerError(this.proctoringId, `Upload File
34794
34809
  Name: ${file.name}
34795
34810
  Error: ${e3.message}
34796
- Size: ${e3.error}`
34797
- );
34798
- await uploadService.upload(
34799
- {
34800
- file,
34801
- onProgress: (progress) => {
34802
- if (onProgress) onProgress(progress);
34803
- }
34804
- },
34805
- token
34806
- );
34807
- });
34811
+ Size: ${e3.error}`);
34812
+ await uploadService.upload(
34813
+ {
34814
+ file,
34815
+ onProgress: (progress) => {
34816
+ if (onProgress) onProgress(progress);
34817
+ }
34818
+ },
34819
+ token
34820
+ );
34821
+ }
34822
+ );
34808
34823
  if (result) {
34809
34824
  let fileType = "";
34810
34825
  if (rec.origin === "Camera" /* Camera */) {
@@ -34843,8 +34858,9 @@ var AlertRecorder = class {
34843
34858
  this.handleLostFocus();
34844
34859
  }
34845
34860
  };
34861
+ this.lastLostFocusTime = Date.now();
34846
34862
  this.handleLostFocus = () => {
34847
- if (this.getRelativeTime() > 1e4) {
34863
+ if (this.getRelativeTime() > 1e4 && Date.now() - this.lastLostFocusTime > 1e3) {
34848
34864
  const alertPayload = {
34849
34865
  begin: this.getRelativeTime(),
34850
34866
  end: 0,
@@ -34853,9 +34869,13 @@ var AlertRecorder = class {
34853
34869
  };
34854
34870
  this.onLostFocusCallback(alertPayload);
34855
34871
  this.alerts.push(alertPayload);
34872
+ this.lastLostFocusTime = Date.now();
34856
34873
  }
34857
34874
  };
34875
+ this.lastReturnFocusTime = Date.now();
34858
34876
  this.handleReturnFocus = () => {
34877
+ const diffTime = Date.now() - this.lastReturnFocusTime;
34878
+ if (diffTime < 1e3) return;
34859
34879
  const lastAlert = this.alerts[this.alerts.length - 1];
34860
34880
  if (lastAlert) {
34861
34881
  this.onFocusCallback({
@@ -34866,6 +34886,7 @@ var AlertRecorder = class {
34866
34886
  });
34867
34887
  lastAlert.end = this.getRelativeTime();
34868
34888
  }
34889
+ this.lastReturnFocusTime = Date.now();
34869
34890
  };
34870
34891
  // 2. SPLIT SCREEN DETECTION
34871
34892
  this.handleResize = () => {
@@ -34950,6 +34971,8 @@ var AlertRecorder = class {
34950
34971
  attachListeners() {
34951
34972
  if (this.optionsProctoring.captureScreen) {
34952
34973
  window.addEventListener("visibilitychange", this.handleVisibilityChange);
34974
+ window.addEventListener("blur", this.handleLostFocus);
34975
+ window.addEventListener("focus", this.handleReturnFocus);
34953
34976
  window.addEventListener("resize", this.handleResize);
34954
34977
  window.document.addEventListener("copy", this.handleCopy);
34955
34978
  window.document.addEventListener("cut", this.handleCut);
@@ -34958,6 +34981,8 @@ var AlertRecorder = class {
34958
34981
  }
34959
34982
  detachListeners() {
34960
34983
  window.removeEventListener("visibilitychange", this.handleVisibilityChange);
34984
+ window.removeEventListener("blur", this.handleLostFocus);
34985
+ window.removeEventListener("focus", this.handleReturnFocus);
34961
34986
  window.removeEventListener("resize", this.handleResize);
34962
34987
  window.document.removeEventListener("copy", this.handleCopy);
34963
34988
  window.document.removeEventListener("cut", this.handleCut);
@@ -37628,7 +37653,12 @@ var ScreenRecorder = class {
37628
37653
  });
37629
37654
  let finalBlob = rawBlob;
37630
37655
  if (typeof fixWebmDuration2 === "function") {
37631
- finalBlob = await fixWebmDuration2(rawBlob, this.duration);
37656
+ try {
37657
+ finalBlob = await fixWebmDuration2(rawBlob, this.duration);
37658
+ } catch (e3) {
37659
+ console.warn("Erro ao corrigir a dura\xE7\xE3o do v\xEDdeo", e3);
37660
+ finalBlob = rawBlob;
37661
+ }
37632
37662
  } else {
37633
37663
  console.warn("fixWebmDuration n\xE3o dispon\xEDvel");
37634
37664
  }
@@ -11,6 +11,5 @@ export declare class ProctoringUploader {
11
11
  private uploadRecordings;
12
12
  private uploadAllFiles;
13
13
  private toFile;
14
- private getFileType;
15
14
  private uploadFile;
16
15
  }
@@ -25,7 +25,9 @@ export declare class AlertRecorder implements IRecorder {
25
25
  private attachListeners;
26
26
  private detachListeners;
27
27
  private handleVisibilityChange;
28
+ lastLostFocusTime: number;
28
29
  private handleLostFocus;
30
+ lastReturnFocusTime: number;
29
31
  private handleReturnFocus;
30
32
  private handleResize;
31
33
  private handleUserActivity;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "easyproctor-hml",
3
- "version": "2.8.0",
3
+ "version": "3.1.0",
4
4
  "description": "Modulo web de gravação do EasyProctor",
5
5
  "main": "./index.js",
6
6
  "module": "./esm/index.js",
@@ -1,5 +1,9 @@
1
1
  export declare function setRecorderProctoringId(id: string): void;
2
- export default function recorder(stream: MediaStream, buffer: Blob[], onBufferSizeError?: boolean, onBufferSizeErrorCallback?: (e?: any) => void, audio?: boolean): {
2
+ export interface RecorderOptions {
3
+ timeslice?: number;
4
+ onChunkAvailable?: (blob: Blob, chunkIndex: number) => void;
5
+ }
6
+ export default function recorder(stream: MediaStream, buffer: Blob[], onBufferSizeError?: boolean, onBufferSizeErrorCallback?: (e?: any) => void, audio?: boolean, recorderOpts?: RecorderOptions): {
3
7
  startRecording: () => Promise<void>;
4
8
  stopRecording: () => Promise<void>;
5
9
  pauseRecording: () => Promise<void>;