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