easyproctor-hml 2.5.29 → 2.5.30

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
@@ -30387,38 +30387,93 @@ function recorder(stream4, buffer, videoOptions, onBufferSizeError = false, onBu
30387
30387
  };
30388
30388
  }
30389
30389
  console.log("recorderOptions bitsPerSecond", recorderOptions.videoBitsPerSecond);
30390
- const mediaRecorder = new MediaRecorder(stream4, recorderOptions);
30391
- mediaRecorder.ondataavailable = (e2) => {
30392
- if (mediaRecorder.state != "recording") return;
30393
- bufferSize = bufferSize + e2.data.size;
30394
- console.log("video tracks length > 0", stream4.getVideoTracks().length > 0);
30395
- if (stream4.getVideoTracks().length > 0) {
30396
- const videoTrack = stream4.getVideoTracks()[0];
30397
- console.log(videoTrack.readyState);
30398
- console.log(videoTrack.enabled);
30399
- }
30400
- if (e2.data.size > 0) {
30401
- buffer.push(e2.data);
30402
- }
30403
- if (!stopped) {
30404
- if (lastEvent && e2.data.size === lastEvent.data.size || e2.data.size === 0) {
30405
- proctoringId && lastEvent && e2.data.size === lastEvent.data.size && trackers.registerOnBufferSizeError(
30406
- proctoringId,
30407
- `onBufferSizeError: Recorder size freezed: ${e2.data.size} Mb`
30408
- );
30409
- proctoringId && e2.data.size === 0 && trackers.registerOnBufferSizeError(
30410
- proctoringId,
30411
- `onBufferSizeError: Recorder size equal 0 Mb`
30412
- );
30413
- console.log("onbuffer size error" + e2.data.size);
30414
- onBufferSizeErrorCallback && onBufferSizeErrorCallback();
30390
+ function buildMediaRecorder(stream5, recorderOptions2) {
30391
+ const tracks = stream5.getTracks();
30392
+ if (tracks.length == 0) {
30393
+ throw new Error("No tracks found");
30394
+ }
30395
+ const invalidTracks = tracks.find((t2) => t2.readyState != "live");
30396
+ if (invalidTracks) {
30397
+ throw new Error("Track not live: " + invalidTracks.label);
30398
+ }
30399
+ console.log("buildMediaRecorder tracks OK");
30400
+ let mediaRecorder2 = new MediaRecorder(stream5, recorderOptions2);
30401
+ console.log("buildMediaRecorder mediaRecorder OK");
30402
+ mediaRecorder2.ondataavailable = (e2) => {
30403
+ bufferSize = bufferSize + e2.data.size;
30404
+ console.log("video tracks length > 0", stream5.getVideoTracks().length > 0);
30405
+ if (stream5.getVideoTracks().length > 0) {
30406
+ const videoTrack = stream5.getVideoTracks()[0];
30407
+ console.log(videoTrack.readyState);
30408
+ console.log(videoTrack.enabled);
30409
+ }
30410
+ if (e2.data.size > 0) {
30411
+ buffer.push(e2.data);
30412
+ }
30413
+ if (!stopped) {
30414
+ if (lastEvent && e2.data.size === lastEvent.data.size || e2.data.size === 0) {
30415
+ proctoringId && lastEvent && e2.data.size === lastEvent.data.size && trackers.registerOnBufferSizeError(
30416
+ proctoringId,
30417
+ `onBufferSizeError: Recorder size freezed: ${e2.data.size} Mb`
30418
+ );
30419
+ proctoringId && e2.data.size === 0 && trackers.registerOnBufferSizeError(
30420
+ proctoringId,
30421
+ `onBufferSizeError: Recorder size equal 0 Mb`
30422
+ );
30423
+ console.log("onbuffer size error" + e2.data.size);
30424
+ onBufferSizeErrorCallback && onBufferSizeErrorCallback();
30425
+ }
30426
+ lastEvent = e2;
30427
+ } else {
30428
+ resolvePromise && resolvePromise();
30415
30429
  }
30416
- lastEvent = e2;
30417
- } else {
30418
- resolvePromise && resolvePromise();
30430
+ };
30431
+ return mediaRecorder2;
30432
+ }
30433
+ let mediaRecorder = buildMediaRecorder(stream4, recorderOptions);
30434
+ async function startRecorder(recorder2) {
30435
+ return new Promise((resolve, reject) => {
30436
+ let started = false;
30437
+ recorder2.onstart = () => {
30438
+ started = true;
30439
+ resolve();
30440
+ };
30441
+ recorder2.onerror = (e2) => {
30442
+ reject(e2);
30443
+ };
30444
+ try {
30445
+ recorder2.start(1e4);
30446
+ } catch (e2) {
30447
+ return reject(e2);
30448
+ }
30449
+ setTimeout(() => {
30450
+ if (!started) {
30451
+ reject(new Error("Timeout ao iniciar o recorder"));
30452
+ }
30453
+ }, 500);
30454
+ });
30455
+ }
30456
+ async function startWithRetry(recorder2) {
30457
+ for (let i2 = 0; i2 < 3; i2++) {
30458
+ try {
30459
+ console.log("startWithRetry try", i2);
30460
+ await startRecorder(recorder2);
30461
+ if (recorder2.state === "recording") {
30462
+ bufferSize = 0;
30463
+ stopped = false;
30464
+ return;
30465
+ }
30466
+ } catch (e2) {
30467
+ console.error("Erro ao iniciar o recorder:", e2);
30468
+ }
30469
+ await new Promise((r2) => setTimeout(r2, 300));
30470
+ recorder2 = buildMediaRecorder(stream4, recorderOptions);
30419
30471
  }
30420
- };
30421
- function startRecording() {
30472
+ throw new Error("Falha ao iniciar o recorder");
30473
+ }
30474
+ async function startRecording() {
30475
+ await startWithRetry(mediaRecorder);
30476
+ return;
30422
30477
  return new Promise((resolve, reject) => {
30423
30478
  var timeSlice = 1e4;
30424
30479
  if ((videoOptions == null ? void 0 : videoOptions.timeSlice) != void 0) {
@@ -30446,9 +30501,9 @@ function recorder(stream4, buffer, videoOptions, onBufferSizeError = false, onBu
30446
30501
  stopped = false;
30447
30502
  setTimeout(async () => {
30448
30503
  if (mediaRecorder.state == "recording") return;
30449
- console.log("onstart Timeout");
30504
+ +console.log("onstart Timeout");
30450
30505
  reject(new Error("onstart Timeout"));
30451
- }, 5e3);
30506
+ }, 2e3);
30452
30507
  });
30453
30508
  }
30454
30509
  function stopRecording() {
@@ -30491,6 +30546,7 @@ function recorder(stream4, buffer, videoOptions, onBufferSizeError = false, onBu
30491
30546
  }
30492
30547
  return {
30493
30548
  startRecording,
30549
+ startWithRetry,
30494
30550
  stopRecording,
30495
30551
  pauseRecording,
30496
30552
  resumeRecording,
@@ -30855,6 +30911,7 @@ var CameraRecorder = class {
30855
30911
  this.isCanvasLoopActive = false;
30856
30912
  this.hardwareStream = null;
30857
30913
  this.internalClonedStream = null;
30914
+ this.videoElement = null;
30858
30915
  this.currentRetries = 0;
30859
30916
  this.packageCount = 0;
30860
30917
  this.noiseWait = 20;
@@ -30985,8 +31042,131 @@ Setting: ${JSON.stringify(settings, null, 2)}`
30985
31042
  this.hardwareStream = null;
30986
31043
  }
30987
31044
  }
31045
+ async waitForVideoFlow() {
31046
+ return new Promise((resolve) => {
31047
+ const check = () => {
31048
+ var _a2;
31049
+ if (this.videoElement && ((_a2 = this.videoElement) == null ? void 0 : _a2.readyState) >= 3) return resolve();
31050
+ else requestAnimationFrame(check);
31051
+ };
31052
+ check();
31053
+ });
31054
+ }
31055
+ async attachAndWarmup(stream4) {
31056
+ this.videoElement = document.createElement("video");
31057
+ this.videoElement.srcObject = stream4;
31058
+ this.videoElement.muted = true;
31059
+ await this.videoElement.play().catch((e2) => {
31060
+ });
31061
+ console.log("cameraStream.getVideoTracks() length:", this.cameraStream.getVideoTracks().length);
31062
+ await new Promise((resolve) => {
31063
+ var _a2;
31064
+ if (this.videoElement && ((_a2 = this.videoElement) == null ? void 0 : _a2.readyState) >= 1) return resolve();
31065
+ if (this.videoElement)
31066
+ this.videoElement.onloadedmetadata = () => resolve();
31067
+ });
31068
+ console.log("metadata ok");
31069
+ await this.waitForVideoFlow();
31070
+ console.log("waitForVideoFlow ok");
31071
+ await new Promise((r2) => setTimeout(r2, 300));
31072
+ }
30988
31073
  async startRecording(options) {
30989
- var _a2, _b, _c2, _d, _e2, _f, _g, _h;
31074
+ var _a2, _b, _c2, _d, _e2, _f, _g;
31075
+ console.log("startRecording Camera Recorder");
31076
+ 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)) {
31077
+ console.log("startRecording Camera Recorder initializeDetectors");
31078
+ await this.initializeDetectors();
31079
+ }
31080
+ const { cameraId, microphoneId } = this.options;
31081
+ const constraints = {
31082
+ audio: { deviceId: microphoneId },
31083
+ video: {
31084
+ deviceId: cameraId,
31085
+ width: this.videoOptions.width,
31086
+ height: this.videoOptions.height,
31087
+ frameRate: 15
31088
+ }
31089
+ };
31090
+ try {
31091
+ this.hardwareStream = await navigator.mediaDevices.getUserMedia(
31092
+ constraints
31093
+ );
31094
+ this.cameraStream = this.hardwareStream;
31095
+ } catch (error) {
31096
+ console.log("startRecording Camera Recorder error", error);
31097
+ if (error.toString() == "NotReadableError: Could not start video source")
31098
+ throw "N\xE3o foi poss\xEDvel conectar a camera, ela pode estar sendo utilizada por outro programa";
31099
+ throw error;
31100
+ }
31101
+ await this.attachAndWarmup(this.cameraStream);
31102
+ const {
31103
+ startRecording,
31104
+ stopRecording,
31105
+ pauseRecording,
31106
+ resumeRecording,
31107
+ recorderOptions,
31108
+ getBufferSize
31109
+ } = recorder(
31110
+ this.cameraStream,
31111
+ // streamToRecord,
31112
+ this.blobs,
31113
+ this.videoOptions,
31114
+ this.options.onBufferSizeError,
31115
+ (e2) => this.bufferError(e2),
31116
+ false
31117
+ );
31118
+ this.recordingStart = startRecording;
31119
+ this.recordingStop = stopRecording;
31120
+ this.recordingPause = pauseRecording;
31121
+ this.recordingResume = resumeRecording;
31122
+ this.recorderOptions = recorderOptions;
31123
+ this.getBufferSize = getBufferSize;
31124
+ try {
31125
+ await new Promise((r2) => setTimeout(r2, 500));
31126
+ await this.recordingStart();
31127
+ } catch (error) {
31128
+ console.log("startRecording Camera Recorder error", error);
31129
+ throw error;
31130
+ }
31131
+ const track = this.cameraStream.getVideoTracks()[0];
31132
+ const settings = track.getSettings();
31133
+ let { width = 0, height = 0 } = settings;
31134
+ const isPortrait = (_d = screen.orientation) == null ? void 0 : _d.type.includes("portrait");
31135
+ if (isPortrait && isMobileDevice()) {
31136
+ if (this.videoOptions.width == height && this.videoOptions.height == width) {
31137
+ [width, height] = [height, width];
31138
+ }
31139
+ }
31140
+ if (this.videoOptions.minWidth > width || this.videoOptions.minHeight > height) {
31141
+ throw STREAM_UNDER_MINIMUM_PERMITTED;
31142
+ } else if (this.videoOptions.width !== width || this.videoOptions.height !== height) {
31143
+ trackers.registerAnotherStream(
31144
+ this.proctoringId,
31145
+ `Maybe have another stream active
31146
+ Video Options: ${JSON.stringify(
31147
+ this.videoOptions,
31148
+ null,
31149
+ 2
31150
+ )}
31151
+ Setting: ${JSON.stringify(settings, null, 2)}`
31152
+ );
31153
+ throw ANOTHER_STREAM_ACTIVE;
31154
+ }
31155
+ if ((_e2 = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _e2.detectFace) {
31156
+ await this.faceDetection.enableCam(this.cameraStream);
31157
+ }
31158
+ if (((_f = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _f.detectPerson) || ((_g = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _g.detectCellPhone)) {
31159
+ await this.objectDetection.enableCam(this.cameraStream);
31160
+ }
31161
+ this.filesToUpload = [];
31162
+ if (this.options.proctoringType == "REALTIME") {
31163
+ this.captureFrame();
31164
+ }
31165
+ this.packageCount = 0;
31166
+ console.log("startRecording Camera Recorder OK");
31167
+ }
31168
+ async startRecordingOld(options) {
31169
+ var _a2, _b, _c2, _d, _e2, _f, _g;
30990
31170
  console.log("startRecording Camera Recorder");
30991
31171
  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)) {
30992
31172
  console.log("startRecording Camera Recorder initializeDetectors");
@@ -31016,6 +31196,17 @@ Setting: ${JSON.stringify(settings, null, 2)}`
31016
31196
  const track = this.cameraStream.getVideoTracks()[0];
31017
31197
  const settings = track.getSettings();
31018
31198
  let { width = 0, height = 0 } = settings;
31199
+ console.log("cameraStream.getVideoTracks() length:", this.cameraStream.getVideoTracks().length);
31200
+ await new Promise((resolve) => {
31201
+ const interval = setInterval(() => {
31202
+ console.log("cameraStream.getVideoTracks()[0].readyState", this.cameraStream.getVideoTracks()[0].readyState);
31203
+ if (this.cameraStream.getVideoTracks()[0].readyState == "live") {
31204
+ clearInterval(interval);
31205
+ resolve();
31206
+ }
31207
+ }, 100);
31208
+ });
31209
+ await new Promise((r2) => setTimeout(r2, 300));
31019
31210
  const {
31020
31211
  startRecording,
31021
31212
  stopRecording,
@@ -31040,6 +31231,7 @@ Setting: ${JSON.stringify(settings, null, 2)}`
31040
31231
  this.getBufferSize = getBufferSize;
31041
31232
  console.log("startRecording Camera Recorder recordingStart");
31042
31233
  try {
31234
+ await new Promise((r2) => setTimeout(r2, 500));
31043
31235
  await this.recordingStart();
31044
31236
  } catch (error) {
31045
31237
  console.log("startRecording Camera Recorder error", error);
@@ -31066,11 +31258,10 @@ Setting: ${JSON.stringify(settings, null, 2)}`
31066
31258
  );
31067
31259
  throw ANOTHER_STREAM_ACTIVE;
31068
31260
  }
31069
- ((_e2 = this.paramsConfig.imageBehaviourParameters) == null ? void 0 : _e2.useUploadImage) && this.options.proctoringType == "IMAGE" && this.photoShotsCycle();
31070
- if ((_f = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _f.detectFace) {
31261
+ if ((_e2 = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _e2.detectFace) {
31071
31262
  await this.faceDetection.enableCam(this.cameraStream);
31072
31263
  }
31073
- if (((_g = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _g.detectPerson) || ((_h = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _h.detectCellPhone)) {
31264
+ if (((_f = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _f.detectPerson) || ((_g = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _g.detectCellPhone)) {
31074
31265
  await this.objectDetection.enableCam(this.cameraStream);
31075
31266
  }
31076
31267
  this.filesToUpload = [];
@@ -31081,6 +31272,7 @@ Setting: ${JSON.stringify(settings, null, 2)}`
31081
31272
  console.log("startRecording Camera Recorder finished");
31082
31273
  }
31083
31274
  async stopRecording() {
31275
+ var _a2, _b, _c2;
31084
31276
  console.log("Stopping Camera Recorder...");
31085
31277
  this.isCanvasLoopActive = false;
31086
31278
  this.recordingStop && await this.recordingStop();
@@ -31100,8 +31292,18 @@ Setting: ${JSON.stringify(settings, null, 2)}`
31100
31292
  this.hardwareStream.getTracks().forEach((track) => track.stop());
31101
31293
  this.hardwareStream = null;
31102
31294
  }
31103
- } catch {
31104
- console.error("Erro ao parar os streams de m\xEDdia.");
31295
+ if (this.videoElement) {
31296
+ (_a2 = this.videoElement) == null ? void 0 : _a2.remove();
31297
+ this.videoElement = null;
31298
+ }
31299
+ if (this.video) {
31300
+ (_b = this.video) == null ? void 0 : _b.remove();
31301
+ }
31302
+ if (this.canvas) {
31303
+ (_c2 = this.canvas) == null ? void 0 : _c2.remove();
31304
+ }
31305
+ } catch (error) {
31306
+ console.error("Erro ao parar os streams de m\xEDdia.", error);
31105
31307
  }
31106
31308
  this.faceDetection && this.faceDetection.detecting && this.faceDetection.stopDetection();
31107
31309
  this.objectDetection && this.objectDetection.detecting && this.objectDetection.stopDetection();
@@ -31120,35 +31322,6 @@ Setting: ${JSON.stringify(settings, null, 2)}`
31120
31322
  async resumeRecording() {
31121
31323
  await this.recordingResume();
31122
31324
  }
31123
- photoShotsCycle() {
31124
- let imageFile;
31125
- this.configImageCapture();
31126
- this.imageInterval = setInterval(async () => {
31127
- this.canvas.getContext("2d").drawImage(
31128
- this.video,
31129
- 0,
31130
- 0,
31131
- this.videoOptions.width,
31132
- this.videoOptions.height
31133
- );
31134
- const image_data_url = this.canvas.toDataURL("image/jpeg");
31135
- imageFile = await this.getFile(
31136
- image_data_url,
31137
- `${this.proctoringId}_${this.imageCount + 1}.jpg`,
31138
- "image/jpeg"
31139
- );
31140
- if (imageFile && this.upload && this.backendToken) {
31141
- this.upload.upload(
31142
- {
31143
- file: imageFile
31144
- },
31145
- this.backendToken,
31146
- true
31147
- );
31148
- this.imageCount++;
31149
- }
31150
- }, this.paramsConfig.imageBehaviourParameters.uploadInterval * 1e3);
31151
- }
31152
31325
  async getCurrentImageBase64() {
31153
31326
  if (!this.video || !this.canvas) {
31154
31327
  this.configImageCapture();
@@ -33854,7 +34027,6 @@ var _ExternalCameraChecker = class _ExternalCameraChecker {
33854
34027
  this.connection = null;
33855
34028
  this.context = context;
33856
34029
  this.onRealtimeAlertsCallback = onRealtimeAlertsCallback;
33857
- console.log("context -> ", context);
33858
34030
  this.backend = new BackendService({
33859
34031
  type: (context == null ? void 0 : context.type) || "prod",
33860
34032
  token: context.token
@@ -34908,6 +35080,7 @@ var Proctoring = class {
34908
35080
  try {
34909
35081
  console.log("start Proctoring recorder.startAll");
34910
35082
  await this.recorder.startAll();
35083
+ console.log("start Proctoring recorder.startAll ok");
34911
35084
  } catch (error) {
34912
35085
  console.log("start Proctoring error", error);
34913
35086
  alert(error);
@@ -36,6 +36,7 @@ export declare class CameraRecorder implements IRecorder {
36
36
  private isCanvasLoopActive;
37
37
  private hardwareStream;
38
38
  private internalClonedStream;
39
+ private videoElement;
39
40
  constructor(options: {
40
41
  cameraId?: string;
41
42
  microphoneId?: string;
@@ -46,7 +47,7 @@ export declare class CameraRecorder implements IRecorder {
46
47
  onRealtimeAlertsCallback?: (response: any) => void;
47
48
  }, videoOptions: ProctoringVideoOptions, paramsConfig?: IParamsConfig, backend?: BackendService, backendToken?: string);
48
49
  file?: File;
49
- recordingStart: () => any;
50
+ recordingStart: () => Promise<void>;
50
51
  recordingStop: () => any;
51
52
  recordingPause: () => any;
52
53
  recordingResume: () => any;
@@ -60,13 +61,17 @@ export declare class CameraRecorder implements IRecorder {
60
61
  retry?: boolean;
61
62
  }): Promise<void>;
62
63
  stopStream(): Promise<void>;
64
+ waitForVideoFlow(): Promise<void>;
65
+ attachAndWarmup(stream: MediaStream): Promise<void>;
63
66
  startRecording(options?: {
64
67
  retry?: boolean;
65
68
  }): Promise<void>;
69
+ startRecordingOld(options?: {
70
+ retry?: boolean;
71
+ }): Promise<void>;
66
72
  stopRecording(): Promise<void>;
67
73
  pauseRecording(): Promise<void>;
68
74
  resumeRecording(): Promise<void>;
69
- photoShotsCycle(): void;
70
75
  getCurrentImageBase64(): Promise<string>;
71
76
  packageCount: number;
72
77
  captureFrame(): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "easyproctor-hml",
3
- "version": "2.5.29",
3
+ "version": "2.5.30",
4
4
  "description": "Modulo web de gravação do EasyProctor",
5
5
  "main": "./index.js",
6
6
  "module": "./esm/index.js",
@@ -2,6 +2,7 @@ import { ProctoringVideoOptions } from "../proctoring/options/ProctoringVideoOpt
2
2
  export declare function setRecorderProctoringId(id: string): void;
3
3
  export default function recorder(stream: MediaStream, buffer: Blob[], videoOptions: ProctoringVideoOptions | null, onBufferSizeError?: boolean, onBufferSizeErrorCallback?: (e?: any) => void, audio?: boolean): {
4
4
  startRecording: () => Promise<void>;
5
+ startWithRetry: (recorder: MediaRecorder) => Promise<void>;
5
6
  stopRecording: () => Promise<void>;
6
7
  pauseRecording: () => Promise<void>;
7
8
  resumeRecording: () => Promise<void>;