O componente web EasyProctor permite que qualquer plataforma de execução de exames registre sessões de proctoring.
Via NPM:
npm install --save easyproctor
Via CDN
<script src="https://cdn.jsdelivr.net/npm/easyproctor/unpkg/easyproctor.min.js"></script>
Para utilizar o componente será necessário utilizar os seguintes parâmetros:
- examId: identificador do exame
- clientId: identificador do parceiro
- token: token de autenticação biométrica (utilizar SDK biométrico do EasyProctor)
Ao inicializar a sessão de proctoring através do método start do componente você receberá o objeto do tipo StartProctoringDTO que possui o identificador da sessão.
Após finalizar a sessão de proctoring através do método finish você poderá consultar os dados de proctoring através da nossa API.
https://proctoring-api.easyproctor.tech/index.html
Em um bundler
import { useProctoring } from "easyproctor";
const {
login,
start,
finish,
checkDevices,
capturePhoto,
checkPermissions,
enumarateDevices,
checkIfhasMultipleMonitors,
onFocus,
onLostFocus,
onChangeDevices,
onRealtimeAlerts,
onBufferSizeError,
onStopSharingScreen,
} = useProctoring({
examId: "00001",
clientId: "000001",
token: "...",
});
Via CDN: A função "useProctoring" é injetada para ser utilizada globalmente
<script src="https://cdn.jsdelivr.net/npm/easyproctor/unpkg/easyproctor.min.js"></script>
<script>
const {
login,
start,
finish,
checkDevices,
capturePhoto,
checkPermissions,
enumarateDevices,
checkIfhasMultipleMonitors,
onFocus,
onLostFocus,
onChangeDevices,
onRealtimeAlerts,
onBufferSizeError,
onStopSharingScreen,
} = useProctoring({
examId: "00001",
clientId: "000001",
token: "...",
});
</script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="dist/unpkg/easyproctor.min.js"></script>
<script>
const {
login,
start,
finish,
checkDevices,
capturePhoto,
checkPermissions,
enumarateDevices,
checkIfhasMultipleMonitors,
onFocus,
onLostFocus,
onChangeDevices,
onRealtimeAlerts,
onBufferSizeError,
onStopSharingScreen
} = useProctoring({
examId: "00001",
clientId: "000001",
token: "...",
});
async function startExam() {
try {
// Verificar se existem dispositívos disponíveis
if (devices.cameras.length == 0 || devices.microphones.length == 0) {
throw "Você precisa possuir ao menos uma câmera e um microfone";
}
// Verificar se foram setados
const selectedCamera = cameras.value;
const selectedMicrophone = microphones.value;
if (!selectedCamera || !selectedMicrophone) {
throw "Você precisa selecionar uma camera e um microfone";
}
startButton.innerHTML = "Carregando";
onFocus(() => generateAlert(false));
onLostFocus(() => generateAlert(true));
// Adicionar o dispositivo selecionado é opcional
const { cameraStream } = await start({
cameraId: selectedCamera,
microphoneId: selectedMicrophone,
});
} catch (error) {
alert(error);
}
}
async function finishExam() {
try {
await finish({ onProgress: (percentage) => console.log(percentage) });
console.log("EXAME FINALIZADO");
} catch (error) {
alert(error);
}
}
// Verificar permissões
let devices = { cameras: [], microphones: [] };
async function verifyPermissions() {
// Checar permissões
var hasPermissions = await checkPermissions();
if (!hasPermissions) {
window.alert("Para continuar você precisa conceder as permissões");
return;
}
// Listar os dispositivos
devices = await enumarateDevices();
const generateOption = (text, value) => {
const el = document.createElement("option");
el.setAttribute("value", value);
el.innerHTML = text;
return el;
};
devices.cameras.forEach((camera) => {
const option = generateOption(camera.label, camera.id);
cameras.appendChild(option);
});
devices.microphones.forEach((microphone) => {
const option = generateOption(microphone.label, microphone.id);
microphones.appendChild(option);
});
}
// Gerar alerta
function generateAlert(lostFocus) {
const p = document.createElement("p");
if (lostFocus) {
p.classList.add("text-red-500");
p.innerHTML = `Perdeu o foco em: ${new Date().toLocaleTimeString()}`;
} else {
p.classList.add("text-green-500");
p.innerHTML = `Retomou o foco em: ${new Date().toLocaleTimeString()}`;
}
alerts.appendChild(p);
}
</script>
</head>
<body>
<div
style="height: 100vh; display: flex; align-items: center; justify-content: center;"
>
<button onclick="startExam()">Iniciar</button>
<button onclick="finishExam()">Finalizar</button>
<button onclick="verifyPermissions()">Verificar permissões</button>
</div>
</body>
</html>
const {
// Inicia a gravação da prova
start,
// Finaliza a gravação da prova retornando os arquivos gerados
finish,
// Adiciona uma função callback para ser executada quando o usuário recupera o foco da tela
onFocus,
// Adiciona uma função de callback para ser executada quando ...
onBufferSizeError,
// Adiciona um função de callback para ser executada quando o usuário altera os dispositivos
onChangeDevices,
// Adiciona uma função callback para ser executada quando o usuário perde o foco da tela
onLostFocus,
// Adiciona uma função de callback para ser executada quando ocorrem alertas durante o exame
onRealtimeAlerts,
// Adiciona uma função callback para ser executada quando o usuário cancela o compartilhamento de tela
onStopSharingScreen
// Realiza uma captura de foto do usuário e a utiliza para fazer o resgistro ou login biométrico.
capturePhoto
// Checa se os dispositivos (câmera, microfone, stream da tela) estão funcionando corretamente
checkDevices,
// Checa se existe mais de um monitor
checkIfhasMultipleMonitors,
// Checa as permissões de camera e microfone
checkPermissions,
// Enumera os dispositivos de camera e microfone
enumarateDevices,
} = useProctoring({
examId: "00001",
clientId: "000001",
token: "...",
});
- Criação do runCheckDevicesFlow que permite que o usuário receba a lógica do checkDevices() em um modal próprio
- Otimização na gravação de áudio removendo necessidade de download de scripts
- Tratamento para fechamento de streams
- console.log() configuravel
- Tratamento para duplo clique no checkDevices
- Ajuste de CORS no NoiseRecorder
- Remoção do script deprecated AudioProcessor
- Monitoramento ativo durante o exame
- Novos tipos de alertas do onRealtimeAlerts:
- audio_detection_on_stream
- face_detection_on_stream
- mobile_detection_on_stream
- person_detection_on_stream
- position_detection_on_stream
- Novos tipos de alertas do onRealtimeAlerts:
- Nova forma de gravação de áudio
- Remoção das funções
pause()
eresume()
- Análise de posicionamento da face no modal do
checkDevices()
- Novas propriedades adicionadas no retorno do
checkDevices()
:
{
allowedAmbient: boolean,
allowedMicrophone: boolean,
allowedPositionFace: boolean,
allowedResolution: boolean,
cameraId: string,
michophoneId: string,
volumeRange: number,
faceDetectionAlerts: { status: 'OK' | 'ALERT', type: string, description?: string },
result: boolean,
}
-
- Adiciona o botão de cancelar captura no
capturePhoto()
. - Se a captura for cancelada, ela lancará uma exceção.
- Adiciona o botão de cancelar captura no
- Captura da Geolocalização
- Login via componente (Credentials)
- Bloquear navegadores sem suporte
- Bloquear exame quando camera estiver em uso
- Gravação de vídeo opcional
- Atualização Interface do CapturePhoto
- Criação do callback onBufferSizeError
- Criação do callback onRealtimeAlerts
- Bloqueio das cameras simuladas da listagem de devices
- Aviso de camera ocupada
- Adicionado resolução de 480p na gravação da tela
- Melhorias no finish
- Adicionado fotos durante a execução da prova
- Adicionado o modal de capturePhoto, para cadastramento e autenticação biométrica
- Correção de interface do modal checkDevices com problema no lts