@microblink/camera-manager 7.2.0 → 7.2.1
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/camera-manager.js +57 -50
- package/dist/camera-manager.js.map +1 -1
- package/package.json +1 -1
- package/types/core/cameraUtils.d.ts +9 -0
- package/types/core/cameraUtils.d.ts.map +1 -1
- package/types/core/cameraUtils.test.d.ts +5 -0
- package/types/core/cameraUtils.test.d.ts.map +1 -0
- package/types/media-mock/fake-devices.d.ts.map +1 -1
- package/types/media-mock/fakeDevices/DesktopSingleFrontFacing.d.ts +6 -0
- package/types/media-mock/fakeDevices/DesktopSingleFrontFacing.d.ts.map +1 -0
package/dist/camera-manager.js
CHANGED
|
@@ -600,12 +600,40 @@ const createConstraints = (resolution, facing, id) => {
|
|
|
600
600
|
};
|
|
601
601
|
return constraints;
|
|
602
602
|
};
|
|
603
|
+
function scoreCameraCapabilities(camera) {
|
|
604
|
+
let score = 0;
|
|
605
|
+
if (camera.torchSupported) score += 1;
|
|
606
|
+
if (camera.singleShotSupported) score += 1;
|
|
607
|
+
return score;
|
|
608
|
+
}
|
|
609
|
+
function filterCamerasByFacing(cameras, requestedFacing) {
|
|
610
|
+
return cameras.filter((camera) => {
|
|
611
|
+
if (requestedFacing === "back" || requestedFacing === void 0) {
|
|
612
|
+
return isBackCameraName(camera.name);
|
|
613
|
+
} else {
|
|
614
|
+
return isFrontCameraName(camera.name);
|
|
615
|
+
}
|
|
616
|
+
});
|
|
617
|
+
}
|
|
603
618
|
const findIdealCamera = async (cameras, resolution = "4k", requestedFacing = "back") => {
|
|
604
619
|
if (cameras.length === 0) {
|
|
605
620
|
throw new Error("No cameras found");
|
|
606
621
|
}
|
|
622
|
+
if (cameras.length === 1) {
|
|
623
|
+
await cameras[0].startStream(resolution);
|
|
624
|
+
return cameras[0];
|
|
625
|
+
}
|
|
626
|
+
let cameraPool = filterCamerasByFacing(cameras, requestedFacing);
|
|
627
|
+
if (cameraPool.length === 1) {
|
|
628
|
+
await cameraPool[0].startStream(resolution);
|
|
629
|
+
return cameraPool[0];
|
|
630
|
+
}
|
|
631
|
+
if (cameraPool.length === 0) {
|
|
632
|
+
console.debug("No camera found with requested facing, using all cameras");
|
|
633
|
+
cameraPool = cameras;
|
|
634
|
+
}
|
|
607
635
|
if (requestedFacing === "back") {
|
|
608
|
-
const dualWideCamera =
|
|
636
|
+
const dualWideCamera = cameraPool.find(
|
|
609
637
|
(camera) => backDualWideCameraLocalizations.includes(camera.name)
|
|
610
638
|
);
|
|
611
639
|
if (dualWideCamera) {
|
|
@@ -613,65 +641,44 @@ const findIdealCamera = async (cameras, resolution = "4k", requestedFacing = "ba
|
|
|
613
641
|
return dualWideCamera;
|
|
614
642
|
}
|
|
615
643
|
}
|
|
616
|
-
|
|
617
|
-
if (requestedFacing === "back" || requestedFacing === void 0) {
|
|
618
|
-
return isBackCameraName(camera.name);
|
|
619
|
-
} else {
|
|
620
|
-
return isFrontCameraName(camera.name);
|
|
621
|
-
}
|
|
622
|
-
});
|
|
623
|
-
if (cameraPool.length === 1 && cameraPool[0].facingMode === requestedFacing) {
|
|
624
|
-
await cameraPool[0].startStream(resolution);
|
|
625
|
-
return cameraPool[0];
|
|
626
|
-
}
|
|
627
|
-
if (cameraPool.length > 0 && requestedFacing === "front") {
|
|
644
|
+
if (requestedFacing === "front") {
|
|
628
645
|
const lastCamera = cameraPool[cameraPool.length - 1];
|
|
629
646
|
await lastCamera.startStream(resolution);
|
|
630
647
|
return lastCamera;
|
|
631
648
|
}
|
|
632
|
-
if (cameraPool.length === 0) {
|
|
633
|
-
console.debug("No camera found with requested facing, using all cameras");
|
|
634
|
-
cameraPool.push(...cameras);
|
|
635
|
-
}
|
|
636
649
|
const cameraScores = /* @__PURE__ */ new Map();
|
|
637
|
-
|
|
650
|
+
let bestCamera;
|
|
651
|
+
let maxScore = -Infinity;
|
|
638
652
|
for (let i = cameraPool.length - 1; i >= 0; i--) {
|
|
639
653
|
const camera = cameraPool[i];
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
camera.stopStream();
|
|
648
|
-
continue;
|
|
649
|
-
}
|
|
650
|
-
if (camera.torchSupported && camera.singleShotSupported) {
|
|
651
|
-
console.debug("Camera supports torch and single shot, returning");
|
|
652
|
-
return camera;
|
|
653
|
-
}
|
|
654
|
-
if (camera.torchSupported) {
|
|
655
|
-
cameraScores.set(camera, cameraScores.get(camera) + 1);
|
|
656
|
-
}
|
|
657
|
-
if (camera.singleShotSupported) {
|
|
658
|
-
cameraScores.set(camera, cameraScores.get(camera) + 1);
|
|
659
|
-
}
|
|
660
|
-
if (i === 0) {
|
|
661
|
-
console.debug("Last camera in the pool, picking the best one");
|
|
662
|
-
let maxKey;
|
|
663
|
-
let maxValue = -Infinity;
|
|
664
|
-
cameraScores.forEach((score, camera2) => {
|
|
665
|
-
if (score > maxValue) {
|
|
666
|
-
maxValue = score;
|
|
667
|
-
maxKey = camera2;
|
|
654
|
+
try {
|
|
655
|
+
await camera.startStream(resolution);
|
|
656
|
+
const score = scoreCameraCapabilities(camera);
|
|
657
|
+
cameraScores.set(camera, score);
|
|
658
|
+
if (score > maxScore) {
|
|
659
|
+
if (bestCamera && bestCamera !== camera) {
|
|
660
|
+
bestCamera.stopStream();
|
|
668
661
|
}
|
|
669
|
-
|
|
670
|
-
|
|
662
|
+
maxScore = score;
|
|
663
|
+
bestCamera = camera;
|
|
664
|
+
} else {
|
|
665
|
+
camera.stopStream();
|
|
666
|
+
}
|
|
667
|
+
if (score === 2) {
|
|
668
|
+
console.debug("Found camera with all capabilities, returning early");
|
|
669
|
+
return camera;
|
|
670
|
+
}
|
|
671
|
+
} catch (error) {
|
|
672
|
+
console.warn(`Failed to test camera ${camera.name}:`, error);
|
|
673
|
+
camera.stopStream();
|
|
671
674
|
}
|
|
672
|
-
camera.stopStream();
|
|
673
675
|
}
|
|
674
|
-
|
|
676
|
+
if (bestCamera) {
|
|
677
|
+
return bestCamera;
|
|
678
|
+
}
|
|
679
|
+
const firstCamera = cameraPool[0];
|
|
680
|
+
await firstCamera.startStream(resolution);
|
|
681
|
+
return firstCamera;
|
|
675
682
|
};
|
|
676
683
|
function createCameras(cameras) {
|
|
677
684
|
const camerasWithStream = [];
|