easyproctor-hml 0.0.17 → 0.0.19
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 +5 -2
- package/esm/index.js +193 -174
- package/extension/extension.d.ts +2 -2
- package/index.js +193 -174
- package/new-flow/backend/BackendService.d.ts +5 -0
- package/new-flow/recorders/AlertRecorder.d.ts +8 -1
- package/new-flow/recorders/VolumeMeter.d.ts +10 -0
- package/package.json +1 -1
- package/proctoring/DeviceChecker.d.ts +3 -1
- package/proctoring/options/ProctoringOptions.d.ts +2 -1
- package/proctoring/proctoring.d.ts +2 -0
- package/proctoring/useProctoring.d.ts +2 -1
- package/unpkg/easyproctor.min.js +19 -25
package/README.md
CHANGED
|
@@ -219,9 +219,12 @@ const {
|
|
|
219
219
|
});
|
|
220
220
|
```
|
|
221
221
|
|
|
222
|
-
## Release Note V 1.0.
|
|
222
|
+
## Release Note V 1.0.2
|
|
223
223
|
|
|
224
|
-
-
|
|
224
|
+
- Correção na função checkDevices
|
|
225
|
+
- Adicionado callback onNoiseDetected
|
|
226
|
+
- Correção de erro relacionado ao link do blob no download e na extensão
|
|
227
|
+
- Correção send percentage on finish with extension
|
|
225
228
|
|
|
226
229
|
|
|
227
230
|
## License
|
package/esm/index.js
CHANGED
|
@@ -14642,17 +14642,16 @@ var ScreenRecorder = class {
|
|
|
14642
14642
|
};
|
|
14643
14643
|
|
|
14644
14644
|
// src/proctoring/options/ProctoringOptions.ts
|
|
14645
|
-
|
|
14646
|
-
|
|
14647
|
-
|
|
14648
|
-
|
|
14649
|
-
|
|
14650
|
-
|
|
14651
|
-
|
|
14652
|
-
|
|
14653
|
-
|
|
14654
|
-
|
|
14655
|
-
}
|
|
14645
|
+
var getDefaultProctoringOptions = {
|
|
14646
|
+
cameraId: void 0,
|
|
14647
|
+
microphoneId: void 0,
|
|
14648
|
+
allowMultipleMonitors: false,
|
|
14649
|
+
allowOnlyFirstMonitor: true,
|
|
14650
|
+
captureScreen: true,
|
|
14651
|
+
noiseLimit: 40,
|
|
14652
|
+
proctoringType: "IMAGE",
|
|
14653
|
+
insights: ""
|
|
14654
|
+
};
|
|
14656
14655
|
|
|
14657
14656
|
// src/proctoring/options/ProctoringVideoOptions.ts
|
|
14658
14657
|
function validatePartialVideoOptions(options) {
|
|
@@ -14670,68 +14669,82 @@ function validatePartialVideoOptions(options) {
|
|
|
14670
14669
|
var DeviceChecker = class {
|
|
14671
14670
|
constructor() {
|
|
14672
14671
|
}
|
|
14673
|
-
async checkDevices(options = getDefaultProctoringOptions
|
|
14674
|
-
this.
|
|
14675
|
-
|
|
14676
|
-
|
|
14677
|
-
|
|
14672
|
+
async checkDevices(options = getDefaultProctoringOptions, _videoOptions = { width: 1080, height: 720 }) {
|
|
14673
|
+
this.options = {
|
|
14674
|
+
...getDefaultProctoringOptions,
|
|
14675
|
+
...options,
|
|
14676
|
+
captureScreen: false,
|
|
14677
|
+
allowMultipleMonitors: true,
|
|
14678
|
+
allowOnlyFirstMonitor: false
|
|
14679
|
+
};
|
|
14680
|
+
this.videoOptions = _videoOptions;
|
|
14681
|
+
return this.checkDevicesInterface();
|
|
14678
14682
|
}
|
|
14679
14683
|
checkDevicesInterface() {
|
|
14680
|
-
|
|
14681
|
-
|
|
14682
|
-
|
|
14683
|
-
|
|
14684
|
-
|
|
14685
|
-
|
|
14686
|
-
|
|
14687
|
-
|
|
14688
|
-
|
|
14689
|
-
|
|
14690
|
-
|
|
14691
|
-
|
|
14692
|
-
|
|
14693
|
-
|
|
14694
|
-
|
|
14695
|
-
|
|
14696
|
-
|
|
14697
|
-
|
|
14698
|
-
|
|
14699
|
-
|
|
14700
|
-
|
|
14701
|
-
|
|
14702
|
-
|
|
14703
|
-
|
|
14704
|
-
|
|
14705
|
-
|
|
14706
|
-
|
|
14707
|
-
|
|
14708
|
-
|
|
14709
|
-
|
|
14710
|
-
|
|
14711
|
-
|
|
14712
|
-
|
|
14713
|
-
|
|
14714
|
-
|
|
14715
|
-
|
|
14716
|
-
|
|
14717
|
-
|
|
14718
|
-
|
|
14719
|
-
|
|
14720
|
-
|
|
14721
|
-
|
|
14722
|
-
|
|
14723
|
-
|
|
14724
|
-
|
|
14725
|
-
|
|
14726
|
-
|
|
14727
|
-
|
|
14728
|
-
|
|
14729
|
-
|
|
14730
|
-
|
|
14731
|
-
|
|
14732
|
-
|
|
14733
|
-
|
|
14734
|
-
|
|
14684
|
+
return new Promise((resolve) => {
|
|
14685
|
+
const fullBg = document.createElement("div");
|
|
14686
|
+
fullBg.setAttribute("id", "checkDevices");
|
|
14687
|
+
fullBg.style.backgroundColor = "rgba(0,0,0,0.4)";
|
|
14688
|
+
fullBg.style.zIndex = "1000";
|
|
14689
|
+
fullBg.style.position = "absolute";
|
|
14690
|
+
fullBg.style.top = "0";
|
|
14691
|
+
fullBg.style.left = "0";
|
|
14692
|
+
fullBg.style.height = "100vh";
|
|
14693
|
+
fullBg.style.width = "100%";
|
|
14694
|
+
fullBg.style.display = "flex";
|
|
14695
|
+
fullBg.style.alignItems = "center";
|
|
14696
|
+
fullBg.style.justifyContent = "center";
|
|
14697
|
+
const modal = document.createElement("div");
|
|
14698
|
+
modal.style.backgroundColor = "#fff";
|
|
14699
|
+
modal.style.zIndex = "1001";
|
|
14700
|
+
modal.style.width = "400px";
|
|
14701
|
+
modal.style.borderRadius = "10px";
|
|
14702
|
+
modal.style.padding = "20px 10px";
|
|
14703
|
+
modal.style.display = "flex";
|
|
14704
|
+
modal.style.flexDirection = "column";
|
|
14705
|
+
modal.style.alignItems = "center";
|
|
14706
|
+
const h3 = document.createElement("h3");
|
|
14707
|
+
h3.innerText = "Verificar dispositivos";
|
|
14708
|
+
h3.style.color = "rgb(22, 163, 74)";
|
|
14709
|
+
h3.style.fontWeight = "bold";
|
|
14710
|
+
h3.style.fontSize = "26px";
|
|
14711
|
+
h3.style.marginBottom = "15px";
|
|
14712
|
+
modal.appendChild(h3);
|
|
14713
|
+
const video = document.createElement("video");
|
|
14714
|
+
video.setAttribute("id", "cameraStream");
|
|
14715
|
+
video.style.width = "20rem";
|
|
14716
|
+
video.style.backgroundColor = "#000";
|
|
14717
|
+
video.style.borderRadius = "10px";
|
|
14718
|
+
video.style.marginBottom = "15px";
|
|
14719
|
+
modal.appendChild(video);
|
|
14720
|
+
const meter = document.createElement("meter");
|
|
14721
|
+
meter.setAttribute("id", "audioStream");
|
|
14722
|
+
meter.setAttribute("high", "0.25");
|
|
14723
|
+
meter.setAttribute("max", "1");
|
|
14724
|
+
meter.style.width = "20rem";
|
|
14725
|
+
meter.style.borderRadius = "10px";
|
|
14726
|
+
meter.style.marginBottom = "15px";
|
|
14727
|
+
modal.appendChild(meter);
|
|
14728
|
+
const button = document.createElement("button");
|
|
14729
|
+
button.setAttribute("id", "confirmBtn");
|
|
14730
|
+
button.innerText = "Confirmar";
|
|
14731
|
+
button.style.width = "200px";
|
|
14732
|
+
button.style.height = "50px";
|
|
14733
|
+
button.style.backgroundColor = "rgb(22, 163, 74)";
|
|
14734
|
+
button.style.color = "#fff";
|
|
14735
|
+
button.style.borderRadius = "10px";
|
|
14736
|
+
button.addEventListener("click", () => {
|
|
14737
|
+
this.closeCheckDevices();
|
|
14738
|
+
resolve("Complete");
|
|
14739
|
+
});
|
|
14740
|
+
modal.appendChild(button);
|
|
14741
|
+
fullBg.appendChild(modal);
|
|
14742
|
+
document.body.appendChild(fullBg);
|
|
14743
|
+
this.startCheckDevices(this.options, this.videoOptions);
|
|
14744
|
+
});
|
|
14745
|
+
}
|
|
14746
|
+
async startDevice() {
|
|
14747
|
+
const { cameraStream, _screenStream } = await this.startCheckDevices(this.options, this.videoOptions);
|
|
14735
14748
|
}
|
|
14736
14749
|
videoDeviceInterface(stream) {
|
|
14737
14750
|
const cameraStream = document.querySelector("#cameraStream");
|
|
@@ -14758,7 +14771,7 @@ var DeviceChecker = class {
|
|
|
14758
14771
|
};
|
|
14759
14772
|
window.requestAnimationFrame(onFrame);
|
|
14760
14773
|
}
|
|
14761
|
-
async startCheckDevices(options = getDefaultProctoringOptions
|
|
14774
|
+
async startCheckDevices(options = getDefaultProctoringOptions, _videoOptions) {
|
|
14762
14775
|
var _a2;
|
|
14763
14776
|
this.videoOptions = validatePartialVideoOptions(_videoOptions);
|
|
14764
14777
|
await checkPermissions();
|
|
@@ -14780,6 +14793,8 @@ var DeviceChecker = class {
|
|
|
14780
14793
|
if (this.screenRecorder) {
|
|
14781
14794
|
await this.screenRecorder.startRecording();
|
|
14782
14795
|
}
|
|
14796
|
+
this.videoDeviceInterface(this.cameraRecorder.cameraStream);
|
|
14797
|
+
this.audioDeviceInterface(this.cameraRecorder.cameraStream);
|
|
14783
14798
|
return {
|
|
14784
14799
|
cameraStream: this.cameraRecorder.cameraStream,
|
|
14785
14800
|
_screenStream: (_a2 = this.screenRecorder) == null ? void 0 : _a2.screenStream
|
|
@@ -14825,7 +14840,7 @@ var Extension = class {
|
|
|
14825
14840
|
}
|
|
14826
14841
|
verify(event) {
|
|
14827
14842
|
if (event.source == window && event.data.sender && event.data.sender === "easyproctor-extension" && event.data.message_name && event.data.message_name === "progress") {
|
|
14828
|
-
this.onProgress(100);
|
|
14843
|
+
this.options.onProgress && this.options.onProgress(100);
|
|
14829
14844
|
}
|
|
14830
14845
|
if (event.source == window && event.data.sender && event.data.sender === "easyproctor-extension" && event.data.message_name && event.data.message_name === "start") {
|
|
14831
14846
|
this.responseStart = true;
|
|
@@ -24751,6 +24766,16 @@ var BackendService = class {
|
|
|
24751
24766
|
});
|
|
24752
24767
|
return insights2.data;
|
|
24753
24768
|
}
|
|
24769
|
+
async getAzureBlobUrl(proctoringOptions) {
|
|
24770
|
+
const blobUrl = await this.makeRequestAxios({
|
|
24771
|
+
path: `/AzureKey/get-blob-url`,
|
|
24772
|
+
method: "GET",
|
|
24773
|
+
jwt: proctoringOptions.token
|
|
24774
|
+
}).catch((error) => {
|
|
24775
|
+
throw "N\xE3o foi poss\xEDvel realizar a requisi\xE7\xE3o, tente novamente mais tarde";
|
|
24776
|
+
});
|
|
24777
|
+
return blobUrl.data;
|
|
24778
|
+
}
|
|
24754
24779
|
async getAzureSignedUrl(token, file) {
|
|
24755
24780
|
const urlAzure = await this.makeRequestAxios({
|
|
24756
24781
|
path: `/AzureKey/signed-url`,
|
|
@@ -24797,15 +24822,21 @@ var BackendService = class {
|
|
|
24797
24822
|
});
|
|
24798
24823
|
}
|
|
24799
24824
|
async finishAndSendUrls(proctoringOptions, proctoringSession) {
|
|
24800
|
-
var _a2, _b, _c;
|
|
24825
|
+
var _a2, _b, _c, _d, _e, _f;
|
|
24801
24826
|
const serverTime = new Date().toISOString();
|
|
24802
24827
|
const videoCameraUpload = (_a2 = proctoringSession.recordings.find((e) => e.origin === "Camera" /* Camera */)) == null ? void 0 : _a2.upload;
|
|
24803
24828
|
const audioCameraUpload = (_b = proctoringSession.recordings.find((e) => e.origin === "Mic" /* Mic */)) == null ? void 0 : _b.upload;
|
|
24804
24829
|
const videoScreenUpload = (_c = proctoringSession.recordings.find((e) => e.origin === "Screen" /* Screen */)) == null ? void 0 : _c.upload;
|
|
24805
24830
|
const clearUrl = (url) => url ? url.substring(0, url.indexOf("?")) : void 0;
|
|
24806
|
-
|
|
24807
|
-
|
|
24808
|
-
|
|
24831
|
+
let videoCameraUrl = clearUrl(videoCameraUpload == null ? void 0 : videoCameraUpload.azureUrl);
|
|
24832
|
+
let audioCameraUrl = clearUrl(audioCameraUpload == null ? void 0 : audioCameraUpload.azureUrl);
|
|
24833
|
+
let videoScreenUrl = clearUrl(videoScreenUpload == null ? void 0 : videoScreenUpload.azureUrl);
|
|
24834
|
+
if (!videoCameraUrl || !audioCameraUrl || !videoScreenUrl) {
|
|
24835
|
+
const blobUrl = await this.getAzureBlobUrl(proctoringOptions);
|
|
24836
|
+
!videoCameraUrl && (videoCameraUrl = `${blobUrl}/${(_d = proctoringSession.recordings.find((e) => e.origin === "Camera" /* Camera */)) == null ? void 0 : _d.file.name}`);
|
|
24837
|
+
!audioCameraUrl && (audioCameraUrl = `${blobUrl}/${(_e = proctoringSession.recordings.find((e) => e.origin === "Mic" /* Mic */)) == null ? void 0 : _e.file.name}`);
|
|
24838
|
+
!videoScreenUrl && proctoringSession.recordings.find((e) => e.origin === "Screen" /* Screen */) && (videoScreenUrl = `${blobUrl}/${(_f = proctoringSession.recordings.find((e) => e.origin === "Screen" /* Screen */)) == null ? void 0 : _f.file.name}`);
|
|
24839
|
+
}
|
|
24809
24840
|
await this.makeRequest({
|
|
24810
24841
|
path: `/proctoring/finish/${proctoringOptions.examId}`,
|
|
24811
24842
|
method: "POST",
|
|
@@ -25025,16 +25056,62 @@ var ProctoringUploader = class {
|
|
|
25025
25056
|
}
|
|
25026
25057
|
};
|
|
25027
25058
|
|
|
25059
|
+
// src/new-flow/recorders/VolumeMeter.ts
|
|
25060
|
+
var VolumeMeter = class {
|
|
25061
|
+
constructor(stream) {
|
|
25062
|
+
this.stream = stream;
|
|
25063
|
+
}
|
|
25064
|
+
start() {
|
|
25065
|
+
return new Promise((resolve, reject) => {
|
|
25066
|
+
try {
|
|
25067
|
+
const audioContext = new AudioContext();
|
|
25068
|
+
const analyser = audioContext.createAnalyser();
|
|
25069
|
+
const microphone = audioContext.createMediaStreamSource(this.stream);
|
|
25070
|
+
this.scriptProcessor = audioContext.createScriptProcessor(2048, 1, 1);
|
|
25071
|
+
analyser.smoothingTimeConstant = 0.8;
|
|
25072
|
+
analyser.fftSize = 1024;
|
|
25073
|
+
microphone.connect(analyser);
|
|
25074
|
+
analyser.connect(this.scriptProcessor);
|
|
25075
|
+
this.scriptProcessor.connect(audioContext.destination);
|
|
25076
|
+
const that = this;
|
|
25077
|
+
this.scriptProcessor.onaudioprocess = function() {
|
|
25078
|
+
const array = new Uint8Array(analyser.frequencyBinCount);
|
|
25079
|
+
analyser.getByteFrequencyData(array);
|
|
25080
|
+
const arraySum = array.reduce((a, value) => a + value, 0);
|
|
25081
|
+
const average = arraySum / array.length;
|
|
25082
|
+
that.setVolume(average);
|
|
25083
|
+
};
|
|
25084
|
+
resolve(true);
|
|
25085
|
+
} catch (error) {
|
|
25086
|
+
this.stop();
|
|
25087
|
+
reject(`Error: ${error}`);
|
|
25088
|
+
}
|
|
25089
|
+
});
|
|
25090
|
+
}
|
|
25091
|
+
stop() {
|
|
25092
|
+
this.scriptProcessor && this.scriptProcessor.disconnect();
|
|
25093
|
+
}
|
|
25094
|
+
getVolume() {
|
|
25095
|
+
return this.volume;
|
|
25096
|
+
}
|
|
25097
|
+
setVolume(value) {
|
|
25098
|
+
this.volume = value;
|
|
25099
|
+
}
|
|
25100
|
+
};
|
|
25101
|
+
|
|
25028
25102
|
// src/new-flow/recorders/AlertRecorder.ts
|
|
25029
25103
|
var AlertRecorder = class {
|
|
25030
|
-
constructor(options, optionsProctoring) {
|
|
25104
|
+
constructor(options, optionsProctoring, cameraRecorder) {
|
|
25031
25105
|
this.alerts = [];
|
|
25032
25106
|
this.onLostFocusCallback = options.onLostFocusCallback;
|
|
25033
25107
|
this.onFocusCallback = options.onFocusCallback;
|
|
25108
|
+
this.onNoiseDetectedCallback = options.onNoiseDetectedCallback;
|
|
25034
25109
|
this.optionsProctoring = optionsProctoring;
|
|
25110
|
+
this.cameraRecorder = cameraRecorder;
|
|
25035
25111
|
}
|
|
25036
25112
|
async startRecording() {
|
|
25037
25113
|
this.startTime = new Date(Date.now());
|
|
25114
|
+
this.intervalNoiseDetection = setInterval(() => this.onNoiseDetected(), 500);
|
|
25038
25115
|
if (this.optionsProctoring.captureScreen) {
|
|
25039
25116
|
window.addEventListener("blur", () => this.onLostFocus());
|
|
25040
25117
|
window.addEventListener("focus", () => this.onReturnFocus());
|
|
@@ -25043,16 +25120,25 @@ var AlertRecorder = class {
|
|
|
25043
25120
|
async pauseRecording() {
|
|
25044
25121
|
window.removeEventListener("blur", () => this.onLostFocus());
|
|
25045
25122
|
window.removeEventListener("focus", () => this.onReturnFocus());
|
|
25123
|
+
window.removeEventListener("focus", () => this.onNoiseDetected());
|
|
25124
|
+
this.volumeMeter.stop();
|
|
25125
|
+
clearInterval(this.intervalNoiseDetection);
|
|
25046
25126
|
}
|
|
25047
25127
|
async resumeRecording() {
|
|
25128
|
+
this.volumeMeter = void 0;
|
|
25129
|
+
this.intervalNoiseDetection = setInterval(() => this.onNoiseDetected(), 500);
|
|
25048
25130
|
if (this.optionsProctoring.captureScreen) {
|
|
25049
25131
|
window.addEventListener("blur", () => this.onLostFocus());
|
|
25050
25132
|
window.addEventListener("focus", () => this.onReturnFocus());
|
|
25133
|
+
window.addEventListener("focus", () => this.onNoiseDetected());
|
|
25051
25134
|
}
|
|
25052
25135
|
}
|
|
25053
25136
|
async stopRecording() {
|
|
25054
25137
|
window.removeEventListener("blur", () => this.onLostFocus());
|
|
25055
25138
|
window.removeEventListener("focus", () => this.onReturnFocus());
|
|
25139
|
+
window.removeEventListener("focus", () => this.onNoiseDetected());
|
|
25140
|
+
this.volumeMeter.stop();
|
|
25141
|
+
clearInterval(this.intervalNoiseDetection);
|
|
25056
25142
|
}
|
|
25057
25143
|
async saveOnSession(session) {
|
|
25058
25144
|
this.alerts.forEach((alert2) => {
|
|
@@ -25077,6 +25163,19 @@ var AlertRecorder = class {
|
|
|
25077
25163
|
lastAlert.end = Date.now() - this.startTime.getTime();
|
|
25078
25164
|
}
|
|
25079
25165
|
}
|
|
25166
|
+
onNoiseDetected() {
|
|
25167
|
+
var _a2;
|
|
25168
|
+
if (!this.volumeMeter && this.cameraRecorder.cameraStream) {
|
|
25169
|
+
this.volumeMeter = new VolumeMeter(this.cameraRecorder.cameraStream);
|
|
25170
|
+
this.volumeMeter.start().catch((e) => {
|
|
25171
|
+
console.log(e);
|
|
25172
|
+
this.volumeMeter = void 0;
|
|
25173
|
+
});
|
|
25174
|
+
}
|
|
25175
|
+
if (((_a2 = this.volumeMeter) == null ? void 0 : _a2.getVolume()) >= (this.optionsProctoring.noiseLimit || 40)) {
|
|
25176
|
+
this.onNoiseDetectedCallback();
|
|
25177
|
+
}
|
|
25178
|
+
}
|
|
25080
25179
|
};
|
|
25081
25180
|
|
|
25082
25181
|
// src/new-flow/repository/IndexDbSessionRepository.ts
|
|
@@ -25158,87 +25257,6 @@ var IndexDbSessionRepository = class {
|
|
|
25158
25257
|
}
|
|
25159
25258
|
};
|
|
25160
25259
|
|
|
25161
|
-
// src/new-flow/upload/AwsUploadService.ts
|
|
25162
|
-
var AwsUploadService = class {
|
|
25163
|
-
constructor(proctoringId, backend) {
|
|
25164
|
-
this.backend = backend;
|
|
25165
|
-
this.proctoringId = proctoringId;
|
|
25166
|
-
}
|
|
25167
|
-
async upload(data, token) {
|
|
25168
|
-
const { file, onProgress } = data;
|
|
25169
|
-
try {
|
|
25170
|
-
const progressCallback = (e) => {
|
|
25171
|
-
const progress = e.loadedBytes / file.size * 100;
|
|
25172
|
-
onProgress && onProgress(Math.round(progress));
|
|
25173
|
-
};
|
|
25174
|
-
const uploadUrl = await this.backend.getAwsSignedUrl(token, file);
|
|
25175
|
-
const uploaded = await axios_default2.request({
|
|
25176
|
-
url: uploadUrl,
|
|
25177
|
-
method: "PUT",
|
|
25178
|
-
headers: {
|
|
25179
|
-
"Content-Type": file.type
|
|
25180
|
-
},
|
|
25181
|
-
data: file,
|
|
25182
|
-
onUploadProgress: (p) => {
|
|
25183
|
-
progressCallback({ loadedBytes: p.loaded });
|
|
25184
|
-
}
|
|
25185
|
-
}).then(() => true).catch(() => false);
|
|
25186
|
-
await this.backend.sendAwsToAzure(token, file);
|
|
25187
|
-
return {
|
|
25188
|
-
storage: "AwsS3" /* AwsS3 */,
|
|
25189
|
-
url: uploadUrl,
|
|
25190
|
-
uploaded
|
|
25191
|
-
};
|
|
25192
|
-
} catch (err) {
|
|
25193
|
-
trackers.registerError(this.proctoringId, `Failed to upload to AWS
|
|
25194
|
-
File name: ${file.name}
|
|
25195
|
-
File type: ${file.type}
|
|
25196
|
-
File size: ${file.size}`);
|
|
25197
|
-
throw new Error("Failed to upload to AWS");
|
|
25198
|
-
}
|
|
25199
|
-
}
|
|
25200
|
-
};
|
|
25201
|
-
|
|
25202
|
-
// src/new-flow/upload/AzureUploadService.ts
|
|
25203
|
-
var AzureUploadService = class {
|
|
25204
|
-
constructor(proctoringId, backend) {
|
|
25205
|
-
this.backend = backend;
|
|
25206
|
-
this.proctoringId = proctoringId;
|
|
25207
|
-
}
|
|
25208
|
-
async upload(data, token) {
|
|
25209
|
-
const { file, onProgress } = data;
|
|
25210
|
-
try {
|
|
25211
|
-
const progressCallback = (e) => {
|
|
25212
|
-
const progress = e.loadedBytes / file.size * 100;
|
|
25213
|
-
onProgress && onProgress(Math.round(progress));
|
|
25214
|
-
};
|
|
25215
|
-
const uploadUrl = await this.backend.getAzureSignedUrl(token, file);
|
|
25216
|
-
const uploaded = await axios_default2.request({
|
|
25217
|
-
url: uploadUrl,
|
|
25218
|
-
method: "PUT",
|
|
25219
|
-
headers: {
|
|
25220
|
-
"x-ms-blob-type": "BlockBlob"
|
|
25221
|
-
},
|
|
25222
|
-
data: file,
|
|
25223
|
-
onUploadProgress: (p) => {
|
|
25224
|
-
progressCallback({ loadedBytes: p.loaded });
|
|
25225
|
-
}
|
|
25226
|
-
}).then(() => true).catch(() => false);
|
|
25227
|
-
return {
|
|
25228
|
-
storage: "AzureBlob" /* AzureBlob */,
|
|
25229
|
-
url: uploadUrl,
|
|
25230
|
-
uploaded
|
|
25231
|
-
};
|
|
25232
|
-
} catch (err) {
|
|
25233
|
-
trackers.registerError(this.proctoringId, `Failed to upload to Azure
|
|
25234
|
-
File name: ${file.name}
|
|
25235
|
-
File type: ${file.type}
|
|
25236
|
-
File size: ${file.size}`);
|
|
25237
|
-
throw new Error("Failed to upload to azure");
|
|
25238
|
-
}
|
|
25239
|
-
}
|
|
25240
|
-
};
|
|
25241
|
-
|
|
25242
25260
|
// src/utils/verifyVersion.ts
|
|
25243
25261
|
function versionVerify() {
|
|
25244
25262
|
const agentStr = window.navigator.userAgent.split("SEB/");
|
|
@@ -25264,6 +25282,8 @@ var Proctoring = class {
|
|
|
25264
25282
|
};
|
|
25265
25283
|
this.onFocusCallback = () => {
|
|
25266
25284
|
};
|
|
25285
|
+
this.onNoiseDetectedCallback = () => {
|
|
25286
|
+
};
|
|
25267
25287
|
this.backend = new BackendService({
|
|
25268
25288
|
type: context.type
|
|
25269
25289
|
});
|
|
@@ -25279,11 +25299,14 @@ var Proctoring = class {
|
|
|
25279
25299
|
setOnFocusCallback(cb) {
|
|
25280
25300
|
this.onFocusCallback = () => cb();
|
|
25281
25301
|
}
|
|
25302
|
+
setOnNoiseDetectedCallback(cb) {
|
|
25303
|
+
this.onNoiseDetectedCallback = () => cb();
|
|
25304
|
+
}
|
|
25282
25305
|
async onChangeDevices(options = {}) {
|
|
25283
25306
|
const onChange = new onChangeDevices(this.repositoryDevices, this.proctoringId);
|
|
25284
25307
|
onChange.startRecording(options);
|
|
25285
25308
|
}
|
|
25286
|
-
createRecorders(options = getDefaultProctoringOptions
|
|
25309
|
+
createRecorders(options = getDefaultProctoringOptions) {
|
|
25287
25310
|
var _a2;
|
|
25288
25311
|
const cameraRecorder = new CameraRecorder({
|
|
25289
25312
|
cameraId: this.sessionOptions.cameraId,
|
|
@@ -25299,8 +25322,9 @@ var Proctoring = class {
|
|
|
25299
25322
|
}) : void 0;
|
|
25300
25323
|
const alertRecorder = new AlertRecorder({
|
|
25301
25324
|
onFocusCallback: () => this.onFocusCallback(),
|
|
25302
|
-
onLostFocusCallback: () => this.onLostFocusCallback()
|
|
25303
|
-
|
|
25325
|
+
onLostFocusCallback: () => this.onLostFocusCallback(),
|
|
25326
|
+
onNoiseDetectedCallback: () => this.onNoiseDetectedCallback()
|
|
25327
|
+
}, options, cameraRecorder);
|
|
25304
25328
|
this.onChangeDevices();
|
|
25305
25329
|
const recorders = [
|
|
25306
25330
|
cameraRecorder,
|
|
@@ -25311,14 +25335,14 @@ var Proctoring = class {
|
|
|
25311
25335
|
this.recorder = new ProctoringRecorder(this.proctoringSession, recorders);
|
|
25312
25336
|
return { cameraRecorder, audioRecorder, screenRecorder, alertRecorder };
|
|
25313
25337
|
}
|
|
25314
|
-
async start(options = getDefaultProctoringOptions
|
|
25338
|
+
async start(options = getDefaultProctoringOptions, _videoOptions = {}) {
|
|
25315
25339
|
this.extension = new Extension();
|
|
25316
25340
|
this.extension.addEventListener();
|
|
25317
25341
|
const baseURL = this.backend.selectBaseUrl(this.context.type);
|
|
25318
25342
|
setTimeout(() => this.extension.sendVerifyMsg(baseURL, this.context.token), 5e3);
|
|
25319
25343
|
const devices = await enumarateDevices();
|
|
25320
25344
|
await this.repositoryDevices.save({ ...devices, id: "devices" });
|
|
25321
|
-
this.sessionOptions = options;
|
|
25345
|
+
this.sessionOptions = { ...getDefaultProctoringOptions, ...options };
|
|
25322
25346
|
this.videoOptions = validatePartialVideoOptions(_videoOptions);
|
|
25323
25347
|
if (this.state != "Stop" /* Stop */) {
|
|
25324
25348
|
throw PROCTORING_ALREADY_STARTED;
|
|
@@ -25337,7 +25361,7 @@ var Proctoring = class {
|
|
|
25337
25361
|
}, this.sessionOptions.proctoringType);
|
|
25338
25362
|
this.proctoringId = startResponse.id;
|
|
25339
25363
|
this.proctoringSession = new ProctoringSession(this.proctoringId);
|
|
25340
|
-
this.allRecorders = this.createRecorders(
|
|
25364
|
+
this.allRecorders = this.createRecorders(this.sessionOptions);
|
|
25341
25365
|
await this.recorder.startAll();
|
|
25342
25366
|
await this.repository.save(this.proctoringSession);
|
|
25343
25367
|
trackers.registerStart(this.proctoringId, true, "");
|
|
@@ -25362,7 +25386,7 @@ Error: ` + error);
|
|
|
25362
25386
|
this.state = "Stop" /* Stop */;
|
|
25363
25387
|
}
|
|
25364
25388
|
async finish(options = {}) {
|
|
25365
|
-
this.extension.
|
|
25389
|
+
this.extension.options = options;
|
|
25366
25390
|
if (this.state !== "Recording" /* Recording */) {
|
|
25367
25391
|
throw PROCTORING_NOT_STARTED;
|
|
25368
25392
|
}
|
|
@@ -25379,8 +25403,6 @@ Error: ` + error);
|
|
|
25379
25403
|
this.serviceType = "Download" /* Download */;
|
|
25380
25404
|
} else {
|
|
25381
25405
|
uploader = new ProctoringUploader(this.proctoringSession, this.proctoringId, [
|
|
25382
|
-
new AzureUploadService(this.proctoringId, this.backend),
|
|
25383
|
-
new AwsUploadService(this.proctoringId, this.backend),
|
|
25384
25406
|
new DownloadService(this.proctoringId)
|
|
25385
25407
|
]);
|
|
25386
25408
|
uploaderServices = "Azure, AWS, Download";
|
|
@@ -25390,9 +25412,6 @@ Error: ` + error);
|
|
|
25390
25412
|
if (this.extension.hasExtension) {
|
|
25391
25413
|
await this.extension.start().then((response) => {
|
|
25392
25414
|
extensionSuccess = response;
|
|
25393
|
-
if (!this.proctoringSession.hasSomethingToUpload) {
|
|
25394
|
-
this.proctoringSession.setUploaded();
|
|
25395
|
-
}
|
|
25396
25415
|
}).catch((error) => {
|
|
25397
25416
|
extensionSuccess = false;
|
|
25398
25417
|
});
|
|
@@ -25404,8 +25423,6 @@ Error: ` + error);
|
|
|
25404
25423
|
Upload Services: ${uploaderServices}`, this.serviceType);
|
|
25405
25424
|
if (versionVerify() !== "1.0.0.0") {
|
|
25406
25425
|
uploader = new ProctoringUploader(this.proctoringSession, this.proctoringId, [
|
|
25407
|
-
new AzureUploadService(this.proctoringId, this.backend),
|
|
25408
|
-
new AwsUploadService(this.proctoringId, this.backend),
|
|
25409
25426
|
new DownloadService(this.proctoringId)
|
|
25410
25427
|
]);
|
|
25411
25428
|
uploaderServices = "Azure, AWS, Download";
|
|
@@ -25477,7 +25494,7 @@ Upload Services: ${uploaderServices}`, this.serviceType);
|
|
|
25477
25494
|
throw PROCTORING_NOT_STARTED;
|
|
25478
25495
|
}
|
|
25479
25496
|
await this.verifyMultipleMonitors(this.sessionOptions);
|
|
25480
|
-
|
|
25497
|
+
this.allRecorders = this.createRecorders(this.sessionOptions);
|
|
25481
25498
|
await this.recorder.startAll();
|
|
25482
25499
|
this.proctoringSession.recordings = [];
|
|
25483
25500
|
await this.repository.save(this.proctoringSession);
|
|
@@ -25504,6 +25521,7 @@ function useProctoring(proctoringOptions, enviromentConfig = "prod") {
|
|
|
25504
25521
|
const resume = proctoring.resume.bind(proctoring);
|
|
25505
25522
|
const onFocus = proctoring.setOnFocusCallback.bind(proctoring);
|
|
25506
25523
|
const onLostFocus = proctoring.setOnLostFocusCallback.bind(proctoring);
|
|
25524
|
+
const onNoiseDetected = proctoring.setOnNoiseDetectedCallback.bind(proctoring);
|
|
25507
25525
|
const onChangeDevices2 = proctoring.onChangeDevices.bind(proctoring);
|
|
25508
25526
|
const onStopSharingScreen = proctoring.setOnStopSharingScreenCallback.bind(proctoring);
|
|
25509
25527
|
const checkDevices = checker.checkDevices.bind(checker);
|
|
@@ -25512,6 +25530,7 @@ function useProctoring(proctoringOptions, enviromentConfig = "prod") {
|
|
|
25512
25530
|
finish,
|
|
25513
25531
|
onFocus,
|
|
25514
25532
|
onLostFocus,
|
|
25533
|
+
onNoiseDetected,
|
|
25515
25534
|
onChangeDevices: onChangeDevices2,
|
|
25516
25535
|
checkDevices,
|
|
25517
25536
|
pause,
|
package/extension/extension.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ProctoringFinisherOptions } from "../proctoring/proctoring";
|
|
2
2
|
export declare class Extension {
|
|
3
3
|
hasExtension: boolean;
|
|
4
4
|
tryes: number;
|
|
5
5
|
responseStart: boolean;
|
|
6
|
-
|
|
6
|
+
options: ProctoringFinisherOptions;
|
|
7
7
|
start(): Promise<boolean>;
|
|
8
8
|
sendVerifyMsg(link: string, token: string): void;
|
|
9
9
|
private verify;
|