easyproctor-hml 0.0.54 → 0.0.56

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.
@@ -10,6 +10,8 @@ export declare const PROCTORING_RUNNING = "proctoring_running";
10
10
  export declare const NO_VIDEOS_RECORDED = "no_videos_recorded";
11
11
  export declare const PERMISSIONS_NOT_GRANTED = "permissions_not_granted";
12
12
  export declare const ANOTHER_STREAM_ACTIVE = "another_stream_active";
13
+ export declare const STREAM_UNDER_MINIMUM_PERMITTED = "stream_under_minimum_permitted";
13
14
  export declare const BROWSER_NOT_SUPPORTED = "browser_not_supported";
14
15
  export declare const TOKEN_MISSING = "token_missing";
15
16
  export declare const CREDENTIALS_MISSING = "credentials_missing";
17
+ export declare const CAMERA_BLOCKED = "camera_blocked";
package/esm/index.js CHANGED
@@ -17376,6 +17376,7 @@ var MULTIPLE_MONITORS_DETECTED = "multiple_monitors_detected";
17376
17376
  var PROCTORING_ALREADY_STARTED = "proctoring_already_started";
17377
17377
  var PROCTORING_NOT_STARTED = "proctoring_not_started";
17378
17378
  var ANOTHER_STREAM_ACTIVE = "another_stream_active";
17379
+ var STREAM_UNDER_MINIMUM_PERMITTED = "stream_under_minimum_permitted";
17379
17380
  var BROWSER_NOT_SUPPORTED = "browser_not_supported";
17380
17381
  var TOKEN_MISSING = "token_missing";
17381
17382
  var CREDENTIALS_MISSING = "credentials_missing";
@@ -17396,11 +17397,15 @@ var CameraRecorder = class {
17396
17397
  onBufferSizeError: false,
17397
17398
  onBufferSizeErrorCallback: () => {
17398
17399
  },
17399
- proctoringType: "IMAGE"
17400
+ proctoringType: "IMAGE",
17401
+ onChangeDevicesCallback: (devices) => {
17402
+ }
17400
17403
  };
17401
17404
  this.videoOptions = {
17402
17405
  width: 640,
17403
- height: 480
17406
+ height: 480,
17407
+ minWidth: 0,
17408
+ minHeight: 0
17404
17409
  };
17405
17410
  this.blobsRTC = [];
17406
17411
  this.imageCount = 0;
@@ -17420,8 +17425,8 @@ var CameraRecorder = class {
17420
17425
  this.video.srcObject = this.cameraStream;
17421
17426
  this.video.play();
17422
17427
  this.video.muted = true;
17423
- this.canvas.width = 1280;
17424
- this.canvas.height = 720;
17428
+ this.canvas.width = this.videoOptions.width;
17429
+ this.canvas.height = this.videoOptions.height;
17425
17430
  }
17426
17431
  async startRecording() {
17427
17432
  const { cameraId, microphoneId, onBufferSizeErrorCallback } = this.options;
@@ -17447,8 +17452,13 @@ var CameraRecorder = class {
17447
17452
  this.recordingPause = pauseRecording;
17448
17453
  this.recordingResume = resumeRecording;
17449
17454
  this.recordingStart();
17450
- const settings = this.cameraStream.getVideoTracks()[0].getSettings();
17451
- if (this.videoOptions.width !== settings.width || this.videoOptions.height !== settings.height) {
17455
+ const tracks = this.cameraStream.getVideoTracks();
17456
+ const settings = tracks[0].getSettings();
17457
+ if (this.videoOptions.minWidth > settings.width || this.videoOptions.minHeight > settings.height) {
17458
+ throw STREAM_UNDER_MINIMUM_PERMITTED;
17459
+ } else if (this.videoOptions.width !== settings.width || this.videoOptions.height !== settings.height) {
17460
+ console.log("this.videoOptions: ", this.videoOptions);
17461
+ console.log("settings: ", settings);
17452
17462
  trackers.registerAnotherStream(this.proctoringId, `Maybe have another stream active
17453
17463
  Video Options: ${this.videoOptions}
17454
17464
  Setting: ${settings}`);
@@ -17470,7 +17480,7 @@ Setting: ${settings}`);
17470
17480
  let imageFile;
17471
17481
  this.configImageCapture();
17472
17482
  this.imageInterval = setInterval(async () => {
17473
- this.canvas.getContext("2d").drawImage(this.video, 0, 0, 1280, 720);
17483
+ this.canvas.getContext("2d").drawImage(this.video, 0, 0, this.videoOptions.width, this.videoOptions.height);
17474
17484
  const image_data_url = this.canvas.toDataURL("image/jpeg");
17475
17485
  imageFile = await this.getFile(image_data_url, `${this.proctoringId}_${this.imageCount + 1}.jpg`, "image/jpeg");
17476
17486
  if (imageFile && this.upload && this.backendToken) {
@@ -17485,6 +17495,16 @@ Setting: ${settings}`);
17485
17495
  }
17486
17496
  }, this.imageParams.uploadInterval * 1e3);
17487
17497
  }
17498
+ download(file) {
17499
+ const url = URL.createObjectURL(file);
17500
+ const a = document.createElement("a");
17501
+ document.body.appendChild(a);
17502
+ a.style.display = "none";
17503
+ a.href = url;
17504
+ a.download = file.name;
17505
+ a.click();
17506
+ window.URL.revokeObjectURL(url);
17507
+ }
17488
17508
  async saveOnSession(session) {
17489
17509
  const settings = this.cameraStream.getVideoTracks()[0].getSettings();
17490
17510
  const settingsAudio = this.cameraStream.getAudioTracks()[0].getSettings();
@@ -17862,7 +17882,9 @@ function validatePartialVideoOptions(options) {
17862
17882
  if (!!options.width && !!options.height) {
17863
17883
  return {
17864
17884
  width: options.width,
17865
- height: options.height
17885
+ height: options.height,
17886
+ minWidth: options.minWidth,
17887
+ minHeight: options.minHeight
17866
17888
  };
17867
17889
  } else {
17868
17890
  return { width: 640, height: 480 };
@@ -17872,30 +17894,48 @@ function validatePartialVideoOptions(options) {
17872
17894
  // src/proctoring/DeviceChecker.ts
17873
17895
  var DeviceChecker = class {
17874
17896
  constructor() {
17897
+ this.videoOptions = { width: 1080, height: 720, minWidth: 0, minHeight: 0 };
17875
17898
  this.volumeMedia = 0;
17876
17899
  this.volumeSum = 0;
17877
17900
  this.volumeCounter = 0;
17901
+ this.allowedResolution = true;
17878
17902
  }
17879
- async checkDevices(options = getDefaultProctoringOptions, _videoOptions = { width: 1080, height: 720 }) {
17880
- this.options = {
17881
- ...getDefaultProctoringOptions,
17882
- ...options,
17883
- captureScreen: false,
17884
- allowMultipleMonitors: true,
17885
- allowOnlyFirstMonitor: false
17886
- };
17887
- this.videoOptions = _videoOptions;
17888
- const { cameraId, microphoneId } = await this.checkDevicesInterface();
17889
- return new Promise((resolve) => {
17890
- resolve({
17891
- cameraId,
17892
- microphoneId,
17893
- volumeRange: this.volumeMedia
17903
+ async checkDevices(options = getDefaultProctoringOptions, _videoOptions) {
17904
+ try {
17905
+ this.options = {
17906
+ ...getDefaultProctoringOptions,
17907
+ ...options,
17908
+ captureScreen: false,
17909
+ allowMultipleMonitors: true,
17910
+ allowOnlyFirstMonitor: false
17911
+ };
17912
+ this.videoOptions = { ...this.videoOptions, ..._videoOptions };
17913
+ const { cameraId, microphoneId, result } = await this.checkDevicesInterface();
17914
+ return new Promise((resolve) => {
17915
+ resolve({
17916
+ result,
17917
+ cameraId,
17918
+ microphoneId,
17919
+ volumeRange: this.volumeMedia,
17920
+ allowedResolution: this.allowedResolution
17921
+ });
17894
17922
  });
17895
- });
17923
+ } catch (error) {
17924
+ this.closeCheckDevices();
17925
+ return Promise.reject(error);
17926
+ }
17927
+ }
17928
+ isUnderResolution() {
17929
+ const settings = this.cameraRecorder.cameraStream.getVideoTracks()[0].getSettings();
17930
+ const error = document.getElementById("cameraError");
17931
+ if (this.videoOptions.minWidth > settings.width || this.videoOptions.minHeight > settings.height) {
17932
+ this.allowedResolution = false;
17933
+ error.innerText = `A c\xE2mera n\xE3o satisfaz a resolu\xE7\xE3o m\xEDnima exigida (${this.videoOptions.minWidth}x${this.videoOptions.minHeight}).
17934
+ Para iniciar um exame utilize uma outra c\xE2mera.`;
17935
+ }
17896
17936
  }
17897
17937
  checkDevicesInterface() {
17898
- return new Promise((resolve) => {
17938
+ return new Promise((resolve, reject) => {
17899
17939
  const fullBg = document.createElement("div");
17900
17940
  fullBg.setAttribute("id", "checkDevices");
17901
17941
  fullBg.style.backgroundColor = "rgba(0,0,0,0.4)";
@@ -17944,8 +17984,18 @@ var DeviceChecker = class {
17944
17984
  divCameraHeader.appendChild(h3Camera);
17945
17985
  divCameraHeader.appendChild(selectCamera);
17946
17986
  modal.appendChild(divCameraHeader);
17987
+ const divCameraError = document.createElement("div");
17988
+ const error = document.createElement("error");
17989
+ error.setAttribute("id", "cameraError");
17990
+ divCameraError.style.width = "calc(100% - 40px)";
17991
+ divCameraError.style.marginBottom = "5px";
17992
+ error.style.color = "#FF0000";
17993
+ error.style.textAlign = "left";
17994
+ divCameraError.appendChild(error);
17995
+ modal.appendChild(divCameraError);
17947
17996
  const divCamera = document.createElement("div");
17948
17997
  const video = document.createElement("video");
17998
+ const center = document.createElement("div");
17949
17999
  video.setAttribute("id", "cameraStream");
17950
18000
  video.muted = true;
17951
18001
  divCamera.style.width = "calc(100% - 40px)";
@@ -17953,10 +18003,12 @@ var DeviceChecker = class {
17953
18003
  divCamera.style.justifyContent = "space-between";
17954
18004
  divCamera.style.borderBottom = "2px solid rgba(0, 0, 0, .1)";
17955
18005
  divCamera.style.paddingBottom = "15px";
18006
+ divCamera.style.transform = "rotateY(180deg)";
17956
18007
  video.style.width = "20rem";
17957
18008
  video.style.backgroundColor = "#000";
17958
18009
  video.style.borderRadius = "10px";
17959
18010
  video.style.marginBottom = "15px";
18011
+ divCamera.appendChild(center);
17960
18012
  divCamera.appendChild(video);
17961
18013
  modal.appendChild(divCamera);
17962
18014
  const divMicHeader = document.createElement("div");
@@ -18012,6 +18064,8 @@ var DeviceChecker = class {
18012
18064
  divMic.appendChild(divRange);
18013
18065
  modal.appendChild(divMic);
18014
18066
  const button = document.createElement("button");
18067
+ const divider = document.createElement("span");
18068
+ const buttonCancel = document.createElement("button");
18015
18069
  const divBtn = document.createElement("div");
18016
18070
  button.setAttribute("id", "confirmBtn");
18017
18071
  divBtn.style.width = "100%";
@@ -18019,6 +18073,20 @@ var DeviceChecker = class {
18019
18073
  divBtn.style.alignItems = "center";
18020
18074
  divBtn.style.justifyContent = "center";
18021
18075
  divBtn.style.borderTop = "2px solid rgba(0, 0, 0, .1)";
18076
+ buttonCancel.innerText = "Cancelar";
18077
+ buttonCancel.style.width = "100%";
18078
+ buttonCancel.style.height = "70px";
18079
+ buttonCancel.style.backgroundColor = "#FFF";
18080
+ buttonCancel.style.border = "none";
18081
+ buttonCancel.style.color = "rgba(0, 0, 0, .7)";
18082
+ buttonCancel.style.fontWeight = "bold";
18083
+ buttonCancel.style.borderRadius = "10px";
18084
+ buttonCancel.style.paddingTop = "5px";
18085
+ buttonCancel.style.paddingBottom = "5px";
18086
+ divider.style.width = "3px";
18087
+ divider.style.height = "70px";
18088
+ divider.style.margin = "0px 2px";
18089
+ divider.style.background = "rgba(0, 0, 0, .1)";
18022
18090
  button.innerText = "Continuar";
18023
18091
  button.style.width = "100%";
18024
18092
  button.style.height = "70px";
@@ -18034,14 +18102,25 @@ var DeviceChecker = class {
18034
18102
  this.closeCheckDevices();
18035
18103
  resolve({
18036
18104
  cameraId: selectCamera == null ? void 0 : selectCamera.value,
18037
- microphoneId: selectMic == null ? void 0 : selectMic.value
18105
+ microphoneId: selectMic == null ? void 0 : selectMic.value,
18106
+ result: true
18038
18107
  });
18039
18108
  });
18109
+ buttonCancel.addEventListener("click", () => {
18110
+ this.closeCheckDevices();
18111
+ resolve({
18112
+ cameraId: selectCamera == null ? void 0 : selectCamera.value,
18113
+ microphoneId: selectMic == null ? void 0 : selectMic.value,
18114
+ result: false
18115
+ });
18116
+ });
18117
+ divBtn.appendChild(buttonCancel);
18118
+ divBtn.appendChild(divider);
18040
18119
  divBtn.appendChild(button);
18041
18120
  modal.appendChild(divBtn);
18042
18121
  fullBg.appendChild(modal);
18043
18122
  document.body.appendChild(fullBg);
18044
- this.startCheckDevices(this.options, this.videoOptions);
18123
+ this.startCheckDevices(this.options, this.videoOptions).catch((e) => reject(e));
18045
18124
  });
18046
18125
  }
18047
18126
  videoDeviceInterface(stream) {
@@ -18049,6 +18128,7 @@ var DeviceChecker = class {
18049
18128
  if (cameraStream) {
18050
18129
  cameraStream.srcObject = stream;
18051
18130
  cameraStream.play();
18131
+ this.isUnderResolution();
18052
18132
  }
18053
18133
  }
18054
18134
  audioDeviceInterface(stream) {
@@ -18740,7 +18820,7 @@ var ScreenRecorder = class {
18740
18820
  const displayMediaStreamConstraints = {
18741
18821
  video: {
18742
18822
  cursor: "always",
18743
- width: 640,
18823
+ width: 854,
18744
18824
  height: 480,
18745
18825
  displaySurface: "monitor"
18746
18826
  },
@@ -19026,12 +19106,15 @@ var Proctoring = class {
19026
19106
  };
19027
19107
  this.onNoiseDetectedCallback = () => {
19028
19108
  };
19109
+ this.onChangeDevicesCallback = (devices) => {
19110
+ return;
19111
+ };
19029
19112
  this.onBufferSizeErrorCallback = () => {
19030
19113
  return;
19031
19114
  };
19032
19115
  var _a;
19033
19116
  this.backend = new BackendService({
19034
- type: context.type,
19117
+ type: context.type || "prod",
19035
19118
  token: context.token
19036
19119
  });
19037
19120
  this.repository = new IndexDbSessionRepository("EasyProctorDb", "exams2");
@@ -19056,23 +19139,28 @@ var Proctoring = class {
19056
19139
  async onChangeDevices(options = {}) {
19057
19140
  const onChange = new onChangeDevices(this.repositoryDevices, this.proctoringId);
19058
19141
  onChange.startRecording(options);
19142
+ this.onChangeDevicesCallback = (devices) => options.status && options.status(devices);
19059
19143
  }
19060
19144
  setOnBufferSizeErrorCallback(cb) {
19061
19145
  this.onBufferSizeErrorCallback = () => cb();
19062
19146
  }
19063
19147
  createRecorders(options = getDefaultProctoringOptions) {
19064
19148
  var _a, _b;
19149
+ this.onChangeDevices();
19065
19150
  const cameraRecorder = new CameraRecorder(
19066
19151
  {
19067
19152
  cameraId: this.sessionOptions.cameraId,
19068
19153
  microphoneId: this.sessionOptions.microphoneId,
19069
19154
  onBufferSizeError: this.sessionOptions.onBufferSizeError,
19070
19155
  onBufferSizeErrorCallback: () => this.onBufferSizeErrorCallback(),
19071
- proctoringType: this.sessionOptions.proctoringType
19156
+ proctoringType: this.sessionOptions.proctoringType,
19157
+ onChangeDevicesCallback: (devices) => this.onChangeDevicesCallback(devices)
19072
19158
  },
19073
19159
  {
19074
19160
  width: this.videoOptions.width,
19075
- height: this.videoOptions.height
19161
+ height: this.videoOptions.height,
19162
+ minWidth: this.videoOptions.minWidth,
19163
+ minHeight: this.videoOptions.minHeight
19076
19164
  },
19077
19165
  this.paramsConfig.imageParams,
19078
19166
  this.backend,
@@ -19095,7 +19183,6 @@ var Proctoring = class {
19095
19183
  options,
19096
19184
  cameraRecorder
19097
19185
  );
19098
- this.onChangeDevices();
19099
19186
  const recorders = [
19100
19187
  cameraRecorder,
19101
19188
  audioRecorder,
@@ -19136,8 +19223,6 @@ var Proctoring = class {
19136
19223
  this.proctoringSession = new ProctoringSession();
19137
19224
  this.allRecorders = this.createRecorders(this.sessionOptions);
19138
19225
  await this.recorder.startAll();
19139
- console.log("this.geolocation");
19140
- console.log(this.geolocation);
19141
19226
  const startResponse = await this.backend.confirmStart(
19142
19227
  {
19143
19228
  clientId: this.context.clientId,
package/index.js CHANGED
@@ -28924,6 +28924,7 @@ var MULTIPLE_MONITORS_DETECTED = "multiple_monitors_detected";
28924
28924
  var PROCTORING_ALREADY_STARTED = "proctoring_already_started";
28925
28925
  var PROCTORING_NOT_STARTED = "proctoring_not_started";
28926
28926
  var ANOTHER_STREAM_ACTIVE = "another_stream_active";
28927
+ var STREAM_UNDER_MINIMUM_PERMITTED = "stream_under_minimum_permitted";
28927
28928
  var BROWSER_NOT_SUPPORTED = "browser_not_supported";
28928
28929
  var TOKEN_MISSING = "token_missing";
28929
28930
  var CREDENTIALS_MISSING = "credentials_missing";
@@ -28944,11 +28945,15 @@ var CameraRecorder = class {
28944
28945
  onBufferSizeError: false,
28945
28946
  onBufferSizeErrorCallback: () => {
28946
28947
  },
28947
- proctoringType: "IMAGE"
28948
+ proctoringType: "IMAGE",
28949
+ onChangeDevicesCallback: (devices) => {
28950
+ }
28948
28951
  };
28949
28952
  this.videoOptions = {
28950
28953
  width: 640,
28951
- height: 480
28954
+ height: 480,
28955
+ minWidth: 0,
28956
+ minHeight: 0
28952
28957
  };
28953
28958
  this.blobsRTC = [];
28954
28959
  this.imageCount = 0;
@@ -28968,8 +28973,8 @@ var CameraRecorder = class {
28968
28973
  this.video.srcObject = this.cameraStream;
28969
28974
  this.video.play();
28970
28975
  this.video.muted = true;
28971
- this.canvas.width = 1280;
28972
- this.canvas.height = 720;
28976
+ this.canvas.width = this.videoOptions.width;
28977
+ this.canvas.height = this.videoOptions.height;
28973
28978
  }
28974
28979
  async startRecording() {
28975
28980
  const { cameraId, microphoneId, onBufferSizeErrorCallback } = this.options;
@@ -28995,8 +29000,13 @@ var CameraRecorder = class {
28995
29000
  this.recordingPause = pauseRecording;
28996
29001
  this.recordingResume = resumeRecording;
28997
29002
  this.recordingStart();
28998
- const settings = this.cameraStream.getVideoTracks()[0].getSettings();
28999
- if (this.videoOptions.width !== settings.width || this.videoOptions.height !== settings.height) {
29003
+ const tracks = this.cameraStream.getVideoTracks();
29004
+ const settings = tracks[0].getSettings();
29005
+ if (this.videoOptions.minWidth > settings.width || this.videoOptions.minHeight > settings.height) {
29006
+ throw STREAM_UNDER_MINIMUM_PERMITTED;
29007
+ } else if (this.videoOptions.width !== settings.width || this.videoOptions.height !== settings.height) {
29008
+ console.log("this.videoOptions: ", this.videoOptions);
29009
+ console.log("settings: ", settings);
29000
29010
  trackers.registerAnotherStream(this.proctoringId, `Maybe have another stream active
29001
29011
  Video Options: ${this.videoOptions}
29002
29012
  Setting: ${settings}`);
@@ -29018,7 +29028,7 @@ Setting: ${settings}`);
29018
29028
  let imageFile;
29019
29029
  this.configImageCapture();
29020
29030
  this.imageInterval = setInterval(async () => {
29021
- this.canvas.getContext("2d").drawImage(this.video, 0, 0, 1280, 720);
29031
+ this.canvas.getContext("2d").drawImage(this.video, 0, 0, this.videoOptions.width, this.videoOptions.height);
29022
29032
  const image_data_url = this.canvas.toDataURL("image/jpeg");
29023
29033
  imageFile = await this.getFile(image_data_url, `${this.proctoringId}_${this.imageCount + 1}.jpg`, "image/jpeg");
29024
29034
  if (imageFile && this.upload && this.backendToken) {
@@ -29033,6 +29043,16 @@ Setting: ${settings}`);
29033
29043
  }
29034
29044
  }, this.imageParams.uploadInterval * 1e3);
29035
29045
  }
29046
+ download(file) {
29047
+ const url2 = URL.createObjectURL(file);
29048
+ const a = document.createElement("a");
29049
+ document.body.appendChild(a);
29050
+ a.style.display = "none";
29051
+ a.href = url2;
29052
+ a.download = file.name;
29053
+ a.click();
29054
+ window.URL.revokeObjectURL(url2);
29055
+ }
29036
29056
  async saveOnSession(session) {
29037
29057
  const settings = this.cameraStream.getVideoTracks()[0].getSettings();
29038
29058
  const settingsAudio = this.cameraStream.getAudioTracks()[0].getSettings();
@@ -29410,7 +29430,9 @@ function validatePartialVideoOptions(options) {
29410
29430
  if (!!options.width && !!options.height) {
29411
29431
  return {
29412
29432
  width: options.width,
29413
- height: options.height
29433
+ height: options.height,
29434
+ minWidth: options.minWidth,
29435
+ minHeight: options.minHeight
29414
29436
  };
29415
29437
  } else {
29416
29438
  return { width: 640, height: 480 };
@@ -29420,30 +29442,48 @@ function validatePartialVideoOptions(options) {
29420
29442
  // src/proctoring/DeviceChecker.ts
29421
29443
  var DeviceChecker = class {
29422
29444
  constructor() {
29445
+ this.videoOptions = { width: 1080, height: 720, minWidth: 0, minHeight: 0 };
29423
29446
  this.volumeMedia = 0;
29424
29447
  this.volumeSum = 0;
29425
29448
  this.volumeCounter = 0;
29449
+ this.allowedResolution = true;
29426
29450
  }
29427
- async checkDevices(options = getDefaultProctoringOptions, _videoOptions = { width: 1080, height: 720 }) {
29428
- this.options = {
29429
- ...getDefaultProctoringOptions,
29430
- ...options,
29431
- captureScreen: false,
29432
- allowMultipleMonitors: true,
29433
- allowOnlyFirstMonitor: false
29434
- };
29435
- this.videoOptions = _videoOptions;
29436
- const { cameraId, microphoneId } = await this.checkDevicesInterface();
29437
- return new Promise((resolve) => {
29438
- resolve({
29439
- cameraId,
29440
- microphoneId,
29441
- volumeRange: this.volumeMedia
29451
+ async checkDevices(options = getDefaultProctoringOptions, _videoOptions) {
29452
+ try {
29453
+ this.options = {
29454
+ ...getDefaultProctoringOptions,
29455
+ ...options,
29456
+ captureScreen: false,
29457
+ allowMultipleMonitors: true,
29458
+ allowOnlyFirstMonitor: false
29459
+ };
29460
+ this.videoOptions = { ...this.videoOptions, ..._videoOptions };
29461
+ const { cameraId, microphoneId, result } = await this.checkDevicesInterface();
29462
+ return new Promise((resolve) => {
29463
+ resolve({
29464
+ result,
29465
+ cameraId,
29466
+ microphoneId,
29467
+ volumeRange: this.volumeMedia,
29468
+ allowedResolution: this.allowedResolution
29469
+ });
29442
29470
  });
29443
- });
29471
+ } catch (error) {
29472
+ this.closeCheckDevices();
29473
+ return Promise.reject(error);
29474
+ }
29475
+ }
29476
+ isUnderResolution() {
29477
+ const settings = this.cameraRecorder.cameraStream.getVideoTracks()[0].getSettings();
29478
+ const error = document.getElementById("cameraError");
29479
+ if (this.videoOptions.minWidth > settings.width || this.videoOptions.minHeight > settings.height) {
29480
+ this.allowedResolution = false;
29481
+ error.innerText = `A c\xE2mera n\xE3o satisfaz a resolu\xE7\xE3o m\xEDnima exigida (${this.videoOptions.minWidth}x${this.videoOptions.minHeight}).
29482
+ Para iniciar um exame utilize uma outra c\xE2mera.`;
29483
+ }
29444
29484
  }
29445
29485
  checkDevicesInterface() {
29446
- return new Promise((resolve) => {
29486
+ return new Promise((resolve, reject) => {
29447
29487
  const fullBg = document.createElement("div");
29448
29488
  fullBg.setAttribute("id", "checkDevices");
29449
29489
  fullBg.style.backgroundColor = "rgba(0,0,0,0.4)";
@@ -29492,8 +29532,18 @@ var DeviceChecker = class {
29492
29532
  divCameraHeader.appendChild(h3Camera);
29493
29533
  divCameraHeader.appendChild(selectCamera);
29494
29534
  modal.appendChild(divCameraHeader);
29535
+ const divCameraError = document.createElement("div");
29536
+ const error = document.createElement("error");
29537
+ error.setAttribute("id", "cameraError");
29538
+ divCameraError.style.width = "calc(100% - 40px)";
29539
+ divCameraError.style.marginBottom = "5px";
29540
+ error.style.color = "#FF0000";
29541
+ error.style.textAlign = "left";
29542
+ divCameraError.appendChild(error);
29543
+ modal.appendChild(divCameraError);
29495
29544
  const divCamera = document.createElement("div");
29496
29545
  const video = document.createElement("video");
29546
+ const center = document.createElement("div");
29497
29547
  video.setAttribute("id", "cameraStream");
29498
29548
  video.muted = true;
29499
29549
  divCamera.style.width = "calc(100% - 40px)";
@@ -29501,10 +29551,12 @@ var DeviceChecker = class {
29501
29551
  divCamera.style.justifyContent = "space-between";
29502
29552
  divCamera.style.borderBottom = "2px solid rgba(0, 0, 0, .1)";
29503
29553
  divCamera.style.paddingBottom = "15px";
29554
+ divCamera.style.transform = "rotateY(180deg)";
29504
29555
  video.style.width = "20rem";
29505
29556
  video.style.backgroundColor = "#000";
29506
29557
  video.style.borderRadius = "10px";
29507
29558
  video.style.marginBottom = "15px";
29559
+ divCamera.appendChild(center);
29508
29560
  divCamera.appendChild(video);
29509
29561
  modal.appendChild(divCamera);
29510
29562
  const divMicHeader = document.createElement("div");
@@ -29560,6 +29612,8 @@ var DeviceChecker = class {
29560
29612
  divMic.appendChild(divRange);
29561
29613
  modal.appendChild(divMic);
29562
29614
  const button = document.createElement("button");
29615
+ const divider = document.createElement("span");
29616
+ const buttonCancel = document.createElement("button");
29563
29617
  const divBtn = document.createElement("div");
29564
29618
  button.setAttribute("id", "confirmBtn");
29565
29619
  divBtn.style.width = "100%";
@@ -29567,6 +29621,20 @@ var DeviceChecker = class {
29567
29621
  divBtn.style.alignItems = "center";
29568
29622
  divBtn.style.justifyContent = "center";
29569
29623
  divBtn.style.borderTop = "2px solid rgba(0, 0, 0, .1)";
29624
+ buttonCancel.innerText = "Cancelar";
29625
+ buttonCancel.style.width = "100%";
29626
+ buttonCancel.style.height = "70px";
29627
+ buttonCancel.style.backgroundColor = "#FFF";
29628
+ buttonCancel.style.border = "none";
29629
+ buttonCancel.style.color = "rgba(0, 0, 0, .7)";
29630
+ buttonCancel.style.fontWeight = "bold";
29631
+ buttonCancel.style.borderRadius = "10px";
29632
+ buttonCancel.style.paddingTop = "5px";
29633
+ buttonCancel.style.paddingBottom = "5px";
29634
+ divider.style.width = "3px";
29635
+ divider.style.height = "70px";
29636
+ divider.style.margin = "0px 2px";
29637
+ divider.style.background = "rgba(0, 0, 0, .1)";
29570
29638
  button.innerText = "Continuar";
29571
29639
  button.style.width = "100%";
29572
29640
  button.style.height = "70px";
@@ -29582,14 +29650,25 @@ var DeviceChecker = class {
29582
29650
  this.closeCheckDevices();
29583
29651
  resolve({
29584
29652
  cameraId: selectCamera == null ? void 0 : selectCamera.value,
29585
- microphoneId: selectMic == null ? void 0 : selectMic.value
29653
+ microphoneId: selectMic == null ? void 0 : selectMic.value,
29654
+ result: true
29586
29655
  });
29587
29656
  });
29657
+ buttonCancel.addEventListener("click", () => {
29658
+ this.closeCheckDevices();
29659
+ resolve({
29660
+ cameraId: selectCamera == null ? void 0 : selectCamera.value,
29661
+ microphoneId: selectMic == null ? void 0 : selectMic.value,
29662
+ result: false
29663
+ });
29664
+ });
29665
+ divBtn.appendChild(buttonCancel);
29666
+ divBtn.appendChild(divider);
29588
29667
  divBtn.appendChild(button);
29589
29668
  modal.appendChild(divBtn);
29590
29669
  fullBg.appendChild(modal);
29591
29670
  document.body.appendChild(fullBg);
29592
- this.startCheckDevices(this.options, this.videoOptions);
29671
+ this.startCheckDevices(this.options, this.videoOptions).catch((e) => reject(e));
29593
29672
  });
29594
29673
  }
29595
29674
  videoDeviceInterface(stream4) {
@@ -29597,6 +29676,7 @@ var DeviceChecker = class {
29597
29676
  if (cameraStream) {
29598
29677
  cameraStream.srcObject = stream4;
29599
29678
  cameraStream.play();
29679
+ this.isUnderResolution();
29600
29680
  }
29601
29681
  }
29602
29682
  audioDeviceInterface(stream4) {
@@ -30288,7 +30368,7 @@ var ScreenRecorder = class {
30288
30368
  const displayMediaStreamConstraints = {
30289
30369
  video: {
30290
30370
  cursor: "always",
30291
- width: 640,
30371
+ width: 854,
30292
30372
  height: 480,
30293
30373
  displaySurface: "monitor"
30294
30374
  },
@@ -30574,12 +30654,15 @@ var Proctoring = class {
30574
30654
  };
30575
30655
  this.onNoiseDetectedCallback = () => {
30576
30656
  };
30657
+ this.onChangeDevicesCallback = (devices) => {
30658
+ return;
30659
+ };
30577
30660
  this.onBufferSizeErrorCallback = () => {
30578
30661
  return;
30579
30662
  };
30580
30663
  var _a;
30581
30664
  this.backend = new BackendService({
30582
- type: context.type,
30665
+ type: context.type || "prod",
30583
30666
  token: context.token
30584
30667
  });
30585
30668
  this.repository = new IndexDbSessionRepository("EasyProctorDb", "exams2");
@@ -30604,23 +30687,28 @@ var Proctoring = class {
30604
30687
  async onChangeDevices(options = {}) {
30605
30688
  const onChange = new onChangeDevices(this.repositoryDevices, this.proctoringId);
30606
30689
  onChange.startRecording(options);
30690
+ this.onChangeDevicesCallback = (devices) => options.status && options.status(devices);
30607
30691
  }
30608
30692
  setOnBufferSizeErrorCallback(cb) {
30609
30693
  this.onBufferSizeErrorCallback = () => cb();
30610
30694
  }
30611
30695
  createRecorders(options = getDefaultProctoringOptions) {
30612
30696
  var _a, _b;
30697
+ this.onChangeDevices();
30613
30698
  const cameraRecorder = new CameraRecorder(
30614
30699
  {
30615
30700
  cameraId: this.sessionOptions.cameraId,
30616
30701
  microphoneId: this.sessionOptions.microphoneId,
30617
30702
  onBufferSizeError: this.sessionOptions.onBufferSizeError,
30618
30703
  onBufferSizeErrorCallback: () => this.onBufferSizeErrorCallback(),
30619
- proctoringType: this.sessionOptions.proctoringType
30704
+ proctoringType: this.sessionOptions.proctoringType,
30705
+ onChangeDevicesCallback: (devices) => this.onChangeDevicesCallback(devices)
30620
30706
  },
30621
30707
  {
30622
30708
  width: this.videoOptions.width,
30623
- height: this.videoOptions.height
30709
+ height: this.videoOptions.height,
30710
+ minWidth: this.videoOptions.minWidth,
30711
+ minHeight: this.videoOptions.minHeight
30624
30712
  },
30625
30713
  this.paramsConfig.imageParams,
30626
30714
  this.backend,
@@ -30643,7 +30731,6 @@ var Proctoring = class {
30643
30731
  options,
30644
30732
  cameraRecorder
30645
30733
  );
30646
- this.onChangeDevices();
30647
30734
  const recorders = [
30648
30735
  cameraRecorder,
30649
30736
  audioRecorder,
@@ -30684,8 +30771,6 @@ var Proctoring = class {
30684
30771
  this.proctoringSession = new ProctoringSession();
30685
30772
  this.allRecorders = this.createRecorders(this.sessionOptions);
30686
30773
  await this.recorder.startAll();
30687
- console.log("this.geolocation");
30688
- console.log(this.geolocation);
30689
30774
  const startResponse = await this.backend.confirmStart(
30690
30775
  {
30691
30776
  clientId: this.context.clientId,