@utamuratov/ngx-face-id 0.4.1 → 0.4.2

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.
@@ -287,7 +287,7 @@ class NgxFaceLiveness {
287
287
  <p class="hint">{{ stepText() }}</p>
288
288
  </div>
289
289
  </div>
290
- `, isInline: true, styles: [":host{display:flex;align-items:center;justify-content:center;height:100vh;padding:1rem}.camera-wrapper{position:relative;width:100%;max-width:480px;aspect-ratio:3/4;margin:auto;overflow:hidden;border-radius:1rem;background:#65a0f8}.camera-video{width:100%;border-radius:12px}.overlay{position:absolute;inset:0;pointer-events:none;display:flex;flex-direction:column;align-items:center;justify-content:center}.oval-mask{width:80%;aspect-ratio:5/6;border-radius:50%;border:4px dashed #65a0f8;background:transparent;box-shadow:0 0 0 9999px #0009}.hint{margin-top:12px;color:#fff;font-size:14px;text-align:center;position:absolute;top:5px;background-color:#0000007a;padding:2px 4px;border-radius:5px}.captured-image{position:absolute;top:0;left:0;width:100%;height:100%;object-fit:cover;border-radius:12px}\n"] });
290
+ `, isInline: true, styles: [":host{display:flex;align-items:center;justify-content:center;height:100vh;padding:1rem}.camera-wrapper{position:relative;width:100%;max-width:480px;aspect-ratio:3/4;margin:auto;overflow:hidden;border-radius:1rem;background:#65a0f8}.camera-video{width:100%;height:100%;border-radius:12px}.overlay{position:absolute;inset:0;pointer-events:none;display:flex;flex-direction:column;align-items:center;justify-content:center}.oval-mask{width:80%;aspect-ratio:5/6;border-radius:50%;border:4px dashed #65a0f8;background:transparent;box-shadow:0 0 0 9999px #0009}.hint{margin-top:12px;color:#fff;font-size:14px;text-align:center;position:absolute;top:5px;background-color:#0000007a;padding:2px 4px;border-radius:5px}.captured-image{position:absolute;top:0;left:0;width:100%;height:100%;object-fit:cover;border-radius:12px}\n"] });
291
291
  }
292
292
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NgxFaceLiveness, decorators: [{
293
293
  type: Component,
@@ -304,7 +304,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
304
304
  <p class="hint">{{ stepText() }}</p>
305
305
  </div>
306
306
  </div>
307
- `, styles: [":host{display:flex;align-items:center;justify-content:center;height:100vh;padding:1rem}.camera-wrapper{position:relative;width:100%;max-width:480px;aspect-ratio:3/4;margin:auto;overflow:hidden;border-radius:1rem;background:#65a0f8}.camera-video{width:100%;border-radius:12px}.overlay{position:absolute;inset:0;pointer-events:none;display:flex;flex-direction:column;align-items:center;justify-content:center}.oval-mask{width:80%;aspect-ratio:5/6;border-radius:50%;border:4px dashed #65a0f8;background:transparent;box-shadow:0 0 0 9999px #0009}.hint{margin-top:12px;color:#fff;font-size:14px;text-align:center;position:absolute;top:5px;background-color:#0000007a;padding:2px 4px;border-radius:5px}.captured-image{position:absolute;top:0;left:0;width:100%;height:100%;object-fit:cover;border-radius:12px}\n"] }]
307
+ `, styles: [":host{display:flex;align-items:center;justify-content:center;height:100vh;padding:1rem}.camera-wrapper{position:relative;width:100%;max-width:480px;aspect-ratio:3/4;margin:auto;overflow:hidden;border-radius:1rem;background:#65a0f8}.camera-video{width:100%;height:100%;border-radius:12px}.overlay{position:absolute;inset:0;pointer-events:none;display:flex;flex-direction:column;align-items:center;justify-content:center}.oval-mask{width:80%;aspect-ratio:5/6;border-radius:50%;border:4px dashed #65a0f8;background:transparent;box-shadow:0 0 0 9999px #0009}.hint{margin-top:12px;color:#fff;font-size:14px;text-align:center;position:absolute;top:5px;background-color:#0000007a;padding:2px 4px;border-radius:5px}.captured-image{position:absolute;top:0;left:0;width:100%;height:100%;object-fit:cover;border-radius:12px}\n"] }]
308
308
  }], ctorParameters: () => [{ type: LivenessService }], propDecorators: { videoRef: [{
309
309
  type: ViewChild,
310
310
  args: ['video']
@@ -1 +1 @@
1
- {"version":3,"file":"utamuratov-ngx-face-id.mjs","sources":["../../../projects/ngx-face-id/src/lib/face-liveness/liveness.service.ts","../../../projects/ngx-face-id/src/lib/face-liveness/face-liveness.ts","../../../projects/ngx-face-id/src/public-api.ts","../../../projects/ngx-face-id/src/utamuratov-ngx-face-id.ts"],"sourcesContent":["import { computed, Injectable, signal } from '@angular/core';\nimport * as faceapi from 'face-api.js';\n\ntype Step = 'BLINK' | 'MOUTH' | 'HEAD' | 'HOLD' | 'DONE';\n\ntype FaceInside = 'NO_FACE' | 'OUTSIDE_OVAL' | 'COME_CLOSE' | 'VERY_CLOSE' | 'VALID';\n\n@Injectable({ providedIn: 'root' })\nexport class LivenessService {\n private step = signal<Step>('BLINK');\n private faceInsideStatus = signal<FaceInside>('OUTSIDE_OVAL');\n currentStep = computed(() => this.step());\n currentFaceInsideStatus = computed(() => this.faceInsideStatus());\n\n private prevBlinkAvg = 0;\n private blinkCount = 0;\n private prevNoseX?: number;\n private holdStart?: number;\n\n async loadModels() {\n const MODEL_URL = '/models';\n await Promise.all([\n faceapi.nets.tinyFaceDetector.loadFromUri(MODEL_URL),\n faceapi.nets.faceLandmark68Net.loadFromUri(MODEL_URL),\n faceapi.nets.faceRecognitionNet.loadFromUri(MODEL_URL),\n ]);\n }\n\n reset() {\n this.faceInsideStatus.set('OUTSIDE_OVAL');\n this.step.set('BLINK');\n this.blinkCount = 0;\n this.prevBlinkAvg = 0;\n this.prevNoseX = undefined;\n this.holdStart = undefined;\n }\n\n // ---------- HELPERS ----------\n\n private isFaceInsideOval(box: faceapi.Box, video: HTMLVideoElement): boolean {\n const vw = video.videoWidth;\n const vh = video.videoHeight;\n\n // Oval markazi\n const cx = vw / 2;\n const cy = vh / 2;\n\n // Oval radius (x va y o'qlari bo'yicha)\n // CSS: width = 80% → radius = 40%\n const rx = vw * 0.4;\n const ry = rx * (6 / 5); // aspect-ratio: 5/6\n\n // 1️⃣ Face edge points\n const points = [\n { x: box.x, y: box.y + box.height / 2 }, // left\n { x: box.x + box.width, y: box.y + box.height / 2 }, // right\n { x: box.x + box.width / 2, y: box.y }, // top\n { x: box.x + box.width / 2, y: box.y + box.height }, // bottom\n ];\n\n const inside = points.every((p) => {\n const v = Math.pow((p.x - cx) / rx, 2) + Math.pow((p.y - cy) / ry, 2);\n return v <= 1.1;\n });\n\n if (!inside) {\n this.faceInsideStatus.set('OUTSIDE_OVAL');\n return false;\n }\n\n // 2️⃣ Fill ratio\n const faceArea = box.width * box.height;\n const ovalArea = Math.PI * rx * ry;\n const fillRatio = faceArea / ovalArea;\n\n if (fillRatio < 0.42) {\n this.faceInsideStatus.set('COME_CLOSE');\n return false;\n }\n\n if (fillRatio > 0.6) {\n this.faceInsideStatus.set('VERY_CLOSE');\n return false;\n }\n\n this.faceInsideStatus.set('VALID');\n return true;\n }\n\n private dist(a: any, b: any) {\n return Math.hypot(a.x - b.x, a.y - b.y);\n }\n\n private eyeEAR(eye: faceapi.Point[]) {\n return (\n (this.dist(eye[1], eye[5]) + this.dist(eye[2], eye[4])) / (2 * this.dist(eye[0], eye[3]))\n );\n }\n\n private isBlink(lm: faceapi.FaceLandmarks68) {\n const left = this.eyeEAR(lm.getLeftEye());\n const right = this.eyeEAR(lm.getRightEye());\n const avg = (left + right) / 2;\n\n if (this.prevBlinkAvg === 0 || Math.abs(avg - this.prevBlinkAvg) < 0.01) {\n this.prevBlinkAvg = avg;\n return false;\n }\n\n this.prevBlinkAvg = avg;\n this.blinkCount++;\n return this.blinkCount > 2;\n }\n\n private isMouthOpen(lm: faceapi.FaceLandmarks68) {\n const mouth = lm.getMouth();\n return this.dist(mouth[13], mouth[19]) / this.dist(mouth[0], mouth[6]) > 0.4;\n }\n\n private isHeadMoved(lm: faceapi.FaceLandmarks68) {\n const nose = lm.getNose()[3];\n if (!this.prevNoseX) {\n this.prevNoseX = nose.x;\n return false;\n }\n const moved = Math.abs(nose.x - this.prevNoseX) > 30;\n\n this.prevNoseX = nose.x;\n return moved;\n }\n\n // ---------- MAIN CHECK ----------\n\n async process(video: HTMLVideoElement): Promise<boolean> {\n const result = await faceapi\n .detectSingleFace(video, new faceapi.TinyFaceDetectorOptions())\n .withFaceLandmarks();\n\n if (!result) {\n this.faceInsideStatus.set('NO_FACE');\n return false;\n }\n\n // 👇 OVAL CHECK\n const insideOval = this.isFaceInsideOval(result.detection.box, video);\n\n if (!insideOval) {\n if (this.step() === 'HOLD') {\n this.holdStart = Date.now();\n }\n return false;\n }\n\n const lm = result.landmarks;\n\n if (this.step() === 'BLINK' && this.isBlink(lm)) {\n this.step.set('MOUTH');\n } else if (this.step() === 'MOUTH' && this.isMouthOpen(lm)) {\n this.step.set('HEAD');\n } else if (this.step() === 'HEAD' && this.isHeadMoved(lm)) {\n this.step.set('HOLD');\n this.holdStart = Date.now();\n } else if (this.step() === 'HOLD') {\n if (!this.holdStart) this.holdStart = Date.now();\n if (Date.now() - this.holdStart > 3000) {\n this.step.set('DONE');\n return true; // 📸 CAPTURE SIGNAL\n }\n }\n\n return false;\n }\n}\n","import {\n Component,\n ElementRef,\n ViewChild,\n OnInit,\n computed,\n output,\n inject,\n PLATFORM_ID,\n signal,\n} from '@angular/core';\nimport { LivenessService } from './liveness.service';\nimport { isPlatformBrowser } from '@angular/common';\n\n@Component({\n selector: 'ngx-face-liveness',\n template: `\n <div class=\"camera-wrapper\">\n @if (capturesImageSrc()) {\n <img [src]=\"capturesImageSrc()\" alt=\"Captured Image\" class=\"captured-image\" />\n }\n <video #video autoplay muted playsinline class=\"camera-video\"></video>\n\n <!-- Overlay -->\n <div class=\"overlay\">\n <div class=\"oval-mask\" [style.borderColor]=\"isNotValidOval() ? '#fb2c36' : '#65a0f8'\"></div>\n <p class=\"hint\">{{ stepText() }}</p>\n </div>\n </div>\n `,\n styleUrls: ['./face-liveness.scss'],\n})\nexport class NgxFaceLiveness implements OnInit {\n private platformId = inject(PLATFORM_ID);\n private isBrowser = isPlatformBrowser(this.platformId);\n\n @ViewChild('video') videoRef!: ElementRef<HTMLVideoElement>;\n intervalId: any;\n\n capturedImage = output<Blob>();\n capturesImageSrc = signal<string | null>(null);\n\n constructor(private liveness: LivenessService) {}\n\n async ngOnInit() {\n if (!this.isBrowser) return;\n\n await this.liveness.loadModels();\n await this.start();\n }\n\n currentStep = computed(() => this.liveness.currentStep());\n currentFaceInsideStatus = computed(() => this.liveness.currentFaceInsideStatus());\n isNotValidOval = computed(\n () =>\n this.currentFaceInsideStatus() === 'OUTSIDE_OVAL' ||\n this.currentFaceInsideStatus() === 'NO_FACE',\n );\n stepText = computed(() => {\n const currentFaceStatus = this.currentFaceInsideStatus();\n\n if (currentFaceStatus === 'NO_FACE') {\n return '❌ Yuz aniqlanmadi, iltimos, kameraga qarang';\n }\n if (currentFaceStatus === 'OUTSIDE_OVAL') {\n return '📐 Iltimos, yuzingizni oval ichiga joylashtiring';\n }\n if (currentFaceStatus === 'COME_CLOSE') {\n return '🔍 Iltimos, kameraga yaqinroq turing';\n }\n if (currentFaceStatus === 'VERY_CLOSE') {\n return '📷 Juda yaqin, kamerani orqaroq oling';\n }\n\n switch (this.currentStep()) {\n case 'BLINK':\n return '👁 Ko‘zingizni yumib oching(2 marta)';\n case 'MOUTH':\n return '🙂 Og‘zingizni ochib yuming';\n case 'HEAD':\n return '↔️ Boshni chapga yoki o‘ngga burang';\n case 'HOLD':\n return '✋ Barqaror turing (2 soniya)';\n default:\n return '✅ Tayyor!';\n }\n });\n\n async start() {\n this.liveness.reset();\n await this.openCamera();\n\n this.intervalId = setInterval(async () => {\n const done = await this.liveness.process(this.videoRef.nativeElement);\n\n if (done) {\n clearInterval(this.intervalId);\n const blob = await this.capture();\n this.sendToBackend(blob);\n }\n }, 300);\n }\n\n async openCamera() {\n try {\n const devices = await navigator.mediaDevices.enumerateDevices();\n const videoDevices = devices.filter((d) => d.kind === 'videoinput');\n\n if (!videoDevices.length) {\n throw new Error('No video devices found');\n }\n\n // USB yoki default camera tanlash\n const stream = await navigator.mediaDevices.getUserMedia({\n video: {\n deviceId: videoDevices[0].deviceId,\n aspectRatio: 3 / 4,\n width: { min: 480 },\n height: { min: 640 },\n }, // birinchi topilgan kamera\n });\n\n this.videoRef.nativeElement.srcObject = stream;\n } catch (err) {\n console.error('Cannot access camera:', err);\n }\n\n // const stream = await navigator.mediaDevices.getUserMedia({\n // video: { facingMode: 'user', aspectRatio: 3 / 4, width: { min: 480 }, height: { min: 640 } },\n // });\n // this.videoRef.nativeElement.srcObject = stream;\n }\n\n async capture(): Promise<Blob> {\n const video = this.videoRef.nativeElement;\n const canvas = document.createElement('canvas');\n\n canvas.width = video.videoWidth;\n canvas.height = video.videoHeight;\n\n canvas.getContext('2d')!.drawImage(video, 0, 0);\n\n return new Promise((res) => canvas.toBlob((b) => res(b!), 'image/jpeg', 0.9));\n }\n\n sendToBackend(blob: Blob) {\n this.capturedImage.emit(blob);\n this.capturesImageSrc.set(URL.createObjectURL(blob));\n console.log(blob);\n\n // const fd = new FormData();\n // fd.append('file', blob, 'face.jpg');\n // this.http.post('/api/face/verify', fd).subscribe();\n }\n\n ngOnDestroy(): void {\n if (!this.isBrowser) return;\n\n this.cleanup();\n }\n\n private cleanup() {\n // 1️⃣ Interval\n if (this.intervalId) {\n clearInterval(this.intervalId);\n this.intervalId = null;\n }\n\n // 2️⃣ Kamera\n const video = this.videoRef?.nativeElement;\n if (video) {\n video.pause();\n\n const stream = video.srcObject as MediaStream | null;\n if (stream) {\n stream.getTracks().forEach((track) => track.stop());\n }\n\n video.srcObject = null;\n }\n\n // 3️⃣ Service state\n this.liveness.reset();\n }\n}\n","/*\r\n * Public API Surface of ngx-face-id\r\n */\r\n\r\nexport * from './lib/face-liveness/face-liveness';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1.LivenessService"],"mappings":"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"}
1
+ {"version":3,"file":"utamuratov-ngx-face-id.mjs","sources":["../../../projects/ngx-face-id/src/lib/face-liveness/liveness.service.ts","../../../projects/ngx-face-id/src/lib/face-liveness/face-liveness.ts","../../../projects/ngx-face-id/src/public-api.ts","../../../projects/ngx-face-id/src/utamuratov-ngx-face-id.ts"],"sourcesContent":["import { computed, Injectable, signal } from '@angular/core';\nimport * as faceapi from 'face-api.js';\n\ntype Step = 'BLINK' | 'MOUTH' | 'HEAD' | 'HOLD' | 'DONE';\n\ntype FaceInside = 'NO_FACE' | 'OUTSIDE_OVAL' | 'COME_CLOSE' | 'VERY_CLOSE' | 'VALID';\n\n@Injectable({ providedIn: 'root' })\nexport class LivenessService {\n private step = signal<Step>('BLINK');\n private faceInsideStatus = signal<FaceInside>('OUTSIDE_OVAL');\n currentStep = computed(() => this.step());\n currentFaceInsideStatus = computed(() => this.faceInsideStatus());\n\n private prevBlinkAvg = 0;\n private blinkCount = 0;\n private prevNoseX?: number;\n private holdStart?: number;\n\n async loadModels() {\n const MODEL_URL = '/models';\n await Promise.all([\n faceapi.nets.tinyFaceDetector.loadFromUri(MODEL_URL),\n faceapi.nets.faceLandmark68Net.loadFromUri(MODEL_URL),\n faceapi.nets.faceRecognitionNet.loadFromUri(MODEL_URL),\n ]);\n }\n\n reset() {\n this.faceInsideStatus.set('OUTSIDE_OVAL');\n this.step.set('BLINK');\n this.blinkCount = 0;\n this.prevBlinkAvg = 0;\n this.prevNoseX = undefined;\n this.holdStart = undefined;\n }\n\n // ---------- HELPERS ----------\n\n private isFaceInsideOval(box: faceapi.Box, video: HTMLVideoElement): boolean {\n const vw = video.videoWidth;\n const vh = video.videoHeight;\n\n // Oval markazi\n const cx = vw / 2;\n const cy = vh / 2;\n\n // Oval radius (x va y o'qlari bo'yicha)\n // CSS: width = 80% → radius = 40%\n const rx = vw * 0.4;\n const ry = rx * (6 / 5); // aspect-ratio: 5/6\n\n // 1️⃣ Face edge points\n const points = [\n { x: box.x, y: box.y + box.height / 2 }, // left\n { x: box.x + box.width, y: box.y + box.height / 2 }, // right\n { x: box.x + box.width / 2, y: box.y }, // top\n { x: box.x + box.width / 2, y: box.y + box.height }, // bottom\n ];\n\n const inside = points.every((p) => {\n const v = Math.pow((p.x - cx) / rx, 2) + Math.pow((p.y - cy) / ry, 2);\n return v <= 1.1;\n });\n\n if (!inside) {\n this.faceInsideStatus.set('OUTSIDE_OVAL');\n return false;\n }\n\n // 2️⃣ Fill ratio\n const faceArea = box.width * box.height;\n const ovalArea = Math.PI * rx * ry;\n const fillRatio = faceArea / ovalArea;\n\n if (fillRatio < 0.42) {\n this.faceInsideStatus.set('COME_CLOSE');\n return false;\n }\n\n if (fillRatio > 0.6) {\n this.faceInsideStatus.set('VERY_CLOSE');\n return false;\n }\n\n this.faceInsideStatus.set('VALID');\n return true;\n }\n\n private dist(a: any, b: any) {\n return Math.hypot(a.x - b.x, a.y - b.y);\n }\n\n private eyeEAR(eye: faceapi.Point[]) {\n return (\n (this.dist(eye[1], eye[5]) + this.dist(eye[2], eye[4])) / (2 * this.dist(eye[0], eye[3]))\n );\n }\n\n private isBlink(lm: faceapi.FaceLandmarks68) {\n const left = this.eyeEAR(lm.getLeftEye());\n const right = this.eyeEAR(lm.getRightEye());\n const avg = (left + right) / 2;\n\n if (this.prevBlinkAvg === 0 || Math.abs(avg - this.prevBlinkAvg) < 0.01) {\n this.prevBlinkAvg = avg;\n return false;\n }\n\n this.prevBlinkAvg = avg;\n this.blinkCount++;\n return this.blinkCount > 2;\n }\n\n private isMouthOpen(lm: faceapi.FaceLandmarks68) {\n const mouth = lm.getMouth();\n return this.dist(mouth[13], mouth[19]) / this.dist(mouth[0], mouth[6]) > 0.4;\n }\n\n private isHeadMoved(lm: faceapi.FaceLandmarks68) {\n const nose = lm.getNose()[3];\n if (!this.prevNoseX) {\n this.prevNoseX = nose.x;\n return false;\n }\n const moved = Math.abs(nose.x - this.prevNoseX) > 30;\n\n this.prevNoseX = nose.x;\n return moved;\n }\n\n // ---------- MAIN CHECK ----------\n\n async process(video: HTMLVideoElement): Promise<boolean> {\n const result = await faceapi\n .detectSingleFace(video, new faceapi.TinyFaceDetectorOptions())\n .withFaceLandmarks();\n\n if (!result) {\n this.faceInsideStatus.set('NO_FACE');\n return false;\n }\n\n // 👇 OVAL CHECK\n const insideOval = this.isFaceInsideOval(result.detection.box, video);\n\n if (!insideOval) {\n if (this.step() === 'HOLD') {\n this.holdStart = Date.now();\n }\n return false;\n }\n\n const lm = result.landmarks;\n\n if (this.step() === 'BLINK' && this.isBlink(lm)) {\n this.step.set('MOUTH');\n } else if (this.step() === 'MOUTH' && this.isMouthOpen(lm)) {\n this.step.set('HEAD');\n } else if (this.step() === 'HEAD' && this.isHeadMoved(lm)) {\n this.step.set('HOLD');\n this.holdStart = Date.now();\n } else if (this.step() === 'HOLD') {\n if (!this.holdStart) this.holdStart = Date.now();\n if (Date.now() - this.holdStart > 3000) {\n this.step.set('DONE');\n return true; // 📸 CAPTURE SIGNAL\n }\n }\n\n return false;\n }\n}\n","import {\n Component,\n ElementRef,\n ViewChild,\n OnInit,\n computed,\n output,\n inject,\n PLATFORM_ID,\n signal,\n} from '@angular/core';\nimport { LivenessService } from './liveness.service';\nimport { isPlatformBrowser } from '@angular/common';\n\n@Component({\n selector: 'ngx-face-liveness',\n template: `\n <div class=\"camera-wrapper\">\n @if (capturesImageSrc()) {\n <img [src]=\"capturesImageSrc()\" alt=\"Captured Image\" class=\"captured-image\" />\n }\n <video #video autoplay muted playsinline class=\"camera-video\"></video>\n\n <!-- Overlay -->\n <div class=\"overlay\">\n <div class=\"oval-mask\" [style.borderColor]=\"isNotValidOval() ? '#fb2c36' : '#65a0f8'\"></div>\n <p class=\"hint\">{{ stepText() }}</p>\n </div>\n </div>\n `,\n styleUrls: ['./face-liveness.scss'],\n})\nexport class NgxFaceLiveness implements OnInit {\n private platformId = inject(PLATFORM_ID);\n private isBrowser = isPlatformBrowser(this.platformId);\n\n @ViewChild('video') videoRef!: ElementRef<HTMLVideoElement>;\n intervalId: any;\n\n capturedImage = output<Blob>();\n capturesImageSrc = signal<string | null>(null);\n\n constructor(private liveness: LivenessService) {}\n\n async ngOnInit() {\n if (!this.isBrowser) return;\n\n await this.liveness.loadModels();\n await this.start();\n }\n\n currentStep = computed(() => this.liveness.currentStep());\n currentFaceInsideStatus = computed(() => this.liveness.currentFaceInsideStatus());\n isNotValidOval = computed(\n () =>\n this.currentFaceInsideStatus() === 'OUTSIDE_OVAL' ||\n this.currentFaceInsideStatus() === 'NO_FACE',\n );\n stepText = computed(() => {\n const currentFaceStatus = this.currentFaceInsideStatus();\n\n if (currentFaceStatus === 'NO_FACE') {\n return '❌ Yuz aniqlanmadi, iltimos, kameraga qarang';\n }\n if (currentFaceStatus === 'OUTSIDE_OVAL') {\n return '📐 Iltimos, yuzingizni oval ichiga joylashtiring';\n }\n if (currentFaceStatus === 'COME_CLOSE') {\n return '🔍 Iltimos, kameraga yaqinroq turing';\n }\n if (currentFaceStatus === 'VERY_CLOSE') {\n return '📷 Juda yaqin, kamerani orqaroq oling';\n }\n\n switch (this.currentStep()) {\n case 'BLINK':\n return '👁 Ko‘zingizni yumib oching(2 marta)';\n case 'MOUTH':\n return '🙂 Og‘zingizni ochib yuming';\n case 'HEAD':\n return '↔️ Boshni chapga yoki o‘ngga burang';\n case 'HOLD':\n return '✋ Barqaror turing (2 soniya)';\n default:\n return '✅ Tayyor!';\n }\n });\n\n async start() {\n this.liveness.reset();\n await this.openCamera();\n\n this.intervalId = setInterval(async () => {\n const done = await this.liveness.process(this.videoRef.nativeElement);\n\n if (done) {\n clearInterval(this.intervalId);\n const blob = await this.capture();\n this.sendToBackend(blob);\n }\n }, 300);\n }\n\n async openCamera() {\n try {\n const devices = await navigator.mediaDevices.enumerateDevices();\n const videoDevices = devices.filter((d) => d.kind === 'videoinput');\n\n if (!videoDevices.length) {\n throw new Error('No video devices found');\n }\n\n // USB yoki default camera tanlash\n const stream = await navigator.mediaDevices.getUserMedia({\n video: {\n deviceId: videoDevices[0].deviceId,\n aspectRatio: 3 / 4,\n width: { min: 480 },\n height: { min: 640 },\n }, // birinchi topilgan kamera\n });\n\n this.videoRef.nativeElement.srcObject = stream;\n } catch (err) {\n console.error('Cannot access camera:', err);\n }\n\n // const stream = await navigator.mediaDevices.getUserMedia({\n // video: { facingMode: 'user', aspectRatio: 3 / 4, width: { min: 480 }, height: { min: 640 } },\n // });\n // this.videoRef.nativeElement.srcObject = stream;\n }\n\n async capture(): Promise<Blob> {\n const video = this.videoRef.nativeElement;\n const canvas = document.createElement('canvas');\n\n canvas.width = video.videoWidth;\n canvas.height = video.videoHeight;\n\n canvas.getContext('2d')!.drawImage(video, 0, 0);\n\n return new Promise((res) => canvas.toBlob((b) => res(b!), 'image/jpeg', 0.9));\n }\n\n sendToBackend(blob: Blob) {\n this.capturedImage.emit(blob);\n this.capturesImageSrc.set(URL.createObjectURL(blob));\n console.log(blob);\n\n // const fd = new FormData();\n // fd.append('file', blob, 'face.jpg');\n // this.http.post('/api/face/verify', fd).subscribe();\n }\n\n ngOnDestroy(): void {\n if (!this.isBrowser) return;\n\n this.cleanup();\n }\n\n private cleanup() {\n // 1️⃣ Interval\n if (this.intervalId) {\n clearInterval(this.intervalId);\n this.intervalId = null;\n }\n\n // 2️⃣ Kamera\n const video = this.videoRef?.nativeElement;\n if (video) {\n video.pause();\n\n const stream = video.srcObject as MediaStream | null;\n if (stream) {\n stream.getTracks().forEach((track) => track.stop());\n }\n\n video.srcObject = null;\n }\n\n // 3️⃣ Service state\n this.liveness.reset();\n }\n}\n","/*\r\n * Public API Surface of ngx-face-id\r\n */\r\n\r\nexport * from './lib/face-liveness/face-liveness';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1.LivenessService"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@utamuratov/ngx-face-id",
3
- "version": "0.4.1",
3
+ "version": "0.4.2",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },