@jaak.ai/stamps 2.1.0-beta.1 → 2.1.0-beta.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.
- package/dist/cjs/jaak-stamps.cjs.entry.js +109 -18
- 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/components/my-component/my-component.js +25 -16
- package/dist/collection/components/my-component/my-component.js.map +1 -1
- package/dist/collection/services/CameraService.js +84 -2
- package/dist/collection/services/CameraService.js.map +1 -1
- package/dist/components/jaak-stamps.js +109 -18
- package/dist/components/jaak-stamps.js.map +1 -1
- package/dist/esm/jaak-stamps.entry.js +109 -18
- 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-c06e5d7b.entry.js +2 -0
- package/dist/jaak-stamps-webcomponent/p-c06e5d7b.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-a76ae84d.entry.js +0 -2
- package/dist/jaak-stamps-webcomponent/p-a76ae84d.entry.js.map +0 -1
|
@@ -206,7 +206,21 @@ class CameraService {
|
|
|
206
206
|
tempStream.getTracks().forEach(track => track.stop());
|
|
207
207
|
}
|
|
208
208
|
const devices = await navigator.mediaDevices.enumerateDevices();
|
|
209
|
-
|
|
209
|
+
const allCameras = devices.filter(device => device.kind === 'videoinput');
|
|
210
|
+
// Filter out virtual cameras
|
|
211
|
+
this.availableCameras = allCameras.filter(camera => {
|
|
212
|
+
const isVirtual = this.isVirtualCamera(camera);
|
|
213
|
+
if (isVirtual) {
|
|
214
|
+
console.log(`Virtual camera detected and filtered: ${camera.label}`);
|
|
215
|
+
}
|
|
216
|
+
return !isVirtual;
|
|
217
|
+
});
|
|
218
|
+
// Check if there are physical cameras available
|
|
219
|
+
if (this.availableCameras.length === 0) {
|
|
220
|
+
console.log('No physical cameras available');
|
|
221
|
+
this.eventBus.emit('error', new Error('Cámaras virtuales no están permitidas. Use una cámara física.'));
|
|
222
|
+
return [];
|
|
223
|
+
}
|
|
210
224
|
// Cache the results for optimization
|
|
211
225
|
CameraService.deviceEnumerationCache = {
|
|
212
226
|
devices: this.availableCameras,
|
|
@@ -256,6 +270,21 @@ class CameraService {
|
|
|
256
270
|
});
|
|
257
271
|
this.lastStreamConstraints = finalConstraints;
|
|
258
272
|
const stream = await this.currentStreamPromise;
|
|
273
|
+
// Validate that active stream is not from a virtual camera
|
|
274
|
+
const videoTrack = stream.getVideoTracks()[0];
|
|
275
|
+
if (videoTrack) {
|
|
276
|
+
const settings = videoTrack.getSettings();
|
|
277
|
+
const deviceId = settings.deviceId;
|
|
278
|
+
if (deviceId) {
|
|
279
|
+
const devices = await navigator.mediaDevices.enumerateDevices();
|
|
280
|
+
const currentDevice = devices.find(device => device.deviceId === deviceId);
|
|
281
|
+
if (currentDevice && this.isVirtualCamera(currentDevice)) {
|
|
282
|
+
console.log(`Virtual camera detected in active stream: ${currentDevice.label}`);
|
|
283
|
+
stream.getTracks().forEach(track => track.stop());
|
|
284
|
+
throw new Error('Cámaras virtuales no están permitidas. Use una cámara física.');
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
259
288
|
return stream;
|
|
260
289
|
}
|
|
261
290
|
catch (error) {
|
|
@@ -273,7 +302,23 @@ class CameraService {
|
|
|
273
302
|
audio: false
|
|
274
303
|
});
|
|
275
304
|
this.lastStreamConstraints = basicConstraints;
|
|
276
|
-
|
|
305
|
+
const stream = await this.currentStreamPromise;
|
|
306
|
+
// Validate fallback stream as well
|
|
307
|
+
const videoTrack = stream.getVideoTracks()[0];
|
|
308
|
+
if (videoTrack) {
|
|
309
|
+
const settings = videoTrack.getSettings();
|
|
310
|
+
const deviceId = settings.deviceId;
|
|
311
|
+
if (deviceId) {
|
|
312
|
+
const devices = await navigator.mediaDevices.enumerateDevices();
|
|
313
|
+
const currentDevice = devices.find(device => device.deviceId === deviceId);
|
|
314
|
+
if (currentDevice && this.isVirtualCamera(currentDevice)) {
|
|
315
|
+
console.log(`Virtual camera detected in fallback stream: ${currentDevice.label}`);
|
|
316
|
+
stream.getTracks().forEach(track => track.stop());
|
|
317
|
+
throw new Error('Cámaras virtuales no están permitidas. Use una cámara física.');
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
return stream;
|
|
277
322
|
}
|
|
278
323
|
}
|
|
279
324
|
async switchCamera(cameraId) {
|
|
@@ -282,6 +327,12 @@ class CameraService {
|
|
|
282
327
|
await this.enumerateDevices();
|
|
283
328
|
return;
|
|
284
329
|
}
|
|
330
|
+
// Validate that the target camera is not virtual
|
|
331
|
+
if (this.isVirtualCamera(selectedCamera)) {
|
|
332
|
+
console.log(`Attempted to switch to virtual camera: ${selectedCamera.label}`);
|
|
333
|
+
this.eventBus.emit('error', new Error('No se puede cambiar a cámara virtual'));
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
285
336
|
await this.setSelectedCamera(cameraId);
|
|
286
337
|
}
|
|
287
338
|
isRearCamera(stream) {
|
|
@@ -553,6 +604,37 @@ class CameraService {
|
|
|
553
604
|
invalidateDeviceCache() {
|
|
554
605
|
CameraService.deviceEnumerationCache = null;
|
|
555
606
|
}
|
|
607
|
+
isVirtualCamera(device) {
|
|
608
|
+
const label = device.label.toLowerCase();
|
|
609
|
+
const virtualCameraIndicators = [
|
|
610
|
+
'obs',
|
|
611
|
+
'virtual',
|
|
612
|
+
'snap camera',
|
|
613
|
+
'manycam',
|
|
614
|
+
'xsplit',
|
|
615
|
+
'camtwist',
|
|
616
|
+
'ecamm',
|
|
617
|
+
'nvidia broadcast',
|
|
618
|
+
'droidcam',
|
|
619
|
+
'iriun',
|
|
620
|
+
'elgato',
|
|
621
|
+
'streamlabs',
|
|
622
|
+
'wirecast',
|
|
623
|
+
'zoom virtual',
|
|
624
|
+
'teams virtual',
|
|
625
|
+
'mmhmm',
|
|
626
|
+
'camo',
|
|
627
|
+
'reincubate camo',
|
|
628
|
+
'webcamoid',
|
|
629
|
+
'splitcam',
|
|
630
|
+
'cheese',
|
|
631
|
+
'guvcview',
|
|
632
|
+
'yawcam',
|
|
633
|
+
'webcam 7',
|
|
634
|
+
'altserver'
|
|
635
|
+
];
|
|
636
|
+
return virtualCameraIndicators.some(indicator => label.includes(indicator));
|
|
637
|
+
}
|
|
556
638
|
}
|
|
557
639
|
|
|
558
640
|
class LowMemoryDeviceStrategy {
|
|
@@ -1301,7 +1383,7 @@ const JaakStamps = class {
|
|
|
1301
1383
|
if (!window.ort) {
|
|
1302
1384
|
this.updateStatus('Preparando herramientas...', 'Configurando funciones de captura', 'initializing');
|
|
1303
1385
|
const script = document.createElement('script');
|
|
1304
|
-
script.src = 'https://cdn.jsdelivr.net/npm/onnxruntime-web/dist/ort.min.js';
|
|
1386
|
+
script.src = 'https://cdn.jsdelivr.net/npm/onnxruntime-web@1.23.0/dist/ort.min.js';
|
|
1305
1387
|
document.head.appendChild(script);
|
|
1306
1388
|
await new Promise((resolve) => {
|
|
1307
1389
|
script.onload = () => {
|
|
@@ -2108,7 +2190,7 @@ const JaakStamps = class {
|
|
|
2108
2190
|
isCapturing: false
|
|
2109
2191
|
};
|
|
2110
2192
|
const cameraInfo = this.cameraInfoWithAutofocus;
|
|
2111
|
-
return (index.h("div", { key: '
|
|
2193
|
+
return (index.h("div", { key: 'f9cbca2fd6b8548a29ace7fcb972b53f402f61af', class: "detector-container" }, index.h("div", { key: '4f3cac734eb6bfd44a8de644eadca17e7893e11a', class: "video-container" }, index.h("video", { key: '5e15a38c989a72d5274281272d41ba064447ca6f', ref: el => this.videoRef = el, autoplay: true, muted: true, playsinline: true, class: this.shouldMirrorVideo ? 'mirror' : '', style: { display: captureState.isVideoActive ? 'block' : 'none' } }), index.h("div", { key: '38c8ad8b691db60e9b5a2a8b641fe6febbeacfca', ref: el => this.detectionContainer = el, class: `detection-overlay ${this.shouldMirrorVideo ? 'mirror' : ''}` }, this.debug && this.detectionBoxes.map((box, index$1) => (index.h("div", { key: index$1, class: "detection-box", style: {
|
|
2112
2194
|
position: 'absolute',
|
|
2113
2195
|
left: `${box.x}px`,
|
|
2114
2196
|
top: `${box.y}px`,
|
|
@@ -2117,9 +2199,9 @@ const JaakStamps = class {
|
|
|
2117
2199
|
border: '2px solid #32406C',
|
|
2118
2200
|
pointerEvents: 'none',
|
|
2119
2201
|
boxSizing: 'border-box'
|
|
2120
|
-
} })))), this.isMaskReady && (index.h("div", { key: '
|
|
2202
|
+
} })))), this.isMaskReady && (index.h("div", { key: 'c56fde56b7a86a4e8a4cf558745291ea5cde12fd', class: "overlay-mask" }, index.h("div", { key: '04ed3f01f271dc84eed594cb4b60c2453645bd41', class: "card-outline" }, index.h("div", { key: '648bd423a5e886d4768115237de5896c7223b30b', class: "side side-top" }), index.h("div", { key: 'b8878059493ca61961b9b3c82ecc18b50b79ac85', class: "side side-right" }), index.h("div", { key: '09e5ad64ff33dbd5c112bf52b71e14409ab6aa65', class: "side side-bottom" }), index.h("div", { key: 'b8ba3d83c9bc1b4a0da859d7ed4b9a15eaddcc2a', class: "side side-left" })), !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (index.h("div", { key: '3279701a240f77ac96e68a34ad95c099340c9a6a', class: `guide-text ${this.showPerformanceMessage ? 'performance-warning-text' : ''}` }, this.getGuideText(captureState.step))), captureState.step === 'back' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (index.h("div", { key: '2adf96d0a57e482372fd9586229dac2301b64fd4', class: "back-capture-section" }, index.h("div", { key: '305a147c9cfee854c60ac946a48a1d21b2792725', class: "back-capture-buttons" }, (!this.useDocumentDetector || this.performanceDegradedMode || this.showManualCaptureButton) && (index.h("button", { key: '43270a0647f39307229c540dd5130fb58b1ff4fb', class: "capture-button primary-button", onClick: () => this.takeManualScreenshot(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'capture-back' && (index.h("span", { key: 'eb4666603774564eef95a120ac13faeb9e10c8b4', class: "button-spinner" })), "Capturar Reverso")), index.h("button", { key: 'cac667d9548ae2314ad5a677c5ed90f25184f728', class: "skip-button", onClick: () => this.skipBackCapture(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'skip-back' && (index.h("span", { key: '0af7aa4106ce189ae2d79bec78ede01abe25b1e7', class: "button-spinner" })), this.enableBackDocumentTimer && this.backDocumentTimerRemaining > 0
|
|
2121
2203
|
? `Saltar reverso (${this.backDocumentTimerRemaining}s)`
|
|
2122
|
-
: 'Saltar reverso')))), captureState.isVideoActive && (index.h("div", { key: '
|
|
2204
|
+
: 'Saltar reverso')))), captureState.isVideoActive && (index.h("div", { key: 'de6e5c4fad4d4d996b894457c9af52bc71e533fb', class: "camera-controls" }, index.h("button", { key: 'cfddcf2420d5f5923a6b02ca446bbe1b8e9fc5e4', class: `camera-selector-button ${this.isSwitchingCamera ? 'loading' : ''}`, onClick: () => this.toggleCameraSelector(), type: "button", title: "Seleccionar c\u00E1mara", disabled: this.isSwitchingCamera }, this.isSwitchingCamera ? (index.h("div", { class: "button-spinner" })) : ('Cámaras')))), this.showCameraSelector && cameraInfo.availableCameras.length > 0 && (index.h("div", { key: '5fb73f958b9a5a6f9242032c4530b0bdab84f6c5', class: "camera-selector-dropdown" }, index.h("div", { key: '8ee2d26b1001e571e7b6c326e927926fa08287fd', class: "camera-selector-header" }, index.h("span", { key: '78350b0fb1bd933f7c8c59d8dab0b7122ffbe363' }, "Seleccionar C\u00E1mara"), index.h("button", { key: 'bb750e0ddd5a1ee5ff96bd57805a7f90b8821e9f', class: "close-selector", onClick: () => this.toggleCameraSelector(), type: "button" }, "\u00D7")), index.h("div", { key: 'd0f6343cf1b7367f3da33ec8cf64891109d923b8', class: "camera-list" }, cameraInfo.availableCameras.map((camera) => (index.h("button", { key: camera.id, class: `camera-option ${cameraInfo.selectedCameraId === camera.id ? 'selected' : ''}`, onClick: () => this.handleCameraSwitch(camera.id), type: "button" }, index.h("span", { class: "camera-label" }, camera.label || `Cámara ${cameraInfo.availableCameras.indexOf(camera) + 1}`, camera.hasAutofocus && (index.h("span", { class: "autofocus-icon", title: "Autofoco disponible" }, "\u29BF"))), cameraInfo.selectedCameraId === camera.id && (index.h("span", { class: "selected-indicator" }, "\u2713")))))), index.h("div", { key: 'c9642fbfb0acea766d3f0542f4cc9f17f4af4d7b', class: "device-info" }, index.h("small", { key: 'b6e9507ff7addf011f339f6c22a88a96b40db68a' }, "Dispositivo: ", cameraInfo.deviceType)))), this.showManualCaptureButton && captureState.step === 'front' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (index.h("div", { key: '04ae9262409284782850b90945eb7038673e2097', class: "manual-capture-section" }, index.h("button", { key: '27c315e503ccba468b89ebd58d6b70f40ddd06ba', class: "manual-capture-button", onClick: () => this.takeManualScreenshot(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'capture-front' && (index.h("span", { key: '8f2dcd2df9a218b37eb0b8204a8724362cfeaa53', class: "button-spinner" })), "Capturar Frente"))))), captureState.isCapturing && (index.h("div", { key: '6fd6fe1d0213b01c8119a67fb8108f73227feee1', class: "capture-animation" })), captureState.showFlipAnimation && (index.h("div", { key: 'fba3816b48b99ca64510ecbefc0d41431569c9ae', class: "flip-animation" }, index.h("div", { key: 'beea1c8245b5d81f1008efc6d1b079a61c821e7f', class: "id-card-icon" }), index.h("div", { key: 'f0fbc34f619a653e2c0ade764ca99e7aa582d157', class: "flip-text" }, "\u00A1Voltea tu identificaci\u00F3n!"))), captureState.showSuccessAnimation && (index.h("div", { key: 'e4a0e6d31112e3a50024d1d0430b4ad997049fe7', class: "success-animation" }, index.h("div", { key: '5dd3f781f55630bc904c81207548ae35bc79b452', class: "check-icon" }), index.h("div", { key: 'a10ebc557582325091efb0abd12d62b27a43b98c', class: "success-text" }, "\u00A1Proceso completado!"))), index.h("div", { key: '975865955dee1803b5215ecf049701c98b324855', class: `component-status status-${this.currentStatus.type}` }, (this.currentStatus.type === 'loading' || this.currentStatus.type === 'initializing') && (index.h("div", { key: '84f6f67202e26ce80f7fc5d5f321e23b5bc55c57', class: "status-spinner" })), index.h("div", { key: 'a1ae56ed156e8feb279a1bf160f749c5d0b5ce45', class: "status-content" }, index.h("div", { key: 'd62932554cea257ce19763df26e0ba702e50eeca', class: "status-message" }, this.currentStatus.message), this.currentStatus.description && (index.h("div", { key: 'c5506fa12dd0d37d26dc26c9f2381c843330451f', class: "status-description" }, this.currentStatus.description)))), this.debug && (index.h("div", { key: '2097eda63185f336f7319014fae2ef6db1e41761', class: "performance-monitor" }, index.h("div", { key: 'd611c494c6b1a5930ef64aebdcba41e5d94c9ee6', class: "performance-expanded" }, index.h("div", { key: '800d46831e7b9bec260d9c5e67ea1a3eb9c2933e', class: "metrics-row" }, index.h("div", { key: 'dd0db1faa9050d98e71da4b5cd26a4a484c37c64', class: "metric-compact" }, index.h("span", { key: 'f0e6ea61a35ddb2ae5c2a6aff8c255a02c5c1219', class: "metric-label" }, "FPS"), index.h("span", { key: 'cbf4df4d142f6f01e45f566a8ede8fbbf29ad673', class: `metric-value ${this.performanceData.fps < 15 ? 'warning' : this.performanceData.fps < 10 ? 'danger' : 'good'}` }, this.performanceData.fps)), index.h("div", { key: '83861ad31fa46c8199a5583e4b3f8eefd44bacd6', class: "metric-compact" }, index.h("span", { key: '41b8de4cda47959dfc9df393e95fdadde534dd21', class: "metric-label" }, "MEM"), index.h("span", { key: 'b268f13cc78066e240ed158f1443113a94827aff', class: `metric-value ${this.performanceData.memoryUsage > 100 ? 'warning' : this.performanceData.memoryUsage > 200 ? 'danger' : 'good'}` }, this.performanceData.memoryUsage, "MB"))), index.h("div", { key: '9f9a9d0690906b186492af23b900c5fa0f5cff89', class: "metrics-row" }, index.h("div", { key: '84fa6e453dc36e4a74e8b573447b17230766229e', class: "metric-compact" }, index.h("span", { key: 'f17d52899090c89f532d74c552dd8c5338fc2d83', class: "metric-label" }, "INF"), index.h("span", { key: '2beca0d7ce55ed574f6b01efc086c5846983e024', class: `metric-value ${this.performanceData.inferenceTime > 100 ? 'warning' : this.performanceData.inferenceTime > 200 ? 'danger' : 'good'}` }, this.performanceData.inferenceTime, "ms")), index.h("div", { key: '981e300cf076e81bfe946974f6cffd63619eacde', class: "metric-compact" }, index.h("span", { key: '3dfb0c996a69eb87b0f711322675cad69c471146', class: "metric-label" }, "FRAME"), index.h("span", { key: '3ae2ac6e90cda77f23e559f3197c3b761f9bdc40', class: `metric-value ${this.performanceData.frameProcessingTime > 50 ? 'warning' : this.performanceData.frameProcessingTime > 100 ? 'danger' : 'good'}` }, this.performanceData.frameProcessingTime, "ms"))), index.h("div", { key: '2c51216838d87728d9d7764e5ba8a50fa02eb493', class: "metrics-row" }, index.h("div", { key: 'eda810ffb80ec38ab84583f59b26706f90a50fc9', class: "metric-compact" }, index.h("span", { key: '978ba9c0c67d6da6b29b3535af33a314bab9276a', class: "metric-label" }, "DET"), index.h("span", { key: '3e5e169fd4a3906283d8f918b5bbc7c5df6ccd0f', class: "metric-value good" }, this.performanceData.successfulDetections, "/", this.performanceData.totalDetections)), index.h("div", { key: 'b4b915c745e35c09470a4dc5edfc112d32cfb8b6', class: "metric-compact" }, index.h("span", { key: '3e2a7b88a4446813c955efb0dfa9e2958e8e1448', class: "metric-label" }, "RATE"), index.h("span", { key: 'f4f073f7ee622167a241c6a1c535ef580c13d9ab', class: `metric-value ${this.performanceData.detectionRate < 30 ? 'danger' : this.performanceData.detectionRate < 60 ? 'warning' : 'good'}` }, this.performanceData.detectionRate, "%")))))), index.h("div", { key: '76c556e92f6d7980539f1a30efe8751f665164fb', class: "watermark" }, index.h("img", { key: 'af23e115d6b4e92a72e55d6d98fde0e4b1d09e9b', src: "https://storage.googleapis.com/jaak-static/commons/powered-by-jaak.png", alt: "Powered by Jaak" })))));
|
|
2123
2205
|
}
|
|
2124
2206
|
// Utility methods
|
|
2125
2207
|
updateDetectionBoxes(boxes) {
|
|
@@ -2316,8 +2398,8 @@ const JaakStamps = class {
|
|
|
2316
2398
|
if (captureState.step === 'front') {
|
|
2317
2399
|
this.stateManager.setCapturedImages({
|
|
2318
2400
|
front: {
|
|
2319
|
-
fullFrame: captureCanvas.toDataURL('image/
|
|
2320
|
-
cropped: croppedCanvas.toDataURL('image/
|
|
2401
|
+
fullFrame: captureCanvas.toDataURL('image/jpeg'),
|
|
2402
|
+
cropped: croppedCanvas.toDataURL('image/jpeg')
|
|
2321
2403
|
}
|
|
2322
2404
|
});
|
|
2323
2405
|
// Check if document classification is enabled (independent of detector)
|
|
@@ -2357,8 +2439,8 @@ const JaakStamps = class {
|
|
|
2357
2439
|
else if (captureState.step === 'back') {
|
|
2358
2440
|
this.stateManager.setCapturedImages({
|
|
2359
2441
|
back: {
|
|
2360
|
-
fullFrame: captureCanvas.toDataURL('image/
|
|
2361
|
-
cropped: croppedCanvas.toDataURL('image/
|
|
2442
|
+
fullFrame: captureCanvas.toDataURL('image/jpeg'),
|
|
2443
|
+
cropped: croppedCanvas.toDataURL('image/jpeg')
|
|
2362
2444
|
}
|
|
2363
2445
|
});
|
|
2364
2446
|
this.completeProcess(false);
|
|
@@ -2396,8 +2478,8 @@ const JaakStamps = class {
|
|
|
2396
2478
|
if (captureState.step === 'front') {
|
|
2397
2479
|
this.stateManager.setCapturedImages({
|
|
2398
2480
|
front: {
|
|
2399
|
-
fullFrame: captureCanvas.toDataURL('image/
|
|
2400
|
-
cropped: croppedCanvas.toDataURL('image/
|
|
2481
|
+
fullFrame: captureCanvas.toDataURL('image/jpeg'),
|
|
2482
|
+
cropped: croppedCanvas.toDataURL('image/jpeg')
|
|
2401
2483
|
}
|
|
2402
2484
|
});
|
|
2403
2485
|
// Check if document classification is enabled
|
|
@@ -2429,8 +2511,8 @@ const JaakStamps = class {
|
|
|
2429
2511
|
else if (captureState.step === 'back') {
|
|
2430
2512
|
this.stateManager.setCapturedImages({
|
|
2431
2513
|
back: {
|
|
2432
|
-
fullFrame: captureCanvas.toDataURL('image/
|
|
2433
|
-
cropped: croppedCanvas.toDataURL('image/
|
|
2514
|
+
fullFrame: captureCanvas.toDataURL('image/jpeg'),
|
|
2515
|
+
cropped: croppedCanvas.toDataURL('image/jpeg')
|
|
2434
2516
|
}
|
|
2435
2517
|
});
|
|
2436
2518
|
this.completeProcess(false);
|
|
@@ -2556,10 +2638,13 @@ const JaakStamps = class {
|
|
|
2556
2638
|
this.useDocumentDetector = false; // Desactivar detector automático
|
|
2557
2639
|
// Actualizar el estado con mensaje de error
|
|
2558
2640
|
this.updateStatus('Modo manual activado', errorMessage, 'error');
|
|
2559
|
-
//
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2641
|
+
// Continuar con la configuración de cámara para mostrar el video
|
|
2642
|
+
this.continueWithCameraSetup().catch(() => {
|
|
2643
|
+
// Si falla la configuración de cámara, mantener el mensaje de error pero cambiar el estado
|
|
2644
|
+
setTimeout(() => {
|
|
2645
|
+
this.updateStatus('Captura manual', 'Use el botón para capturar', 'ready');
|
|
2646
|
+
}, 5000);
|
|
2647
|
+
});
|
|
2563
2648
|
}
|
|
2564
2649
|
stopPerformanceMonitoring() {
|
|
2565
2650
|
// Nota: No necesitamos limpiar más variables porque ya no se usarán
|
|
@@ -2646,6 +2731,12 @@ const JaakStamps = class {
|
|
|
2646
2731
|
try {
|
|
2647
2732
|
// Close the selector immediately when user selects a camera
|
|
2648
2733
|
this.showCameraSelector = false;
|
|
2734
|
+
// Check if user selected the same camera that's already active
|
|
2735
|
+
const currentCameraId = this.cameraService.getSelectedCameraId();
|
|
2736
|
+
if (currentCameraId === cameraId) {
|
|
2737
|
+
// Same camera selected, just close the selector without switching
|
|
2738
|
+
return;
|
|
2739
|
+
}
|
|
2649
2740
|
this.isSwitchingCamera = true;
|
|
2650
2741
|
// Stop current video stream
|
|
2651
2742
|
if (this.videoStream) {
|