@jaak.ai/stamps 2.0.0-dev.52 → 2.0.0-dev.54
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/dist/cjs/jaak-stamps.cjs.entry.js +159 -22
- package/dist/cjs/jaak-stamps.cjs.entry.js.map +1 -1
- package/dist/cjs/jaak-stamps.entry.cjs.js.map +1 -1
- package/dist/collection/services/CameraService.js +158 -21
- package/dist/collection/services/CameraService.js.map +1 -1
- package/dist/collection/services/DetectionService.js +1 -1
- package/dist/collection/services/DetectionService.js.map +1 -1
- package/dist/components/jaak-stamps.js +159 -22
- package/dist/components/jaak-stamps.js.map +1 -1
- package/dist/esm/jaak-stamps.entry.js +159 -22
- package/dist/esm/jaak-stamps.entry.js.map +1 -1
- package/dist/jaak-stamps-webcomponent/jaak-stamps-webcomponent.esm.js +1 -1
- package/dist/jaak-stamps-webcomponent/jaak-stamps.entry.esm.js.map +1 -1
- package/dist/jaak-stamps-webcomponent/p-9ed19fa4.entry.js +2 -0
- package/dist/jaak-stamps-webcomponent/p-9ed19fa4.entry.js.map +1 -0
- package/dist/types/services/CameraService.d.ts +1 -0
- package/package.json +1 -1
- package/dist/jaak-stamps-webcomponent/p-ffb29fbd.entry.js +0 -2
- package/dist/jaak-stamps-webcomponent/p-ffb29fbd.entry.js.map +0 -1
|
@@ -201,6 +201,7 @@ class CameraService {
|
|
|
201
201
|
deviceType = 'desktop';
|
|
202
202
|
preferredCameraFacing = null;
|
|
203
203
|
preferredCamera = 'auto';
|
|
204
|
+
isManuallySelected = false;
|
|
204
205
|
constructor(logger, eventBus, preferredCamera = 'auto') {
|
|
205
206
|
this.logger = logger;
|
|
206
207
|
this.eventBus = eventBus;
|
|
@@ -247,6 +248,11 @@ class CameraService {
|
|
|
247
248
|
}))
|
|
248
249
|
});
|
|
249
250
|
this.setInitialCameraPreference();
|
|
251
|
+
this.logger.state('PREFERENCIA_INICIAL_APLICADA', {
|
|
252
|
+
selectedCameraId: this.selectedCameraId,
|
|
253
|
+
preferredCameraFacing: this.preferredCameraFacing,
|
|
254
|
+
preferredCamera: this.preferredCamera
|
|
255
|
+
});
|
|
250
256
|
this.eventBus.emit('camera-changed', this.selectedCameraId);
|
|
251
257
|
return this.availableCameras;
|
|
252
258
|
}
|
|
@@ -272,6 +278,7 @@ class CameraService {
|
|
|
272
278
|
}
|
|
273
279
|
this.selectedCameraId = cameraId;
|
|
274
280
|
this.updatePreferredFacing(camera);
|
|
281
|
+
this.isManuallySelected = true; // Mark as manually selected
|
|
275
282
|
this.savePreference();
|
|
276
283
|
this.eventBus.emit('camera-changed', cameraId);
|
|
277
284
|
}
|
|
@@ -279,12 +286,31 @@ class CameraService {
|
|
|
279
286
|
return this.preferredCameraFacing;
|
|
280
287
|
}
|
|
281
288
|
async setupCamera(constraints) {
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
289
|
+
try {
|
|
290
|
+
const finalConstraints = constraints || await this.getMaxResolution();
|
|
291
|
+
const stream = await navigator.mediaDevices.getUserMedia({
|
|
292
|
+
video: finalConstraints,
|
|
293
|
+
audio: false
|
|
294
|
+
});
|
|
295
|
+
return stream;
|
|
296
|
+
}
|
|
297
|
+
catch (error) {
|
|
298
|
+
this.logger.error('Error en setupCamera, intentando con restricciones básicas:', error);
|
|
299
|
+
// Fallback to basic constraints if getMaxResolution fails
|
|
300
|
+
const basicConstraints = {
|
|
301
|
+
width: { ideal: 1280 },
|
|
302
|
+
height: { ideal: 720 }
|
|
303
|
+
};
|
|
304
|
+
// Only add facingMode if not on desktop to avoid OverconstrainedError
|
|
305
|
+
if (this.deviceType !== 'desktop' && this.preferredCameraFacing) {
|
|
306
|
+
basicConstraints.facingMode = this.preferredCameraFacing;
|
|
307
|
+
}
|
|
308
|
+
this.logger.state('USANDO_RESTRICCIONES_BASICAS', { constraints: basicConstraints });
|
|
309
|
+
return await navigator.mediaDevices.getUserMedia({
|
|
310
|
+
video: basicConstraints,
|
|
311
|
+
audio: false
|
|
312
|
+
});
|
|
313
|
+
}
|
|
288
314
|
}
|
|
289
315
|
async switchCamera(cameraId) {
|
|
290
316
|
const selectedCamera = this.availableCameras.find(cam => cam.deviceId === cameraId);
|
|
@@ -296,7 +322,8 @@ class CameraService {
|
|
|
296
322
|
await this.setSelectedCamera(cameraId);
|
|
297
323
|
this.logger.state('CAMARA_CAMBIADA', {
|
|
298
324
|
label: selectedCamera.label,
|
|
299
|
-
deviceId: selectedCamera.deviceId
|
|
325
|
+
deviceId: selectedCamera.deviceId,
|
|
326
|
+
isManuallySelected: this.isManuallySelected
|
|
300
327
|
});
|
|
301
328
|
}
|
|
302
329
|
async flipToNextCamera() {
|
|
@@ -378,6 +405,13 @@ class CameraService {
|
|
|
378
405
|
setInitialCameraPreference() {
|
|
379
406
|
if (this.availableCameras.length === 0)
|
|
380
407
|
return;
|
|
408
|
+
// Clear any existing localStorage preferences to ensure fresh start
|
|
409
|
+
localStorage.removeItem('jaak-stamps-camera-preference');
|
|
410
|
+
this.logger.state('APLICANDO_PREFERENCIA_INICIAL', {
|
|
411
|
+
preferredCamera: this.preferredCamera,
|
|
412
|
+
availableCamerasCount: this.availableCameras.length
|
|
413
|
+
});
|
|
414
|
+
this.isManuallySelected = false; // Reset manual selection flag
|
|
381
415
|
if (this.preferredCamera === 'front') {
|
|
382
416
|
this.selectFrontCamera();
|
|
383
417
|
}
|
|
@@ -390,23 +424,56 @@ class CameraService {
|
|
|
390
424
|
}
|
|
391
425
|
selectFrontCamera() {
|
|
392
426
|
this.preferredCameraFacing = 'user';
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
427
|
+
this.logger.state('BUSCANDO_CAMARA_FRONTAL', {
|
|
428
|
+
availableCameras: this.availableCameras.map(cam => ({
|
|
429
|
+
id: cam.deviceId,
|
|
430
|
+
label: cam.label
|
|
431
|
+
}))
|
|
432
|
+
});
|
|
433
|
+
const frontCamera = this.availableCameras.find(camera => {
|
|
434
|
+
const label = camera.label.toLowerCase();
|
|
435
|
+
return label.includes('front') ||
|
|
436
|
+
label.includes('user') ||
|
|
437
|
+
label.includes('selfie') ||
|
|
438
|
+
label.includes('frontal') ||
|
|
439
|
+
(!label.includes('back') && !label.includes('rear') && !label.includes('environment'));
|
|
440
|
+
});
|
|
441
|
+
// If not found, use the first camera (usually front on mobile)
|
|
397
442
|
this.selectedCameraId = frontCamera ? frontCamera.deviceId : this.availableCameras[0].deviceId;
|
|
398
443
|
this.logger.state('CAMARA_FRONTAL_SELECCIONADA', {
|
|
444
|
+
found: !!frontCamera,
|
|
399
445
|
label: frontCamera?.label || this.availableCameras[0].label,
|
|
400
446
|
deviceId: this.selectedCameraId
|
|
401
447
|
});
|
|
402
448
|
}
|
|
403
449
|
selectBackCamera() {
|
|
404
450
|
this.preferredCameraFacing = 'environment';
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
451
|
+
this.logger.state('BUSCANDO_CAMARA_TRASERA', {
|
|
452
|
+
availableCameras: this.availableCameras.map(cam => ({
|
|
453
|
+
id: cam.deviceId,
|
|
454
|
+
label: cam.label
|
|
455
|
+
}))
|
|
456
|
+
});
|
|
457
|
+
// Try to find rear camera with multiple detection methods
|
|
458
|
+
let backCamera = this.availableCameras.find(camera => {
|
|
459
|
+
const label = camera.label.toLowerCase();
|
|
460
|
+
return label.includes('back') ||
|
|
461
|
+
label.includes('rear') ||
|
|
462
|
+
label.includes('environment') ||
|
|
463
|
+
label.includes('trasera') ||
|
|
464
|
+
label.includes('posterior');
|
|
465
|
+
});
|
|
466
|
+
// If not found by label, try to use the last camera (usually rear on mobile)
|
|
467
|
+
if (!backCamera && this.availableCameras.length > 1) {
|
|
468
|
+
backCamera = this.availableCameras[this.availableCameras.length - 1];
|
|
469
|
+
this.logger.state('USANDO_ULTIMA_CAMARA_COMO_TRASERA', {
|
|
470
|
+
label: backCamera.label,
|
|
471
|
+
deviceId: backCamera.deviceId
|
|
472
|
+
});
|
|
473
|
+
}
|
|
408
474
|
this.selectedCameraId = backCamera ? backCamera.deviceId : this.availableCameras[0].deviceId;
|
|
409
475
|
this.logger.state('CAMARA_TRASERA_SELECCIONADA', {
|
|
476
|
+
found: !!backCamera,
|
|
410
477
|
label: backCamera?.label || this.availableCameras[0].label,
|
|
411
478
|
deviceId: this.selectedCameraId
|
|
412
479
|
});
|
|
@@ -417,8 +484,10 @@ class CameraService {
|
|
|
417
484
|
this.logger.state('CAMARA_AUTO_SELECCIONADA_MOBILE', { type: 'rear' });
|
|
418
485
|
}
|
|
419
486
|
else {
|
|
420
|
-
|
|
487
|
+
// For desktop, prefer front camera (usually built-in webcam)
|
|
488
|
+
this.selectFrontCamera();
|
|
421
489
|
this.logger.state('CAMARA_AUTO_SELECCIONADA_DESKTOP', {
|
|
490
|
+
type: 'front',
|
|
422
491
|
label: this.availableCameras[0].label,
|
|
423
492
|
deviceId: this.selectedCameraId
|
|
424
493
|
});
|
|
@@ -432,15 +501,60 @@ class CameraService {
|
|
|
432
501
|
}
|
|
433
502
|
async getMaxResolution() {
|
|
434
503
|
try {
|
|
504
|
+
// Ensure device type is detected before determining constraints
|
|
505
|
+
if (!this.deviceType || this.deviceType === 'desktop') {
|
|
506
|
+
await this.detectDeviceType();
|
|
507
|
+
}
|
|
435
508
|
const videoConstraints = {};
|
|
436
|
-
|
|
509
|
+
this.logger.state('CONFIGURANDO_CONSTRAINS_CAMARA', {
|
|
510
|
+
selectedCameraId: this.selectedCameraId,
|
|
511
|
+
preferredCameraFacing: this.preferredCameraFacing,
|
|
512
|
+
preferredCamera: this.preferredCamera,
|
|
513
|
+
deviceType: this.deviceType,
|
|
514
|
+
isManuallySelected: this.isManuallySelected
|
|
515
|
+
});
|
|
516
|
+
if (this.isManuallySelected && this.selectedCameraId) {
|
|
517
|
+
// When manually selected, use deviceId for exact camera selection
|
|
437
518
|
videoConstraints.deviceId = { exact: this.selectedCameraId };
|
|
519
|
+
this.logger.state('USANDO_CAMARA_MANUAL', {
|
|
520
|
+
deviceId: this.selectedCameraId
|
|
521
|
+
});
|
|
438
522
|
}
|
|
439
523
|
else if (this.preferredCameraFacing) {
|
|
440
|
-
|
|
524
|
+
// Use facingMode for initial preference-based selection
|
|
525
|
+
// Use 'ideal' instead of 'exact' to avoid OverconstrainedError on desktop
|
|
526
|
+
const facingConstraint = this.deviceType === 'desktop'
|
|
527
|
+
? { ideal: this.preferredCameraFacing }
|
|
528
|
+
: { exact: this.preferredCameraFacing };
|
|
529
|
+
videoConstraints.facingMode = facingConstraint;
|
|
530
|
+
this.logger.state('USANDO_FACING_CONSTRAINT', {
|
|
531
|
+
facingMode: this.preferredCameraFacing,
|
|
532
|
+
constraintType: this.deviceType === 'desktop' ? 'ideal' : 'exact'
|
|
533
|
+
});
|
|
534
|
+
}
|
|
535
|
+
else if (this.selectedCameraId) {
|
|
536
|
+
videoConstraints.deviceId = { exact: this.selectedCameraId };
|
|
537
|
+
this.logger.state('USANDO_CAMARA_SELECCIONADA', {
|
|
538
|
+
deviceId: this.selectedCameraId
|
|
539
|
+
});
|
|
441
540
|
}
|
|
442
541
|
else {
|
|
443
|
-
|
|
542
|
+
// Use preferredCamera setting to determine default facing mode
|
|
543
|
+
if (this.preferredCamera === 'front') {
|
|
544
|
+
videoConstraints.facingMode = "user";
|
|
545
|
+
}
|
|
546
|
+
else if (this.preferredCamera === 'back') {
|
|
547
|
+
videoConstraints.facingMode = "environment";
|
|
548
|
+
}
|
|
549
|
+
else {
|
|
550
|
+
// Auto mode: use environment for mobile/tablet, user for desktop
|
|
551
|
+
videoConstraints.facingMode = (this.deviceType === 'mobile' || this.deviceType === 'tablet') ? "environment" : "user";
|
|
552
|
+
}
|
|
553
|
+
this.logger.state('USANDO_PREFERENCIA_CONFIGURADA', {
|
|
554
|
+
facingMode: videoConstraints.facingMode,
|
|
555
|
+
preferredCamera: this.preferredCamera,
|
|
556
|
+
deviceType: this.deviceType
|
|
557
|
+
});
|
|
444
558
|
}
|
|
445
559
|
const tempStream = await navigator.mediaDevices.getUserMedia({
|
|
446
560
|
video: videoConstraints
|
|
@@ -472,6 +586,10 @@ class CameraService {
|
|
|
472
586
|
}
|
|
473
587
|
catch (err) {
|
|
474
588
|
this.logger.warn('No se pudieron obtener capacidades de cámara, usando configuración de respaldo');
|
|
589
|
+
// Ensure device type is detected before determining constraints
|
|
590
|
+
if (!this.deviceType || this.deviceType === 'desktop') {
|
|
591
|
+
await this.detectDeviceType();
|
|
592
|
+
}
|
|
475
593
|
const isTablet = /iPad|Android/i.test(navigator.userAgent) && window.innerWidth >= 768;
|
|
476
594
|
const fallbackConstraints = {
|
|
477
595
|
width: { ideal: isTablet ? 1280 : 1920 },
|
|
@@ -479,14 +597,33 @@ class CameraService {
|
|
|
479
597
|
};
|
|
480
598
|
// Apply basic focus settings even for fallback
|
|
481
599
|
this.applyBasicFocusSettings(fallbackConstraints);
|
|
482
|
-
if (this.selectedCameraId) {
|
|
600
|
+
if (this.isManuallySelected && this.selectedCameraId) {
|
|
601
|
+
// When manually selected, use deviceId for exact camera selection
|
|
483
602
|
fallbackConstraints.deviceId = { exact: this.selectedCameraId };
|
|
484
603
|
}
|
|
485
604
|
else if (this.preferredCameraFacing) {
|
|
486
|
-
|
|
605
|
+
// Use facingMode for initial preference-based selection
|
|
606
|
+
// Use 'ideal' instead of 'exact' to avoid OverconstrainedError on desktop
|
|
607
|
+
const facingConstraint = this.deviceType === 'desktop'
|
|
608
|
+
? { ideal: this.preferredCameraFacing }
|
|
609
|
+
: { exact: this.preferredCameraFacing };
|
|
610
|
+
fallbackConstraints.facingMode = facingConstraint;
|
|
611
|
+
}
|
|
612
|
+
else if (this.selectedCameraId) {
|
|
613
|
+
fallbackConstraints.deviceId = { exact: this.selectedCameraId };
|
|
487
614
|
}
|
|
488
615
|
else {
|
|
489
|
-
|
|
616
|
+
// Use preferredCamera setting to determine default facing mode
|
|
617
|
+
if (this.preferredCamera === 'front') {
|
|
618
|
+
fallbackConstraints.facingMode = "user";
|
|
619
|
+
}
|
|
620
|
+
else if (this.preferredCamera === 'back') {
|
|
621
|
+
fallbackConstraints.facingMode = "environment";
|
|
622
|
+
}
|
|
623
|
+
else {
|
|
624
|
+
// Auto mode: use environment for mobile/tablet, user for desktop
|
|
625
|
+
fallbackConstraints.facingMode = (this.deviceType === 'mobile' || this.deviceType === 'tablet') ? "environment" : "user";
|
|
626
|
+
}
|
|
490
627
|
}
|
|
491
628
|
return fallbackConstraints;
|
|
492
629
|
}
|
|
@@ -730,7 +867,7 @@ class DetectionService {
|
|
|
730
867
|
modelLoaded = false;
|
|
731
868
|
deviceStrategy;
|
|
732
869
|
MODEL_PATH = "https://storage.googleapis.com/jaak-static/web/component/stamps/ddmyp-v2.onnx";
|
|
733
|
-
MOBILENET_MODEL_PATH = "https://storage.googleapis.com/jaak-static/web/component/stamps/
|
|
870
|
+
MOBILENET_MODEL_PATH = "https://storage.googleapis.com/jaak-static/web/component/stamps/squeezenet_new_fp32.onnx";
|
|
734
871
|
MOBILENET_CLASSES_PATH = "https://storage.googleapis.com/jaak-static/web/component/stamps/cdmmp-v1.json";
|
|
735
872
|
INPUT_SIZE = 320;
|
|
736
873
|
CONFIDENCE_THRESHOLD = 0.6;
|