easyproctor-hml 2.5.29 → 2.5.31

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/esm/index.js CHANGED
@@ -12290,38 +12290,125 @@ function recorder(stream, buffer, videoOptions, onBufferSizeError = false, onBuf
12290
12290
  };
12291
12291
  }
12292
12292
  console.log("recorderOptions bitsPerSecond", recorderOptions.videoBitsPerSecond);
12293
- const mediaRecorder = new MediaRecorder(stream, recorderOptions);
12294
- mediaRecorder.ondataavailable = (e2) => {
12295
- if (mediaRecorder.state != "recording") return;
12296
- bufferSize = bufferSize + e2.data.size;
12297
- console.log("video tracks length > 0", stream.getVideoTracks().length > 0);
12298
- if (stream.getVideoTracks().length > 0) {
12299
- const videoTrack = stream.getVideoTracks()[0];
12300
- console.log(videoTrack.readyState);
12301
- console.log(videoTrack.enabled);
12302
- }
12303
- if (e2.data.size > 0) {
12304
- buffer.push(e2.data);
12305
- }
12306
- if (!stopped) {
12307
- if (lastEvent && e2.data.size === lastEvent.data.size || e2.data.size === 0) {
12308
- proctoringId && lastEvent && e2.data.size === lastEvent.data.size && trackers.registerOnBufferSizeError(
12309
- proctoringId,
12310
- `onBufferSizeError: Recorder size freezed: ${e2.data.size} Mb`
12311
- );
12312
- proctoringId && e2.data.size === 0 && trackers.registerOnBufferSizeError(
12313
- proctoringId,
12314
- `onBufferSizeError: Recorder size equal 0 Mb`
12315
- );
12316
- console.log("onbuffer size error" + e2.data.size);
12317
- onBufferSizeErrorCallback && onBufferSizeErrorCallback();
12293
+ function buildMediaRecorder(stream2, recorderOptions2) {
12294
+ const tracks = stream2.getTracks();
12295
+ if (tracks.length == 0) {
12296
+ throw new Error("No tracks found");
12297
+ }
12298
+ const invalidTracks = tracks.find((t2) => t2.readyState != "live");
12299
+ if (invalidTracks) {
12300
+ throw new Error("Track not live: " + invalidTracks.label);
12301
+ }
12302
+ console.log("buildMediaRecorder tracks OK");
12303
+ let mediaRecorder2 = new MediaRecorder(stream2, recorderOptions2);
12304
+ console.log("buildMediaRecorder mediaRecorder OK");
12305
+ mediaRecorder2.ondataavailable = (e2) => {
12306
+ bufferSize = bufferSize + e2.data.size;
12307
+ console.log("video tracks length > 0", stream2.getVideoTracks().length > 0);
12308
+ if (stream2.getVideoTracks().length > 0) {
12309
+ const videoTrack = stream2.getVideoTracks()[0];
12310
+ console.log(videoTrack.readyState);
12311
+ console.log(videoTrack.enabled);
12312
+ }
12313
+ if (e2.data.size > 0) {
12314
+ buffer.push(e2.data);
12315
+ }
12316
+ if (!stopped) {
12317
+ if (lastEvent && e2.data.size === lastEvent.data.size || e2.data.size === 0) {
12318
+ proctoringId && lastEvent && e2.data.size === lastEvent.data.size && trackers.registerOnBufferSizeError(
12319
+ proctoringId,
12320
+ `onBufferSizeError: Recorder size freezed: ${e2.data.size} Mb`
12321
+ );
12322
+ proctoringId && e2.data.size === 0 && trackers.registerOnBufferSizeError(
12323
+ proctoringId,
12324
+ `onBufferSizeError: Recorder size equal 0 Mb`
12325
+ );
12326
+ console.log("onbuffer size error" + e2.data.size);
12327
+ onBufferSizeErrorCallback && onBufferSizeErrorCallback();
12328
+ }
12329
+ lastEvent = e2;
12330
+ } else {
12331
+ resolvePromise && resolvePromise();
12318
12332
  }
12319
- lastEvent = e2;
12320
- } else {
12321
- resolvePromise && resolvePromise();
12333
+ };
12334
+ return mediaRecorder2;
12335
+ }
12336
+ let mediaRecorder = buildMediaRecorder(stream, recorderOptions);
12337
+ async function startRecorder(recorder2) {
12338
+ return new Promise((resolve, reject) => {
12339
+ var _a2, _b;
12340
+ let started = false;
12341
+ recorder2.onstart = () => {
12342
+ started = true;
12343
+ resolve();
12344
+ };
12345
+ recorder2.onerror = (ev) => {
12346
+ console.error("Recorder error event:", ev);
12347
+ stream.getTracks().forEach((t2) => console.log(t2.readyState));
12348
+ if ("error" in ev) {
12349
+ const err = ev.error;
12350
+ console.error("Error name:", err == null ? void 0 : err.name);
12351
+ console.error("Error message:", err == null ? void 0 : err.message);
12352
+ reject(err || ev);
12353
+ } else {
12354
+ console.warn("Evento sem propriedade error");
12355
+ reject(ev);
12356
+ }
12357
+ };
12358
+ try {
12359
+ console.log("State antes do start:", recorder2.state);
12360
+ console.log("MimeType:", recorder2.mimeType);
12361
+ recorder2.start(1e4);
12362
+ } catch (e2) {
12363
+ console.error("Recorder erro ao chamar start event:", e2);
12364
+ console.error("Erro real:", e2, e2 == null ? void 0 : e2.error, (_a2 = e2 == null ? void 0 : e2.error) == null ? void 0 : _a2.name, (_b = e2 == null ? void 0 : e2.error) == null ? void 0 : _b.message);
12365
+ console.error("Erro real 2:", e2, e2 == null ? void 0 : e2.message, e2 == null ? void 0 : e2.name);
12366
+ stream.getTracks().forEach((t2) => console.log(t2.readyState));
12367
+ return reject(e2);
12368
+ }
12369
+ setTimeout(() => {
12370
+ if (!started) {
12371
+ console.error("Timeout ao iniciar o recorder");
12372
+ reject(new Error("Timeout ao iniciar o recorder"));
12373
+ }
12374
+ }, 2e3);
12375
+ });
12376
+ }
12377
+ async function startWithRetry(recorder2) {
12378
+ for (let i2 = 0; i2 < 3; i2++) {
12379
+ try {
12380
+ console.log("startWithRetry try", i2);
12381
+ await startRecorder(recorder2);
12382
+ if (recorder2.state === "recording") {
12383
+ bufferSize = 0;
12384
+ stopped = false;
12385
+ return;
12386
+ }
12387
+ } catch (e2) {
12388
+ console.error("Erro ao iniciar o recorder:", e2);
12389
+ }
12390
+ await new Promise((r2) => setTimeout(r2, 300));
12391
+ if (recorder2) {
12392
+ try {
12393
+ if (recorder2.state !== "inactive") {
12394
+ recorder2.stop();
12395
+ console.log("Recorder antigo parado");
12396
+ }
12397
+ } catch (e2) {
12398
+ console.warn("Erro ao parar recorder antigo:", e2);
12399
+ }
12400
+ }
12401
+ recorder2 = buildMediaRecorder(stream, recorderOptions);
12322
12402
  }
12323
- };
12324
- function startRecording() {
12403
+ throw new Error("Falha ao iniciar o recorder");
12404
+ }
12405
+ async function startRecording() {
12406
+ try {
12407
+ await startWithRetry(mediaRecorder);
12408
+ } catch (e2) {
12409
+ throw e2;
12410
+ }
12411
+ return;
12325
12412
  return new Promise((resolve, reject) => {
12326
12413
  var timeSlice = 1e4;
12327
12414
  if ((videoOptions == null ? void 0 : videoOptions.timeSlice) != void 0) {
@@ -12349,9 +12436,9 @@ function recorder(stream, buffer, videoOptions, onBufferSizeError = false, onBuf
12349
12436
  stopped = false;
12350
12437
  setTimeout(async () => {
12351
12438
  if (mediaRecorder.state == "recording") return;
12352
- console.log("onstart Timeout");
12439
+ +console.log("onstart Timeout");
12353
12440
  reject(new Error("onstart Timeout"));
12354
- }, 5e3);
12441
+ }, 2e3);
12355
12442
  });
12356
12443
  }
12357
12444
  function stopRecording() {
@@ -12394,6 +12481,7 @@ function recorder(stream, buffer, videoOptions, onBufferSizeError = false, onBuf
12394
12481
  }
12395
12482
  return {
12396
12483
  startRecording,
12484
+ startWithRetry,
12397
12485
  stopRecording,
12398
12486
  pauseRecording,
12399
12487
  resumeRecording,
@@ -12758,6 +12846,7 @@ var CameraRecorder = class {
12758
12846
  this.isCanvasLoopActive = false;
12759
12847
  this.hardwareStream = null;
12760
12848
  this.internalClonedStream = null;
12849
+ this.videoElement = null;
12761
12850
  this.currentRetries = 0;
12762
12851
  this.packageCount = 0;
12763
12852
  this.noiseWait = 20;
@@ -12888,8 +12977,131 @@ Setting: ${JSON.stringify(settings, null, 2)}`
12888
12977
  this.hardwareStream = null;
12889
12978
  }
12890
12979
  }
12980
+ async waitForVideoFlow() {
12981
+ return new Promise((resolve) => {
12982
+ const check = () => {
12983
+ var _a2;
12984
+ if (this.videoElement && ((_a2 = this.videoElement) == null ? void 0 : _a2.readyState) >= 3) return resolve();
12985
+ else requestAnimationFrame(check);
12986
+ };
12987
+ check();
12988
+ });
12989
+ }
12990
+ async attachAndWarmup(stream) {
12991
+ this.videoElement = document.createElement("video");
12992
+ this.videoElement.srcObject = stream;
12993
+ this.videoElement.muted = true;
12994
+ await this.videoElement.play().catch((e2) => {
12995
+ });
12996
+ console.log("cameraStream.getVideoTracks() length:", this.cameraStream.getVideoTracks().length);
12997
+ await new Promise((resolve) => {
12998
+ var _a2;
12999
+ if (this.videoElement && ((_a2 = this.videoElement) == null ? void 0 : _a2.readyState) >= 1) return resolve();
13000
+ if (this.videoElement)
13001
+ this.videoElement.onloadedmetadata = () => resolve();
13002
+ });
13003
+ console.log("metadata ok");
13004
+ await this.waitForVideoFlow();
13005
+ console.log("waitForVideoFlow ok");
13006
+ await new Promise((r2) => setTimeout(r2, 300));
13007
+ }
12891
13008
  async startRecording(options) {
12892
- var _a2, _b, _c2, _d, _e2, _f, _g, _h;
13009
+ var _a2, _b, _c2, _d, _e2, _f, _g;
13010
+ console.log("startRecording Camera Recorder");
13011
+ if ((((_a2 = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _a2.detectPerson) || ((_b = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _b.detectCellPhone) || ((_c2 = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _c2.detectFace)) && !(options == null ? void 0 : options.retry)) {
13012
+ console.log("startRecording Camera Recorder initializeDetectors");
13013
+ await this.initializeDetectors();
13014
+ }
13015
+ const { cameraId, microphoneId } = this.options;
13016
+ const constraints = {
13017
+ audio: { deviceId: microphoneId },
13018
+ video: {
13019
+ deviceId: cameraId,
13020
+ width: this.videoOptions.width,
13021
+ height: this.videoOptions.height,
13022
+ frameRate: 15
13023
+ }
13024
+ };
13025
+ try {
13026
+ this.hardwareStream = await navigator.mediaDevices.getUserMedia(
13027
+ constraints
13028
+ );
13029
+ this.cameraStream = this.hardwareStream;
13030
+ } catch (error) {
13031
+ console.log("startRecording Camera Recorder error", error);
13032
+ if (error.toString() == "NotReadableError: Could not start video source")
13033
+ throw "N\xE3o foi poss\xEDvel conectar a camera, ela pode estar sendo utilizada por outro programa";
13034
+ throw error;
13035
+ }
13036
+ await this.attachAndWarmup(this.cameraStream);
13037
+ const {
13038
+ startRecording,
13039
+ stopRecording,
13040
+ pauseRecording,
13041
+ resumeRecording,
13042
+ recorderOptions,
13043
+ getBufferSize
13044
+ } = recorder(
13045
+ this.cameraStream,
13046
+ // streamToRecord,
13047
+ this.blobs,
13048
+ this.videoOptions,
13049
+ this.options.onBufferSizeError,
13050
+ (e2) => this.bufferError(e2),
13051
+ false
13052
+ );
13053
+ this.recordingStart = startRecording;
13054
+ this.recordingStop = stopRecording;
13055
+ this.recordingPause = pauseRecording;
13056
+ this.recordingResume = resumeRecording;
13057
+ this.recorderOptions = recorderOptions;
13058
+ this.getBufferSize = getBufferSize;
13059
+ try {
13060
+ await new Promise((r2) => setTimeout(r2, 500));
13061
+ await this.recordingStart();
13062
+ } catch (error) {
13063
+ console.log("startRecording Camera Recorder error", error);
13064
+ throw error;
13065
+ }
13066
+ const track = this.cameraStream.getVideoTracks()[0];
13067
+ const settings = track.getSettings();
13068
+ let { width = 0, height = 0 } = settings;
13069
+ const isPortrait = (_d = screen.orientation) == null ? void 0 : _d.type.includes("portrait");
13070
+ if (isPortrait && isMobileDevice()) {
13071
+ if (this.videoOptions.width == height && this.videoOptions.height == width) {
13072
+ [width, height] = [height, width];
13073
+ }
13074
+ }
13075
+ if (this.videoOptions.minWidth > width || this.videoOptions.minHeight > height) {
13076
+ throw STREAM_UNDER_MINIMUM_PERMITTED;
13077
+ } else if (this.videoOptions.width !== width || this.videoOptions.height !== height) {
13078
+ trackers.registerAnotherStream(
13079
+ this.proctoringId,
13080
+ `Maybe have another stream active
13081
+ Video Options: ${JSON.stringify(
13082
+ this.videoOptions,
13083
+ null,
13084
+ 2
13085
+ )}
13086
+ Setting: ${JSON.stringify(settings, null, 2)}`
13087
+ );
13088
+ throw ANOTHER_STREAM_ACTIVE;
13089
+ }
13090
+ if ((_e2 = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _e2.detectFace) {
13091
+ await this.faceDetection.enableCam(this.cameraStream);
13092
+ }
13093
+ if (((_f = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _f.detectPerson) || ((_g = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _g.detectCellPhone)) {
13094
+ await this.objectDetection.enableCam(this.cameraStream);
13095
+ }
13096
+ this.filesToUpload = [];
13097
+ if (this.options.proctoringType == "REALTIME") {
13098
+ this.captureFrame();
13099
+ }
13100
+ this.packageCount = 0;
13101
+ console.log("startRecording Camera Recorder OK");
13102
+ }
13103
+ async startRecordingOld(options) {
13104
+ var _a2, _b, _c2, _d, _e2, _f, _g;
12893
13105
  console.log("startRecording Camera Recorder");
12894
13106
  if ((((_a2 = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _a2.detectPerson) || ((_b = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _b.detectCellPhone) || ((_c2 = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _c2.detectFace)) && !(options == null ? void 0 : options.retry)) {
12895
13107
  console.log("startRecording Camera Recorder initializeDetectors");
@@ -12919,6 +13131,17 @@ Setting: ${JSON.stringify(settings, null, 2)}`
12919
13131
  const track = this.cameraStream.getVideoTracks()[0];
12920
13132
  const settings = track.getSettings();
12921
13133
  let { width = 0, height = 0 } = settings;
13134
+ console.log("cameraStream.getVideoTracks() length:", this.cameraStream.getVideoTracks().length);
13135
+ await new Promise((resolve) => {
13136
+ const interval = setInterval(() => {
13137
+ console.log("cameraStream.getVideoTracks()[0].readyState", this.cameraStream.getVideoTracks()[0].readyState);
13138
+ if (this.cameraStream.getVideoTracks()[0].readyState == "live") {
13139
+ clearInterval(interval);
13140
+ resolve();
13141
+ }
13142
+ }, 100);
13143
+ });
13144
+ await new Promise((r2) => setTimeout(r2, 300));
12922
13145
  const {
12923
13146
  startRecording,
12924
13147
  stopRecording,
@@ -12943,6 +13166,7 @@ Setting: ${JSON.stringify(settings, null, 2)}`
12943
13166
  this.getBufferSize = getBufferSize;
12944
13167
  console.log("startRecording Camera Recorder recordingStart");
12945
13168
  try {
13169
+ await new Promise((r2) => setTimeout(r2, 500));
12946
13170
  await this.recordingStart();
12947
13171
  } catch (error) {
12948
13172
  console.log("startRecording Camera Recorder error", error);
@@ -12969,11 +13193,10 @@ Setting: ${JSON.stringify(settings, null, 2)}`
12969
13193
  );
12970
13194
  throw ANOTHER_STREAM_ACTIVE;
12971
13195
  }
12972
- ((_e2 = this.paramsConfig.imageBehaviourParameters) == null ? void 0 : _e2.useUploadImage) && this.options.proctoringType == "IMAGE" && this.photoShotsCycle();
12973
- if ((_f = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _f.detectFace) {
13196
+ if ((_e2 = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _e2.detectFace) {
12974
13197
  await this.faceDetection.enableCam(this.cameraStream);
12975
13198
  }
12976
- if (((_g = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _g.detectPerson) || ((_h = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _h.detectCellPhone)) {
13199
+ if (((_f = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _f.detectPerson) || ((_g = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _g.detectCellPhone)) {
12977
13200
  await this.objectDetection.enableCam(this.cameraStream);
12978
13201
  }
12979
13202
  this.filesToUpload = [];
@@ -12984,6 +13207,7 @@ Setting: ${JSON.stringify(settings, null, 2)}`
12984
13207
  console.log("startRecording Camera Recorder finished");
12985
13208
  }
12986
13209
  async stopRecording() {
13210
+ var _a2, _b, _c2;
12987
13211
  console.log("Stopping Camera Recorder...");
12988
13212
  this.isCanvasLoopActive = false;
12989
13213
  this.recordingStop && await this.recordingStop();
@@ -13003,8 +13227,18 @@ Setting: ${JSON.stringify(settings, null, 2)}`
13003
13227
  this.hardwareStream.getTracks().forEach((track) => track.stop());
13004
13228
  this.hardwareStream = null;
13005
13229
  }
13006
- } catch (e2) {
13007
- console.error("Erro ao parar os streams de m\xEDdia.");
13230
+ if (this.videoElement) {
13231
+ (_a2 = this.videoElement) == null ? void 0 : _a2.remove();
13232
+ this.videoElement = null;
13233
+ }
13234
+ if (this.video) {
13235
+ (_b = this.video) == null ? void 0 : _b.remove();
13236
+ }
13237
+ if (this.canvas) {
13238
+ (_c2 = this.canvas) == null ? void 0 : _c2.remove();
13239
+ }
13240
+ } catch (error) {
13241
+ console.error("Erro ao parar os streams de m\xEDdia.", error);
13008
13242
  }
13009
13243
  this.faceDetection && this.faceDetection.detecting && this.faceDetection.stopDetection();
13010
13244
  this.objectDetection && this.objectDetection.detecting && this.objectDetection.stopDetection();
@@ -13023,35 +13257,6 @@ Setting: ${JSON.stringify(settings, null, 2)}`
13023
13257
  async resumeRecording() {
13024
13258
  await this.recordingResume();
13025
13259
  }
13026
- photoShotsCycle() {
13027
- let imageFile;
13028
- this.configImageCapture();
13029
- this.imageInterval = setInterval(async () => {
13030
- this.canvas.getContext("2d").drawImage(
13031
- this.video,
13032
- 0,
13033
- 0,
13034
- this.videoOptions.width,
13035
- this.videoOptions.height
13036
- );
13037
- const image_data_url = this.canvas.toDataURL("image/jpeg");
13038
- imageFile = await this.getFile(
13039
- image_data_url,
13040
- `${this.proctoringId}_${this.imageCount + 1}.jpg`,
13041
- "image/jpeg"
13042
- );
13043
- if (imageFile && this.upload && this.backendToken) {
13044
- this.upload.upload(
13045
- {
13046
- file: imageFile
13047
- },
13048
- this.backendToken,
13049
- true
13050
- );
13051
- this.imageCount++;
13052
- }
13053
- }, this.paramsConfig.imageBehaviourParameters.uploadInterval * 1e3);
13054
- }
13055
13260
  async getCurrentImageBase64() {
13056
13261
  if (!this.video || !this.canvas) {
13057
13262
  this.configImageCapture();
@@ -15548,6 +15753,7 @@ var ScreenRecorder = class {
15548
15753
  this.recordingStop && await this.recordingStop();
15549
15754
  }
15550
15755
  async saveOnSession(session) {
15756
+ if (isMobileDevice()) return;
15551
15757
  session.addRecording({
15552
15758
  device: "",
15553
15759
  file: new File(this.blobs, `EP_${session.id}_screen_0.webm`, {
@@ -18605,7 +18811,6 @@ var _ExternalCameraChecker = class _ExternalCameraChecker {
18605
18811
  this.connection = null;
18606
18812
  this.context = context;
18607
18813
  this.onRealtimeAlertsCallback = onRealtimeAlertsCallback;
18608
- console.log("context -> ", context);
18609
18814
  this.backend = new BackendService({
18610
18815
  type: (context == null ? void 0 : context.type) || "prod",
18611
18816
  token: context.token
@@ -19659,6 +19864,7 @@ var Proctoring = class {
19659
19864
  try {
19660
19865
  console.log("start Proctoring recorder.startAll");
19661
19866
  await this.recorder.startAll();
19867
+ console.log("start Proctoring recorder.startAll ok");
19662
19868
  } catch (error) {
19663
19869
  console.log("start Proctoring error", error);
19664
19870
  alert(error);