@jaak.ai/stamps 2.1.0-dev.14 → 2.1.0-dev.16
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 +90 -2
- 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 +6 -0
- 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 +90 -2
- package/dist/components/jaak-stamps.js.map +1 -1
- package/dist/esm/jaak-stamps.entry.js +90 -2
- 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-f43eee33.entry.js +2 -0
- package/dist/jaak-stamps-webcomponent/p-f43eee33.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-fd8481ba.entry.js +0 -2
- package/dist/jaak-stamps-webcomponent/p-fd8481ba.entry.js.map +0 -1
|
@@ -204,7 +204,21 @@ class CameraService {
|
|
|
204
204
|
tempStream.getTracks().forEach(track => track.stop());
|
|
205
205
|
}
|
|
206
206
|
const devices = await navigator.mediaDevices.enumerateDevices();
|
|
207
|
-
|
|
207
|
+
const allCameras = devices.filter(device => device.kind === 'videoinput');
|
|
208
|
+
// Filter out virtual cameras
|
|
209
|
+
this.availableCameras = allCameras.filter(camera => {
|
|
210
|
+
const isVirtual = this.isVirtualCamera(camera);
|
|
211
|
+
if (isVirtual) {
|
|
212
|
+
console.log(`Virtual camera detected and filtered: ${camera.label}`);
|
|
213
|
+
}
|
|
214
|
+
return !isVirtual;
|
|
215
|
+
});
|
|
216
|
+
// Check if there are physical cameras available
|
|
217
|
+
if (this.availableCameras.length === 0) {
|
|
218
|
+
console.log('No physical cameras available');
|
|
219
|
+
this.eventBus.emit('error', new Error('Cámaras virtuales no están permitidas. Use una cámara física.'));
|
|
220
|
+
return [];
|
|
221
|
+
}
|
|
208
222
|
// Cache the results for optimization
|
|
209
223
|
CameraService.deviceEnumerationCache = {
|
|
210
224
|
devices: this.availableCameras,
|
|
@@ -254,6 +268,21 @@ class CameraService {
|
|
|
254
268
|
});
|
|
255
269
|
this.lastStreamConstraints = finalConstraints;
|
|
256
270
|
const stream = await this.currentStreamPromise;
|
|
271
|
+
// Validate that active stream is not from a virtual camera
|
|
272
|
+
const videoTrack = stream.getVideoTracks()[0];
|
|
273
|
+
if (videoTrack) {
|
|
274
|
+
const settings = videoTrack.getSettings();
|
|
275
|
+
const deviceId = settings.deviceId;
|
|
276
|
+
if (deviceId) {
|
|
277
|
+
const devices = await navigator.mediaDevices.enumerateDevices();
|
|
278
|
+
const currentDevice = devices.find(device => device.deviceId === deviceId);
|
|
279
|
+
if (currentDevice && this.isVirtualCamera(currentDevice)) {
|
|
280
|
+
console.log(`Virtual camera detected in active stream: ${currentDevice.label}`);
|
|
281
|
+
stream.getTracks().forEach(track => track.stop());
|
|
282
|
+
throw new Error('Cámaras virtuales no están permitidas. Use una cámara física.');
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
257
286
|
return stream;
|
|
258
287
|
}
|
|
259
288
|
catch (error) {
|
|
@@ -271,7 +300,23 @@ class CameraService {
|
|
|
271
300
|
audio: false
|
|
272
301
|
});
|
|
273
302
|
this.lastStreamConstraints = basicConstraints;
|
|
274
|
-
|
|
303
|
+
const stream = await this.currentStreamPromise;
|
|
304
|
+
// Validate fallback stream as well
|
|
305
|
+
const videoTrack = stream.getVideoTracks()[0];
|
|
306
|
+
if (videoTrack) {
|
|
307
|
+
const settings = videoTrack.getSettings();
|
|
308
|
+
const deviceId = settings.deviceId;
|
|
309
|
+
if (deviceId) {
|
|
310
|
+
const devices = await navigator.mediaDevices.enumerateDevices();
|
|
311
|
+
const currentDevice = devices.find(device => device.deviceId === deviceId);
|
|
312
|
+
if (currentDevice && this.isVirtualCamera(currentDevice)) {
|
|
313
|
+
console.log(`Virtual camera detected in fallback stream: ${currentDevice.label}`);
|
|
314
|
+
stream.getTracks().forEach(track => track.stop());
|
|
315
|
+
throw new Error('Cámaras virtuales no están permitidas. Use una cámara física.');
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
return stream;
|
|
275
320
|
}
|
|
276
321
|
}
|
|
277
322
|
async switchCamera(cameraId) {
|
|
@@ -280,6 +325,12 @@ class CameraService {
|
|
|
280
325
|
await this.enumerateDevices();
|
|
281
326
|
return;
|
|
282
327
|
}
|
|
328
|
+
// Validate that the target camera is not virtual
|
|
329
|
+
if (this.isVirtualCamera(selectedCamera)) {
|
|
330
|
+
console.log(`Attempted to switch to virtual camera: ${selectedCamera.label}`);
|
|
331
|
+
this.eventBus.emit('error', new Error('No se puede cambiar a cámara virtual'));
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
283
334
|
await this.setSelectedCamera(cameraId);
|
|
284
335
|
}
|
|
285
336
|
isRearCamera(stream) {
|
|
@@ -551,6 +602,37 @@ class CameraService {
|
|
|
551
602
|
invalidateDeviceCache() {
|
|
552
603
|
CameraService.deviceEnumerationCache = null;
|
|
553
604
|
}
|
|
605
|
+
isVirtualCamera(device) {
|
|
606
|
+
const label = device.label.toLowerCase();
|
|
607
|
+
const virtualCameraIndicators = [
|
|
608
|
+
'obs',
|
|
609
|
+
'virtual',
|
|
610
|
+
'snap camera',
|
|
611
|
+
'manycam',
|
|
612
|
+
'xsplit',
|
|
613
|
+
'camtwist',
|
|
614
|
+
'ecamm',
|
|
615
|
+
'nvidia broadcast',
|
|
616
|
+
'droidcam',
|
|
617
|
+
'iriun',
|
|
618
|
+
'elgato',
|
|
619
|
+
'streamlabs',
|
|
620
|
+
'wirecast',
|
|
621
|
+
'zoom virtual',
|
|
622
|
+
'teams virtual',
|
|
623
|
+
'mmhmm',
|
|
624
|
+
'camo',
|
|
625
|
+
'reincubate camo',
|
|
626
|
+
'webcamoid',
|
|
627
|
+
'splitcam',
|
|
628
|
+
'cheese',
|
|
629
|
+
'guvcview',
|
|
630
|
+
'yawcam',
|
|
631
|
+
'webcam 7',
|
|
632
|
+
'altserver'
|
|
633
|
+
];
|
|
634
|
+
return virtualCameraIndicators.some(indicator => label.includes(indicator));
|
|
635
|
+
}
|
|
554
636
|
}
|
|
555
637
|
|
|
556
638
|
class LowMemoryDeviceStrategy {
|
|
@@ -2647,6 +2729,12 @@ const JaakStamps = class {
|
|
|
2647
2729
|
try {
|
|
2648
2730
|
// Close the selector immediately when user selects a camera
|
|
2649
2731
|
this.showCameraSelector = false;
|
|
2732
|
+
// Check if user selected the same camera that's already active
|
|
2733
|
+
const currentCameraId = this.cameraService.getSelectedCameraId();
|
|
2734
|
+
if (currentCameraId === cameraId) {
|
|
2735
|
+
// Same camera selected, just close the selector without switching
|
|
2736
|
+
return;
|
|
2737
|
+
}
|
|
2650
2738
|
this.isSwitchingCamera = true;
|
|
2651
2739
|
// Stop current video stream
|
|
2652
2740
|
if (this.videoStream) {
|