@privateid/small-age-sdk-alpha
Version:
965 lines • 52.9 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
/* eslint-disable default-param-last */
/* eslint-disable @typescript-eslint/ban-ts-comment */
import { detect } from 'detect-browser';
import { proxy } from 'comlink';
import { getIsSIMD, printLogs, getDebugType, setDefaultCameraDeviceId, getDefaultCameraDeviceId, iOS, multiframeLivenessAndAgePredict, prividDocumentMugshotFaceCompare, getFrontDocumentStatusMessage, scanDocument, isValidBarCode, createImages, isMobileFunc, frontDocumentOcr, } from './utils';
import { CameraFaceMode, DocType, FaceStatuses, ImageType, LOGTYPE } from './types';
import { facingMode } from './constants';
import { getCameraList, getVideoConstraints, isFaceTimeCamera, isMobileBackCameraPortrait } from './cameraUtils';
let isSimd = false;
getIsSIMD().then((simd) => (isSimd = simd));
const debugType = getDebugType();
let privid_wasm_result = (operation, id, response_str) => { };
// camera configs
let videoElement = null;
let faceMode = CameraFaceMode.front;
let mediaDevice = null;
let mediaDevices = null;
let mediaStream = null;
const cameraHeight = 1440;
const cameraWidth = 2560;
const cameraLowResHeight = 1080;
const cameraLowResWidth = 1920;
const mobileCameraResWidth = 2560;
const mobileCameraResHeight = 1440;
const createCallbackMutiframeLivenessAndPredictAge = (callback, imageData) => (operation, id, response_str) => {
var _a;
const isResponse = response_str.length > 0;
// console.log(
// '================[JS RESPONSE]: response_str',
// isResponse ? JSON.parse(response_str) : '', //,
// //debugType,
// //LOGTYPE.LOG,
// );
// console.log('[JS RESPONSE]: operation', operation || 'null'); //debugType, LOGTYPE.LOG);
// console.log('[JS RESPONSE]: id', id || 'null'); //debugType, LOGTYPE.LOG);
if (isResponse) {
const returnValue = JSON.parse(response_str);
console.log("response:", JSON.parse(response_str));
const getResponse = (response) => {
try {
return JSON.parse(response);
}
catch (e) {
return null;
}
};
const returnData = {
call_status: returnValue.call_status.return_status,
mf_token: returnValue.call_status.mf_token,
face_validation_status: returnValue.estimate_age.face_validation_status,
antispoof_status: returnValue.estimate_age.antispoofing_status,
api_payload: returnValue.estimate_age.http_response_payload,
remove_glasses: returnValue.estimate_age.young_with_eye_glasses,
age_estimation: (_a = returnValue === null || returnValue === void 0 ? void 0 : returnValue.estimate_age) === null || _a === void 0 ? void 0 : _a.age_estimation
};
if (operation === 'estimate_age') {
callback({ status: FaceStatuses.WASM_RESPONSE, returnValue: returnData, portrait: imageData });
}
}
};
// Optimized Version
const mfAgeCanvas = document.createElement('canvas');
export const multiframeLivenessAndAge = (callback, config) => __awaiter(void 0, void 0, void 0, function* () {
privid_wasm_result = createCallbackMutiframeLivenessAndPredictAge(callback);
if (!videoElement) {
printLogs('capture need the video element id', '', debugType, LOGTYPE.ERROR);
return { result: 'error' };
}
const videoEl = document.getElementById(videoElement);
printLogs('video element', videoEl, debugType);
if (!videoEl) {
printLogs('no video element found', '', debugType, LOGTYPE.ERROR);
return { result: 'error' };
}
const height = videoEl.videoHeight;
const width = videoEl.videoWidth;
if (width === 0)
return { result: 'error' };
mfAgeCanvas.setAttribute('id', 'test-canvas');
mfAgeCanvas.setAttribute('height', `${height}`);
mfAgeCanvas.setAttribute('width', `${width}`);
// canvas.height = height;
// canvas.width = width;
const context = mfAgeCanvas.getContext('2d', { willReadFrequently: true });
context.drawImage(videoEl, 0, 0);
const imageData = context.getImageData(0, 0, width, height);
let finalConfig = {
input_image_format: 'rgba',
context_string: 'enroll',
angle_rotation_left_threshold: 20.0,
angle_rotation_right_threshold: 20.0,
// preprocessing_margin_factor: 4,
// antispoof_face_margin: 1.0,
// gray_scale_variance_threshold: 100.0,
// enroll_embeddings_compare: 1.9,
threshold_high_vertical_enroll: -0.15,
threshold_down_vertical_enroll: 0.15,
// threshold_user_too_far: 0.15,
threshold_user_right: 0.15,
threshold_user_left: 0.85,
threshold_user_up: 0.08,
threshold_user_down: 0.92,
// anti_spoofing_detect_document: true,
threshold_profile_enroll: 0.65,
threshold_user_too_close: 0.8,
anti_spoofing_threshold: 0.8,
// gray_scale_threshold: 14.0,
threshold_doc_too_far: 40,
conf_score_thr_doc: 0.9,
};
const { os } = detect();
if (['iOS', 'android', 'Android OS'].includes(os)) {
finalConfig = Object.assign(Object.assign({}, finalConfig), {
// threshold_user_too_far: 0.1,
threshold_user_right: 0.2, threshold_user_left: 0.8 });
}
if (config) {
finalConfig = Object.assign(Object.assign({}, finalConfig), config);
}
if (imageData) {
privid_wasm_result = createCallbackMutiframeLivenessAndPredictAge(callback, imageData);
const configString = JSON.stringify(finalConfig);
console.log("Config before worker:", finalConfig);
yield multiframeLivenessAndAgePredict(imageData.data, imageData.width, imageData.height, configString, proxy(privid_wasm_result));
}
releaseCanvas(mfAgeCanvas);
});
const openCameraMobile = (domElement, requestFaceMode = null, canvasResolution, requireHD = false, isDocumentScan) => __awaiter(void 0, void 0, void 0, function* () {
try {
let inCatchBlock = false;
videoElement = domElement;
printLogs('Opening Camera on Mobile', '', debugType);
let devices = yield navigator.mediaDevices.enumerateDevices();
devices = devices.filter((d) => d.kind === 'videoinput');
devices = getDevicesWithCapabilities(devices);
let stream;
let hasError = true;
while (hasError) {
try {
// @ts-ignore
const videoConstraint = getVideoConstraints(yield getCameraList(faceMode === 'back'),
// @ts-ignore
facingMode[faceMode], requireHD, isDocumentScan, canvasResolution, inCatchBlock);
// console.log('videoConstraint:', videoConstraint);
stream = yield navigator.mediaDevices.getUserMedia(
// @ts-ignore
videoConstraint);
hasError = false;
}
catch (e) {
printLogs('openCameraMobile', e, debugType, LOGTYPE.ERROR);
inCatchBlock = true;
// hasError = false;
}
}
const track = stream.getVideoTracks()[0];
const capabilities = track.getCapabilities();
const settings = track.getSettings();
const element = document.getElementById(domElement);
element.srcObject = stream;
element.play();
yield new Promise((resolve) => (element.onplaying = resolve));
mediaStream = stream;
return { status: true, stream, devices, faceMode, settings, capabilities };
}
catch (e) {
printLogs('Error:', e, debugType, LOGTYPE.ERROR);
return null;
}
});
/**
* @ignore
*/
const openCameraMacSafari = (domElement, deviceId = null, canvasResolution = { width: cameraWidth, height: cameraHeight }, requireHD = false) => __awaiter(void 0, void 0, void 0, function* () {
var _a, _b, _c, _d;
try {
videoElement = domElement;
printLogs('Opening Camera on Mac Safari', '', debugType);
let devices = yield navigator.mediaDevices.enumerateDevices();
devices = devices.filter((d) => d.kind === 'videoinput');
const defaultDeviceId = getDefaultCameraDeviceId();
const externalDeviceId = devices.length > 1 ? devices.find((device) => !device.label.includes('FaceTime')) : devices[0];
const isDefaultDeviceAvailable = devices.find((device) => defaultDeviceId === device.deviceId);
mediaDevice = deviceId || (isDefaultDeviceAvailable ? defaultDeviceId : externalDeviceId.deviceId);
setDefaultCameraDeviceId(mediaDevice);
const deviceCapabilites = getDefaultDevice(devices, mediaDevice);
const resolution = requireHD
? (canvasResolution === null || canvasResolution === void 0 ? void 0 : canvasResolution.width) || Math.min(((_b = (_a = deviceCapabilites[0]) === null || _a === void 0 ? void 0 : _a.width) === null || _b === void 0 ? void 0 : _b.max) || cameraWidth, cameraWidth)
: (canvasResolution === null || canvasResolution === void 0 ? void 0 : canvasResolution.width) || Math.min(((_d = (_c = deviceCapabilites[0]) === null || _c === void 0 ? void 0 : _c.width) === null || _d === void 0 ? void 0 : _d.max) || cameraLowResWidth, cameraLowResWidth);
const constraints = {
audio: false,
video: {
deviceId: deviceCapabilites[0].deviceId,
width: { ideal: resolution },
height: (canvasResolution === null || canvasResolution === void 0 ? void 0 : canvasResolution.height) ? { ideal: canvasResolution === null || canvasResolution === void 0 ? void 0 : canvasResolution.height } : undefined,
// advance: [{ width: { ideal: 2560 }, height: { ideal: 1440 } }],
},
};
const stream = yield navigator.mediaDevices.getUserMedia(constraints);
const track = stream.getVideoTracks()[0];
const capabilities = track.getCapabilities();
const settings = track.getSettings();
printLogs('capabilities: ', capabilities, debugType, LOGTYPE.LOG);
printLogs('settings: ', settings, debugType, LOGTYPE.LOG);
const element = document.getElementById(domElement);
element.srcObject = stream;
element.play();
yield new Promise((resolve) => (element.onplaying = resolve));
mediaStream = stream;
return { status: true, stream, devices, faceMode, settings, capabilities };
}
catch (e) {
printLogs('Error while getAccessToCamera', e, debugType, LOGTYPE.ERROR);
return null;
}
});
const openCameraFirefox = (domElement, canvasResolution = { width: cameraWidth, height: cameraHeight }, requireHD = false) => __awaiter(void 0, void 0, void 0, function* () {
videoElement = domElement;
yield navigator.mediaDevices.getUserMedia({ audio: false, video: true });
printLogs('Firefox function here.....', '', debugType);
try {
let devices = [];
devices = yield navigator.mediaDevices.enumerateDevices();
devices = devices.filter((d) => d.kind === 'videoinput');
printLogs('=====> MY DEVICES??? ', devices, debugType);
if (devices.length === 0) {
printLogs('NO_CAMERA', '', debugType, LOGTYPE.ERROR);
throw new Error('NO_CAMERA');
}
const constraints = {
audio: false,
video: {
width: { ideal: (canvasResolution === null || canvasResolution === void 0 ? void 0 : canvasResolution.width) || requireHD ? cameraWidth : cameraLowResWidth },
height: (canvasResolution === null || canvasResolution === void 0 ? void 0 : canvasResolution.height) ? { ideal: canvasResolution === null || canvasResolution === void 0 ? void 0 : canvasResolution.height } : undefined,
},
aspectRatio: 1.7777777778,
focusMode: 'continuous',
facingMode: facingMode[faceMode] || 'user',
};
const stream = yield navigator.mediaDevices.getUserMedia(constraints);
const track = stream.getVideoTracks()[0];
const settings = track.getSettings();
const capabilities = (track === null || track === void 0 ? void 0 : track.getCapabilities) ? track.getCapabilities() : stream;
printLogs('settings: ', settings, debugType);
const element = document.getElementById(domElement);
element.srcObject = stream;
element.play();
yield new Promise((resolve) => (element.onplaying = resolve));
mediaStream = stream;
mediaDevices = devices;
// @ts-ignore
return { status: true, errorMessage: '', stream, devices, faceMode, settings, capabilities };
}
catch (e) {
if (parseInt(debugType, 10) >= 2) {
printLogs('Error while getAccessToCamera', e, debugType, LOGTYPE.ERROR);
}
return null;
}
});
/**
* This function open camera, and returns the stream, current faceMode and the list of available media devices
* @category Face
* @param domElement id of the video tag
* @param requireHD
* @param deviceId
* @param requestFaceMode
* @param canvasResolution
* @param isDocumentScan
*/
export const openCamera = (domElement, requireHD, deviceId = null, requestFaceMode = null, canvasResolution, isDocumentScan) => __awaiter(void 0, void 0, void 0, function* () {
var _e, _f, _g;
videoElement = domElement;
faceMode = requestFaceMode;
const { name: browserName, os } = detect();
yield navigator.mediaDevices.getUserMedia({ video: true, audio: false }).then((mediaStream) => {
const stream = mediaStream;
const tracks = stream.getTracks();
tracks.forEach((track) => track.stop());
});
// Firefox
if (browserName === 'firefox') {
printLogs('==== Firefox open camera', '', debugType);
return openCameraFirefox(domElement, canvasResolution, requireHD);
}
// Mobile
if (iOS() || ['iOS', 'android', 'Android OS'].includes(os)) {
printLogs('==== Mobile open camera!', '', debugType);
return openCameraMobile(domElement, requestFaceMode, canvasResolution, requireHD, isDocumentScan);
}
// Mac Safari Browser
if (os === 'Mac OS' && browserName === 'safari') {
printLogs('==== Mac safari open camera!', '', debugType);
return openCameraMacSafari(domElement, deviceId, canvasResolution, requireHD);
}
try {
let devices = [];
devices = yield navigator.mediaDevices.enumerateDevices();
devices = devices.filter((d) => d.kind === 'videoinput');
printLogs('=====> MY DEVICES??? ', devices, debugType);
if (devices.length === 0) {
printLogs('NO_CAMERA', '', debugType, LOGTYPE.ERROR);
throw new Error('NO_CAMERA');
}
let defaultDeviceId = getDefaultCameraDeviceId();
if (deviceId) {
defaultDeviceId = deviceId;
}
if (!mediaDevice) {
if (deviceId) {
mediaDevice = deviceId;
}
else {
const isDefaultDeviceAvailable = devices.find((device) => defaultDeviceId === device.deviceId);
mediaDevice = isDefaultDeviceAvailable ? defaultDeviceId : devices[0].deviceId;
}
}
const deviceCapabilites = getDefaultDevice(devices, mediaDevice);
const isMacFaceTimeCamera = isFaceTimeCamera((_e = deviceCapabilites[0]) === null || _e === void 0 ? void 0 : _e.label, isDocumentScan);
printLogs('========= Opens Camera ======== ', '', debugType);
const getBestResolution = () => __awaiter(void 0, void 0, void 0, function* () {
var _h, _j;
let resolution = (canvasResolution === null || canvasResolution === void 0 ? void 0 : canvasResolution.width) || Math.min(((_j = (_h = deviceCapabilites[0]) === null || _h === void 0 ? void 0 : _h.width) === null || _j === void 0 ? void 0 : _j.max) || cameraWidth, cameraWidth);
let hasError = true;
let constraints = {
audio: false,
video: {
deviceId: deviceCapabilites[0].deviceId,
width: { ideal: resolution },
height: (canvasResolution === null || canvasResolution === void 0 ? void 0 : canvasResolution.height) ? { ideal: canvasResolution === null || canvasResolution === void 0 ? void 0 : canvasResolution.height } : { ideal: cameraHeight },
aspectRatio: isMacFaceTimeCamera ? 1 : 1.777777778,
resizeMode: 'none',
},
};
let stream;
while (hasError) {
try {
stream = yield navigator.mediaDevices.getUserMedia(constraints);
if (stream)
hasError = false;
}
catch (e) {
resolution = getTheNextResolutionAvailable(resolution);
constraints = Object.assign(Object.assign({}, constraints), { video: Object.assign(Object.assign({}, constraints.video), { width: { ideal: resolution } }) });
}
}
printLogs('bestconstraints: ', constraints, debugType);
return stream;
});
let stream;
if (requireHD) {
let hasError = true;
let resolution = (canvasResolution === null || canvasResolution === void 0 ? void 0 : canvasResolution.width) || Math.min(((_g = (_f = deviceCapabilites[0]) === null || _f === void 0 ? void 0 : _f.width) === null || _g === void 0 ? void 0 : _g.max) || cameraWidth, cameraWidth);
let constraints = {
audio: false,
deviceId: mediaDevice,
video: {
width: { min: resolution, max: resolution },
aspectRatio: isMacFaceTimeCamera ? 1 : 1.777777778,
height: isMacFaceTimeCamera ? { min: cameraHeight, max: cameraHeight } : undefined,
},
};
while (hasError) {
try {
stream = yield navigator.mediaDevices.getUserMedia(constraints);
if (stream)
hasError = false;
}
catch (e) {
printLogs('require HD Error: ', e, debugType, LOGTYPE.ERROR);
resolution = getTheNextResolutionAvailable(resolution);
constraints = Object.assign(Object.assign({}, constraints), { video: Object.assign(Object.assign({}, constraints.video), { width: { min: resolution, max: resolution } }) });
}
}
}
else {
stream = yield getBestResolution();
}
const track = stream.getVideoTracks()[0];
const capabilities = track.getCapabilities();
const settings = track.getSettings();
setDefaultCameraDeviceId(settings === null || settings === void 0 ? void 0 : settings.deviceId);
printLogs('capabilities: ', capabilities, debugType);
printLogs('settings: ', settings, debugType);
const element = document.getElementById(domElement);
element.srcObject = stream;
element.play();
yield new Promise((resolve) => (element.onplaying = resolve));
mediaStream = stream;
mediaDevices = devices;
return { status: true, stream, devices, faceMode, settings, capabilities };
}
catch (e) {
printLogs('Error while getAccessToCamera', e, debugType, LOGTYPE.ERROR);
return null;
}
});
/**
* This function open camera, and returns the stream, current faceMode and the list of available media devices
* @category Face
* @param domElement id of the video tag
*/
export const closeCamera = (element) => __awaiter(void 0, void 0, void 0, function* () {
try {
const video = element || videoElement;
const videoEl = document.getElementById(video);
if (!videoEl)
return;
const stream = videoEl === null || videoEl === void 0 ? void 0 : videoEl.srcObject;
if (stream) {
const tracks = stream === null || stream === void 0 ? void 0 : stream.getTracks();
tracks === null || tracks === void 0 ? void 0 : tracks.forEach((track) => {
track === null || track === void 0 ? void 0 : track.stop();
});
if (videoEl) {
videoEl.srcObject = null;
}
}
}
catch (err) {
printLogs('Close Camera', err, debugType, LOGTYPE.ERROR);
}
});
const getTheNextResolutionAvailable = (currentResolution) => {
printLogs('getTheNextResolutionAvailable', currentResolution, debugType);
const resolutions = [2560, 1920, 1600, 1552, 1440, 1280, 1024, 960, 800, 720, 704, 640].sort((a, b) => b - a);
return resolutions.find((e) => e < currentResolution) || 640;
};
/**
* This function switch camera from front to back on mobile, and to another device on desktop
* @category Face
* @param selectedCamera Selected camera either front or back
* @param device Selected camera ID
* @param canvasResolution
*/
export const switchCamera = (selectedCamera, device, canvasResolution) => __awaiter(void 0, void 0, void 0, function* () {
if (!videoElement)
return;
let devices = [];
if (mediaStream) {
mediaStream.getTracks().forEach((track) => track.stop());
}
devices = yield navigator.mediaDevices.enumerateDevices();
devices = devices.filter((d) => d.kind === 'videoinput');
devices = getDevicesWithCapabilities(devices);
const deviceCapabilites = getDefaultDevice(devices, device);
if (selectedCamera)
faceMode = selectedCamera;
const getBestResolution = () => __awaiter(void 0, void 0, void 0, function* () {
var _k, _l, _m, _o;
let resolution = (canvasResolution === null || canvasResolution === void 0 ? void 0 : canvasResolution.width) || Math.min(((_l = (_k = deviceCapabilites[0]) === null || _k === void 0 ? void 0 : _k.width) === null || _l === void 0 ? void 0 : _l.max) || cameraWidth, cameraWidth);
const isPortraitMobileCamera = isMobileBackCameraPortrait(deviceCapabilites[0]);
console.log('switchCamera', { deviceCapabilites });
let hasError = true;
const videoConstraints = {
deviceId: deviceCapabilites[0].deviceId,
width: { ideal: calculateWidth() },
height: { ideal: calculateHeight() },
facingMode: ((_o = (_m = deviceCapabilites[0]) === null || _m === void 0 ? void 0 : _m.facingMode) === null || _o === void 0 ? void 0 : _o[0]) || undefined,
focusMode: 'continuous',
aspectRatio: calculateAspectRatio(),
resizeMode: 'none',
};
const constraints = {
audio: false,
video: videoConstraints, // Apply video constraints
};
function calculateWidth() {
if (canvasResolution === null || canvasResolution === void 0 ? void 0 : canvasResolution.width) {
return resolution; // Use the specified resolution if canvas width is available
}
else if (isPortraitMobileCamera) {
return cameraHeight; // Use camera height for portrait mobile camera
}
else {
return resolution; // Use the specified resolution for other cases
}
}
function calculateHeight() {
if (canvasResolution === null || canvasResolution === void 0 ? void 0 : canvasResolution.height) {
return canvasResolution.height; // Use the specified canvas height
}
else {
return cameraHeight; // Use camera height if canvas height is not available
}
}
function calculateAspectRatio() {
if (canvasResolution === null || canvasResolution === void 0 ? void 0 : canvasResolution.width) {
return 1.7777777778; // 16:9 aspect ratio if canvas width is available
}
else if (isPortraitMobileCamera) {
return 1; // 1:1 aspect ratio for portrait mobile camera
}
else {
return 1.7777777778; // 16:9 aspect ratio for other cases
}
}
// console.log({ constraints });
let stream;
while (hasError) {
try {
stream = yield navigator.mediaDevices.getUserMedia(constraints);
hasError = false;
}
catch (e) {
resolution = getTheNextResolutionAvailable(resolution);
constraints.video = Object.assign(Object.assign({}, constraints.video), { width: { ideal: resolution } });
}
}
printLogs('bestconstraints: ', constraints, debugType);
return stream;
});
if (device) {
mediaDevice = device;
setDefaultCameraDeviceId(device);
}
if (selectedCamera && !device) {
if (selectedCamera) {
const regex = selectedCamera === CameraFaceMode.back ? /back/gi : /front/gi;
devices = devices.filter((d) => regex.test(d.label));
}
const getBestResolutionWithFacingMode = () => __awaiter(void 0, void 0, void 0, function* () {
var _p, _q;
const deviceCapabilites = getDefaultDevice(devices, devices[0].deviceId);
const { name: browserName, os } = detect();
const resolutionWidth = (canvasResolution === null || canvasResolution === void 0 ? void 0 : canvasResolution.width) || (iOS() || ['iOS'].includes(os) ? cameraLowResWidth : cameraWidth);
const resolutionHeight = (canvasResolution === null || canvasResolution === void 0 ? void 0 : canvasResolution.height) || (iOS() || ['iOS'].includes(os) ? cameraLowResHeight : cameraHeight);
let hasError = true;
const constraints = {
audio: false,
video: {
// deviceId: deviceCapabilites[0].deviceId,
width: { ideal: resolutionWidth },
facingMode: faceMode ? facingMode[faceMode] : 'user',
height: { ideal: resolutionHeight },
resizeMode: 'none',
},
advance: [
{
focusMode: 'continuous',
resizeMode: 'none',
// @ts-ignore
focusDistance: Math.min(((_q = (_p = deviceCapabilites[0]) === null || _p === void 0 ? void 0 : _p.focusDistance) === null || _q === void 0 ? void 0 : _q.max) || 100, 100),
aspectRatio: 1.7777777778,
},
],
};
let stream;
while (hasError) {
try {
stream = yield navigator.mediaDevices.getUserMedia(constraints);
hasError = false;
}
catch (e) {
//
}
}
printLogs('bestconstraints: ', constraints, debugType);
return stream;
});
try {
// eslint-disable-next-line no-nested-ternary
const stream = yield getBestResolutionWithFacingMode();
const element = document.getElementById(videoElement);
element.srcObject = stream;
mediaStream = stream;
const track = stream.getVideoTracks()[0];
const capabilities = (track === null || track === void 0 ? void 0 : track.getCapabilities) ? track.getCapabilities() : null;
const settings = track.getSettings();
printLogs('switch camera capabilities:', capabilities, debugType);
printLogs('switch camera settings:', settings, debugType);
// eslint-disable-next-line consistent-return
return { capabilities, settings };
}
catch (e) {
printLogs('Error while getAccessToCamera', e, debugType, LOGTYPE.ERROR);
yield switchCamera(null, devices[0].deviceId, canvasResolution);
}
}
else {
try {
// eslint-disable-next-line no-nested-ternary
const stream = yield getBestResolution();
const element = document.getElementById(videoElement);
element.srcObject = stream;
mediaStream = stream;
const track = stream.getVideoTracks()[0];
const capabilities = (track === null || track === void 0 ? void 0 : track.getCapabilities) ? track.getCapabilities() : null;
const settings = track.getSettings();
printLogs('switch camera capabilities:', capabilities, debugType);
printLogs('switch camera settings:', settings, debugType);
// eslint-disable-next-line consistent-return
return { capabilities, settings };
}
catch (e) {
printLogs('Error while getAccessToCamera', e, debugType, LOGTYPE.ERROR);
yield switchCamera(null, devices[0].deviceId, canvasResolution);
}
}
});
const getDefaultDevice = (devices, device) => devices.reduce((acc, val) => {
if (val.deviceId === device) {
// @ts-ignore
if (val === null || val === void 0 ? void 0 : val.getCapabilities) {
// @ts-ignore
acc.push(Object.assign(Object.assign({}, val.getCapabilities()), { label: val.label }));
}
else {
acc.push(val);
}
}
return acc;
}, []);
const getDevicesWithCapabilities = (devices) => devices.map((device) => {
// Check if 'getCapabilities' exists on 'device'
// @ts-ignore
if (device.getCapabilities) {
// Use 'device.getCapabilities()' directly without optional chaining
// @ts-ignore
const capabilities = device.getCapabilities();
// Return a new object with capabilities and label
return Object.assign(Object.assign({}, capabilities), { label: device.label });
}
return device;
});
function releaseCanvas(canvas) {
try {
printLogs('---- STARTING TO RELEASE CANVAS -----', '', debugType);
// eslint-disable-next-line no-param-reassign
canvas.width = 1;
// eslint-disable-next-line no-param-reassign
canvas.height = 1;
const ctx = canvas.getContext('2d', { willReadFrequently: true });
// eslint-disable-next-line no-unused-expressions
ctx && ctx.clearRect(0, 0, 1, 1);
// eslint-disable-next-line no-param-reassign
canvas = null;
printLogs('---- CANVAS RELEASED -----', '', debugType);
}
catch (e) {
printLogs('____clearing canvas', e, debugType, LOGTYPE.ERROR);
}
}
export const openFrontCameraOnly = (domElement, deviceId = null) => __awaiter(void 0, void 0, void 0, function* () {
var _r;
videoElement = domElement;
yield navigator.mediaDevices.getUserMedia({ video: true, audio: false }).then((mediaStream) => {
const stream = mediaStream;
const tracks = stream.getTracks();
tracks.forEach((track) => track.stop());
});
try {
let devices = [];
devices = yield navigator.mediaDevices.enumerateDevices();
const frontRegex = /front/gi;
devices = devices.filter((d) => d.kind === 'videoinput' && frontRegex.test(d.label));
printLogs('=====> MY DEVICES??? ', devices, debugType);
if (devices.length === 0) {
printLogs('No front camera available', '', debugType, LOGTYPE.ERROR);
throw new Error('No front Camera available');
}
let defaultDeviceId = getDefaultCameraDeviceId();
if (deviceId) {
defaultDeviceId = deviceId;
}
if (!mediaDevice) {
if (deviceId) {
mediaDevice = deviceId;
}
else {
const isDefaultDeviceAvailable = devices.find((device) => defaultDeviceId === device.deviceId);
mediaDevice = isDefaultDeviceAvailable ? defaultDeviceId : devices[0].deviceId;
}
}
const deviceCapabilites = getDefaultDevice(devices, mediaDevice);
const isMacFaceTimeCamera = isFaceTimeCamera((_r = deviceCapabilites[0]) === null || _r === void 0 ? void 0 : _r.label, false);
printLogs('========= Opens Camera ======== ', '', debugType);
const getBestResolution = () => __awaiter(void 0, void 0, void 0, function* () {
var _s, _t;
let resolution = Math.min(((_t = (_s = deviceCapabilites[0]) === null || _s === void 0 ? void 0 : _s.width) === null || _t === void 0 ? void 0 : _t.max) || cameraWidth, cameraWidth);
let hasError = true;
let constraints = {
audio: false,
video: {
deviceId: deviceCapabilites[0].deviceId,
width: { ideal: 1920 },
height: { ideal: 1080 },
resizeMode: 'none',
facingMode: 'user',
},
};
let stream;
while (hasError) {
try {
stream = yield navigator.mediaDevices.getUserMedia(constraints);
if (stream)
hasError = false;
}
catch (e) {
resolution = getTheNextResolutionAvailable(resolution);
constraints = Object.assign(Object.assign({}, constraints), { video: Object.assign(Object.assign({}, constraints.video), { width: { ideal: resolution } }) });
}
}
printLogs('bestconstraints: ', constraints, debugType);
return stream;
});
let stream;
stream = yield getBestResolution();
const track = stream.getVideoTracks()[0];
const capabilities = track.getCapabilities();
const settings = track.getSettings();
setDefaultCameraDeviceId(settings === null || settings === void 0 ? void 0 : settings.deviceId);
printLogs('capabilities: ', capabilities, debugType);
printLogs('settings: ', settings, debugType);
const element = document.getElementById(domElement);
element.srcObject = stream;
element.play();
yield new Promise((resolve) => (element.onplaying = resolve));
mediaStream = stream;
mediaDevices = devices;
return { status: true, stream, devices, faceMode, settings, capabilities };
}
catch (e) {
printLogs('Error while getAccessToCamera', e, debugType, LOGTYPE.ERROR);
return null;
}
});
const createCallbackCompareDocumentAndFace = (callback) => (operation, id, response_str) => {
const isResponse = response_str.length > 0;
console.log('================[JS RESPONSE]: response_str', isResponse ? JSON.parse(response_str) : ''); //, LOGTYPE.LOG);
console.log('[JS RESPONSE]: operation', operation || 'null'); // , LOGTYPE.LOG);
console.log('[JS RESPONSE]: id', id || 'null'); // , LOGTYPE.LOG);
if (isResponse) {
if (operation === 'compare_mugshot_and_face') {
const returnValue = JSON.parse(response_str);
const getJsonParsed = (toParse) => {
try {
return JSON.parse(toParse);
}
catch (e) {
return '';
}
};
callback({
status: FaceStatuses.WASM_RESPONSE,
returnValue: getJsonParsed(returnValue.compare_face_and_mugshot.http_response_payload),
});
}
}
};
export const documentMugshotFaceCompare = (callback, imageDataA, imageDataB, config) => __awaiter(void 0, void 0, void 0, function* () {
privid_wasm_result = createCallbackCompareDocumentAndFace(callback);
let finalConfig = {
input_image_format: 'rgba',
skip_antispoof: true,
angle_rotation_left_threshold: 100.0,
angle_rotation_right_threshold: 100.0,
threshold_high_vertical_enroll: -0.2,
threshold_down_vertical_enroll: 0.2,
threshold_high_vertical_predict: -0.2,
threshold_down_vertical_predict: 0.2,
threshold_user_too_far: 0.01,
threshold_profile_predict: 0.8,
threshold_profile_enroll: 0.8,
};
if (config) {
finalConfig = Object.assign(Object.assign({}, finalConfig), config);
}
const configJSON = JSON.stringify(finalConfig);
const result = yield prividDocumentMugshotFaceCompare(imageDataA, imageDataB, isSimd, debugType, proxy(privid_wasm_result), configJSON);
return result;
});
const createCallbackFrontDlScan = (callback, canvas) => (operation, id, response_str) => {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1;
const isResponse = response_str.length > 0;
// console.log('================[JS RESPONSE]: response_str', isResponse ? JSON.parse(response_str) : ''); // , LOGTYPE.LOG);
// console.log('[JS RESPONSE]: operation', operation || 'null'); //, LOGTYPE.LOG);
// console.log('[JS RESPONSE]: id', id || 'null'); //, LOGTYPE.LOG);
if (isResponse) {
if (operation === 'document_model') {
const returnValue = JSON.parse(response_str);
const returnData = {
document_validation_status: (_b = (_a = returnValue === null || returnValue === void 0 ? void 0 : returnValue.doc_face) === null || _a === void 0 ? void 0 : _a.document_data) === null || _b === void 0 ? void 0 : _b.document_validation_status,
call_status: (_c = returnValue === null || returnValue === void 0 ? void 0 : returnValue.call_status) === null || _c === void 0 ? void 0 : _c.return_status,
cropped_mugshot: {
data: (_e = (_d = returnValue === null || returnValue === void 0 ? void 0 : returnValue.doc_face) === null || _d === void 0 ? void 0 : _d.cropped_face_image) === null || _e === void 0 ? void 0 : _e.data,
width: (_h = (_g = (_f = returnValue === null || returnValue === void 0 ? void 0 : returnValue.doc_face) === null || _f === void 0 ? void 0 : _f.cropped_face_image) === null || _g === void 0 ? void 0 : _g.info) === null || _h === void 0 ? void 0 : _h.width,
height: (_l = (_k = (_j = returnValue === null || returnValue === void 0 ? void 0 : returnValue.doc_face) === null || _j === void 0 ? void 0 : _j.cropped_face_image) === null || _k === void 0 ? void 0 : _k.info) === null || _l === void 0 ? void 0 : _l.height,
},
cropped_document: {
data: (_p = (_o = (_m = returnValue === null || returnValue === void 0 ? void 0 : returnValue.doc_face) === null || _m === void 0 ? void 0 : _m.document_data) === null || _o === void 0 ? void 0 : _o.cropped_document_image) === null || _p === void 0 ? void 0 : _p.data,
width: (_t = (_s = (_r = (_q = returnValue === null || returnValue === void 0 ? void 0 : returnValue.doc_face) === null || _q === void 0 ? void 0 : _q.document_data) === null || _r === void 0 ? void 0 : _r.cropped_document_image) === null || _s === void 0 ? void 0 : _s.info) === null || _t === void 0 ? void 0 : _t.width,
height: (_x = (_w = (_v = (_u = returnValue === null || returnValue === void 0 ? void 0 : returnValue.doc_face) === null || _u === void 0 ? void 0 : _u.document_data) === null || _v === void 0 ? void 0 : _v.cropped_document_image) === null || _w === void 0 ? void 0 : _w.info) === null || _x === void 0 ? void 0 : _x.height,
},
};
callback({
status: FaceStatuses.WASM_RESPONSE,
returnValue: Object.assign(Object.assign({}, returnData), { status_message: getFrontDocumentStatusMessage((_z = (_y = returnValue === null || returnValue === void 0 ? void 0 : returnValue.doc_face) === null || _y === void 0 ? void 0 : _y.document_data) === null || _z === void 0 ? void 0 : _z.document_validation_status) }),
});
if (((_1 = (_0 = returnValue === null || returnValue === void 0 ? void 0 : returnValue.doc_face) === null || _0 === void 0 ? void 0 : _0.document_data) === null || _1 === void 0 ? void 0 : _1.document_validation_status) === 0) {
releaseCanvas(canvas);
}
}
}
};
const createCallbackBackDlScan = (callback, canvas) => (operation, id, response_str) => {
var _a, _b, _c, _d;
const isResponse = response_str.length > 0;
// console.log('================[JS RESPONSE]: response_str', isResponse ? JSON.parse(response_str) : ''); //, LOGTYPE.LOG);
// console.log('[JS RESPONSE]: operation', operation || 'null'); //, LOGTYPE.LOG);
// console.log('[JS RESPONSE]: id', id || 'null'); //, LOGTYPE.LOG);
if (isResponse) {
const returnValue = JSON.parse(response_str);
const parseResponse = (toParse) => {
try {
return JSON.parse(toParse);
}
catch (e) {
return '';
}
};
if (operation === 'gage_doc_scan_barcode_for_age') {
const returnData = {
call_status: (_a = returnValue === null || returnValue === void 0 ? void 0 : returnValue.call_status) === null || _a === void 0 ? void 0 : _a.return_status,
document_validation_status: (_b = returnValue === null || returnValue === void 0 ? void 0 : returnValue.scan_barcode_for_age) === null || _b === void 0 ? void 0 : _b.document_validation_status,
barcode_status: (_c = returnValue === null || returnValue === void 0 ? void 0 : returnValue.scan_barcode_for_age) === null || _c === void 0 ? void 0 : _c.bar_code_detection_status,
api_response: parseResponse((_d = returnValue === null || returnValue === void 0 ? void 0 : returnValue.scan_barcode_for_age) === null || _d === void 0 ? void 0 : _d.http_response_payload),
};
// GAN, if Missing Field = undefined
callback({
status: FaceStatuses.WASM_RESPONSE,
returnValue: Object.assign({}, returnData),
});
if (returnData.barcode_status === 0) {
releaseCanvas(canvas);
}
}
}
};
const isValidPhotoIDCanvas = document.createElement('canvas');
export const isValidPhotoID = (docType, callback = () => { }, image, config = null, canvasSize = {}) => __awaiter(void 0, void 0, void 0, function* () {
printLogs('________________ DOCUMENT SCAN ______________', '', debugType);
const videoEl = document.getElementById(videoElement);
let configuration = {
document_auto_rotation: false,
input_image_format: 'rgba',
};
if (config) {
configuration = Object.assign(Object.assign({}, configuration), config);
}
if (docType === DocType.PHOTO_ID_FRONT) {
privid_wasm_result = createCallbackFrontDlScan(callback, isValidPhotoIDCanvas);
}
else {
privid_wasm_result = createCallbackBackDlScan(callback, isValidPhotoIDCanvas);
}
if (image && docType === DocType.PHOTO_ID_FRONT) {
// console.log('uploading with image', image);
const result = yield scanDocument(image, isSimd, proxy(privid_wasm_result), undefined, JSON.stringify(configuration), debugType);
return Object.assign({ imageData: image }, result);
}
if (image && docType === DocType.PHOTO_ID_BACK) {
configuration = JSON.stringify(configuration);
// console.log('uploading with image', image);
const result = yield isValidBarCode(image, isSimd, proxy(privid_wasm_result), configuration, debugType);
return Object.assign({ imageData: image }, result);
}
if (!videoElement || !videoEl) {
printLogs('capture need the video element id', '', debugType, LOGTYPE.ERROR);
return { result: 'error' };
}
const isDocument = docType === DocType.PHOTO_ID_FRONT;
let height = (canvasSize === null || canvasSize === void 0 ? void 0 : canvasSize.height) || videoEl.videoHeight;
let width = (canvasSize === null || canvasSize === void 0 ? void 0 : canvasSize.width) || videoEl.videoWidth;
if (isMobileFunc()) {
height = videoEl.videoHeight;
width = videoEl.videoWidth;
}
isValidPhotoIDCanvas.setAttribute('id', 'test-canvas');
isValidPhotoIDCanvas.setAttribute('height', `${height}`);
isValidPhotoIDCanvas.setAttribute('width', `${width}`);
const context = isValidPhotoIDCanvas.getContext('2d', { willReadFrequently: true });
context.drawImage(videoEl, 0, 0);
if ((image === null || image === void 0 ? void 0 : image.width) === 0 || width === 0 || height === 0)
return { result: 'error' };
let imageData = context.getImageData(0, 0, width, height);
let result = null;
const cb = proxy(privid_wasm_result);
if (['900', '901', '902', '903'].includes(debugType)) {
yield createImages([imageData], ImageType.original, true);
}
if (image) {
imageData = image;
}
try {
configuration = JSON.stringify(configuration);
if (isDocument) {
result = yield scanDocument(imageData, isSimd, cb, undefined, configuration, debugType);
}
else {
result = yield isValidBarCode(imageData, isSimd, cb, configuration, debugType);
}
imageData = null;
return Object.assign({}, result);
}
catch (e) {
printLogs('--------isValidPhotoID error', e, debugType);
return {
result: -1,
};
}
});
const createCallbackFrontOcr = (callback) => (operation, id, response_str) => {
var _a, _b, _c, _d;
const isResponse = response_str.length > 0;
console.log('================[JS RESPONSE]: CC OCR response_str', isResponse ? JSON.parse(response_str) : ''); //, LOGTYPE.LOG);
// console.log('[JS RESPONSE]: operation', operation || 'null'); //, LOGTYPE.LOG);
// console.log('[JS RESPONSE]: id', id || 'null'); //, LOGTYPE.LOG);
const parseJson = (doParse) => {
try {
return JSON.parse(doParse);
}
catch (e) {
return '';
}
};
if (isResponse) {
// if (operation === 'estimate_age') {
const returnValue = JSON.parse(response_str);
const returnData = {
call_status: returnValue.call_status.return_status,
face_validation_status: (_a = returnValue === null || returnValue === void 0 ? void 0 : returnValue.scan_document_for_age) === null || _a === void 0 ? void 0 : _a.face_validataion_status,
antispoof_status: (_b = returnValue === null || returnValue === void 0 ? void 0 : returnValue.scan_document_for_age) === null || _b === void 0 ? void 0 : _b.antispoofing_status,
api_payload: (_c = returnValue === null || returnValue === void 0 ? void 0 : returnValue.scan_document_for_age) === null || _c === void 0 ? void 0 : _c.http_response_payload,
age_estimation: (_d = returnValue === null || returnValue === void 0 ? void 0 : returnValue.scan_document_for_age) === null || _d === void 0 ? void 0 : _d.age_estimation
};
callback({ status: FaceStatuses.WASM_RESPONSE, returnValue: returnData });
// }
}
};
export const scanDocumentWithOcr = (callback = () => { }, image, config = null, canvasSize = {}) => __awaiter(void 0, void 0, void 0, function* () {
printLogs('________________ DOCUMENT SCAN ______________', '', debugType);
const videoEl = document.getElementById(videoElement);
let configuration = {
document_auto_rotation: false,
input_image_format: 'rgba',
};
if (config) {
configuration = Object.assign(Object.assign({}, configuration), config);
}
privid_wasm_result = createCallbackFrontOcr(callback);
if (!videoElement || !videoEl) {
printLogs('capture need the video element id', '', debugType, LOGTYPE.ERROR);
return { result: 'error' };
}
let height = (can