UNPKG

scandit-sdk

Version:

Scandit Barcode Scanner SDK for the Web

774 lines 41.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var camera_1 = require("./camera"); var cameraAccess_1 = require("./cameraAccess"); var cameraManager_1 = require("./cameraManager"); var cameraSettings_1 = require("./cameraSettings"); var customError_1 = require("./customError"); /** * @hidden */ var MeteringMode; (function (MeteringMode) { MeteringMode["CONTINUOUS"] = "continuous"; MeteringMode["MANUAL"] = "manual"; MeteringMode["NONE"] = "none"; MeteringMode["SINGLE_SHOT"] = "single-shot"; })(MeteringMode = exports.MeteringMode || (exports.MeteringMode = {})); /** * @hidden * * A barcode picker utility class used to handle camera interaction. */ var BarcodePickerCameraManager = /** @class */ (function (_super) { tslib_1.__extends(BarcodePickerCameraManager, _super); function BarcodePickerCameraManager(triggerFatalError, barcodePickerGui) { var _this = _super.call(this) || this; _this.postStreamInitializationListener = _this.postStreamInitialization.bind(_this); _this.videoTrackUnmuteListener = _this.videoTrackUnmuteRecovery.bind(_this); _this.triggerManualFocusListener = _this.triggerManualFocus.bind(_this); _this.triggerZoomStartListener = _this.triggerZoomStart.bind(_this); _this.triggerZoomMoveListener = _this.triggerZoomMove.bind(_this); _this.triggerFatalError = triggerFatalError; _this.barcodePickerGui = barcodePickerGui; return _this; } BarcodePickerCameraManager.prototype.setInteractionOptions = function (cameraSwitcherEnabled, torchToggleEnabled, tapToFocusEnabled, pinchToZoomEnabled) { this.cameraSwitcherEnabled = cameraSwitcherEnabled; this.torchToggleEnabled = torchToggleEnabled; this.tapToFocusEnabled = tapToFocusEnabled; this.pinchToZoomEnabled = pinchToZoomEnabled; }; BarcodePickerCameraManager.prototype.isCameraSwitcherEnabled = function () { return this.cameraSwitcherEnabled; }; BarcodePickerCameraManager.prototype.setCameraSwitcherEnabled = function (enabled) { return tslib_1.__awaiter(this, void 0, void 0, function () { var cameras; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: this.cameraSwitcherEnabled = enabled; if (!this.cameraSwitcherEnabled) return [3 /*break*/, 2]; return [4 /*yield*/, cameraAccess_1.CameraAccess.getCameras()]; case 1: cameras = _a.sent(); if (cameras.length > 1) { this.barcodePickerGui.setCameraSwitcherVisible(true); } return [3 /*break*/, 3]; case 2: this.barcodePickerGui.setCameraSwitcherVisible(false); _a.label = 3; case 3: return [2 /*return*/]; } }); }); }; BarcodePickerCameraManager.prototype.isTorchToggleEnabled = function () { return this.torchToggleEnabled; }; BarcodePickerCameraManager.prototype.setTorchToggleEnabled = function (enabled) { this.torchToggleEnabled = enabled; if (this.torchToggleEnabled) { if (this.mediaStream != null && this.mediaTrackCapabilities != null && this.mediaTrackCapabilities.torch != null && this.mediaTrackCapabilities.torch) { this.barcodePickerGui.setTorchTogglerVisible(true); } } else { this.barcodePickerGui.setTorchTogglerVisible(false); } }; BarcodePickerCameraManager.prototype.isTapToFocusEnabled = function () { return this.tapToFocusEnabled; }; BarcodePickerCameraManager.prototype.setTapToFocusEnabled = function (enabled) { this.tapToFocusEnabled = enabled; if (this.mediaStream != null) { if (this.tapToFocusEnabled) { this.enableTapToFocusListeners(); } else { this.disableTapToFocusListeners(); } } }; BarcodePickerCameraManager.prototype.isPinchToZoomEnabled = function () { return this.pinchToZoomEnabled; }; BarcodePickerCameraManager.prototype.setPinchToZoomEnabled = function (enabled) { this.pinchToZoomEnabled = enabled; if (this.mediaStream != null) { if (this.pinchToZoomEnabled) { this.enablePinchToZoomListeners(); } else { this.disablePinchToZoomListeners(); } } }; BarcodePickerCameraManager.prototype.setSelectedCamera = function (camera) { this.selectedCamera = camera; }; BarcodePickerCameraManager.prototype.setSelectedCameraSettings = function (cameraSettings) { this.selectedCameraSettings = cameraSettings; }; BarcodePickerCameraManager.prototype.setupCameras = function () { return tslib_1.__awaiter(this, void 0, void 0, function () { var mediaStreamTrack, cameras, mainCamera, autoselectedCamera; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: if (this.cameraInitializationPromise != null) { return [2 /*return*/, this.cameraInitializationPromise]; } return [4 /*yield*/, this.accessInitialCamera()]; case 1: mediaStreamTrack = _a.sent(); return [4 /*yield*/, cameraAccess_1.CameraAccess.getCameras()]; case 2: cameras = _a.sent(); if (this.cameraSwitcherEnabled && cameras.length > 1) { this.barcodePickerGui.setCameraSwitcherVisible(true); } if (mediaStreamTrack != null) { mainCamera = cameraAccess_1.CameraAccess.adjustCamerasFromMainCameraStream(mediaStreamTrack, cameras); if (mainCamera != null) { this.selectedCamera = mainCamera; this.updateActiveCameraCurrentResolution(mainCamera); return [2 /*return*/, Promise.resolve()]; } this.setSelectedCamera(); } if (this.selectedCamera == null) { autoselectedCamera = cameras .filter(function (camera) { return camera.cameraType === camera_1.Camera.Type.BACK; }) .sort(function (camera1, camera2) { return camera1.label.localeCompare(camera2.label); })[0]; if (autoselectedCamera == null) { autoselectedCamera = cameras[0]; if (autoselectedCamera == null) { throw new customError_1.CustomError(BarcodePickerCameraManager.noCameraErrorParameters); } } return [2 /*return*/, this.initializeCameraWithSettings(autoselectedCamera, this.selectedCameraSettings)]; } else { return [2 /*return*/, this.initializeCameraWithSettings(this.selectedCamera, this.selectedCameraSettings)]; } return [2 /*return*/]; } }); }); }; BarcodePickerCameraManager.prototype.stopStream = function () { if (this.activeCamera != null) { this.activeCamera.currentResolution = undefined; } this.activeCamera = undefined; if (this.mediaStream != null) { window.clearTimeout(this.cameraAccessTimeout); window.clearInterval(this.cameraMetadataCheckInterval); window.clearTimeout(this.getCapabilitiesTimeout); window.clearTimeout(this.manualFocusWaitTimeout); window.clearTimeout(this.manualToAutofocusResumeTimeout); window.clearInterval(this.autofocusInterval); this.mediaStream.getVideoTracks().forEach(function (track) { track.stop(); }); this.mediaStream = undefined; this.mediaTrackCapabilities = undefined; } }; BarcodePickerCameraManager.prototype.applyCameraSettings = function (cameraSettings) { this.selectedCameraSettings = cameraSettings; if (this.activeCamera == null) { return Promise.reject(new customError_1.CustomError(BarcodePickerCameraManager.noCameraErrorParameters)); } return this.initializeCameraWithSettings(this.activeCamera, cameraSettings); }; BarcodePickerCameraManager.prototype.reinitializeCamera = function () { if (this.activeCamera != null) { this.initializeCameraWithSettings(this.activeCamera, this.activeCameraSettings).catch(this.triggerFatalError); } }; BarcodePickerCameraManager.prototype.initializeCameraWithSettings = function (camera, cameraSettings) { return tslib_1.__awaiter(this, void 0, void 0, function () { var existingCameraInitializationPromise; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: existingCameraInitializationPromise = Promise.resolve(); if (this.cameraInitializationPromise != null) { existingCameraInitializationPromise = this.cameraInitializationPromise; } return [4 /*yield*/, existingCameraInitializationPromise]; case 1: _a.sent(); this.setSelectedCamera(camera); this.selectedCameraSettings = this.activeCameraSettings = cameraSettings; if (cameraSettings != null && cameraSettings.resolutionPreference === cameraSettings_1.CameraSettings.ResolutionPreference.FULL_HD) { this.cameraInitializationPromise = this.initializeCameraAndCheckUpdatedSettings(camera); } else { this.cameraInitializationPromise = this.initializeCameraAndCheckUpdatedSettings(camera, 3); } return [2 /*return*/, this.cameraInitializationPromise]; } }); }); }; BarcodePickerCameraManager.prototype.setTorchEnabled = function (enabled) { return tslib_1.__awaiter(this, void 0, void 0, function () { var videoTracks; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: if (!(this.mediaStream != null && this.mediaTrackCapabilities != null && this.mediaTrackCapabilities.torch != null && this.mediaTrackCapabilities.torch)) return [3 /*break*/, 2]; this.torchEnabled = enabled; videoTracks = this.mediaStream.getVideoTracks(); if (!(videoTracks.length !== 0 && typeof videoTracks[0].applyConstraints === "function")) return [3 /*break*/, 2]; return [4 /*yield*/, videoTracks[0].applyConstraints({ advanced: [{ torch: enabled }] })]; case 1: _a.sent(); _a.label = 2; case 2: return [2 /*return*/]; } }); }); }; BarcodePickerCameraManager.prototype.toggleTorch = function () { return tslib_1.__awaiter(this, void 0, void 0, function () { return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: this.torchEnabled = !this.torchEnabled; return [4 /*yield*/, this.setTorchEnabled(this.torchEnabled)]; case 1: _a.sent(); return [2 /*return*/]; } }); }); }; BarcodePickerCameraManager.prototype.setZoom = function (zoomPercentage, currentZoom) { return tslib_1.__awaiter(this, void 0, void 0, function () { var videoTracks, zoomRange, targetZoom; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: if (!(this.mediaStream != null && this.mediaTrackCapabilities != null && this.mediaTrackCapabilities.zoom != null)) return [3 /*break*/, 2]; videoTracks = this.mediaStream.getVideoTracks(); if (!(videoTracks.length !== 0 && typeof videoTracks[0].applyConstraints === "function")) return [3 /*break*/, 2]; zoomRange = this.mediaTrackCapabilities.zoom.max - this.mediaTrackCapabilities.zoom.min; if (currentZoom == null) { currentZoom = this.mediaTrackCapabilities.zoom.min; } targetZoom = Math.max(this.mediaTrackCapabilities.zoom.min, Math.min(currentZoom + zoomRange * zoomPercentage, this.mediaTrackCapabilities.zoom.max)); return [4 /*yield*/, videoTracks[0].applyConstraints({ advanced: [{ zoom: targetZoom }] })]; case 1: _a.sent(); _a.label = 2; case 2: return [2 /*return*/]; } }); }); }; BarcodePickerCameraManager.prototype.accessInitialCamera = function () { var _this = this; var initialCameraAccessPromise = Promise.resolve(); if (this.selectedCamera == null) { // Try to directly access primary (back or only) camera var primaryCamera_1 = { deviceId: "", label: "", cameraType: camera_1.Camera.Type.BACK }; initialCameraAccessPromise = new Promise(function (resolve) { return tslib_1.__awaiter(_this, void 0, void 0, function () { var videoTracks, _a; return tslib_1.__generator(this, function (_b) { switch (_b.label) { case 0: _b.trys.push([0, 2, 3, 4]); return [4 /*yield*/, this.initializeCameraWithSettings(primaryCamera_1, this.selectedCameraSettings)]; case 1: _b.sent(); if (this.mediaStream != null) { videoTracks = this.mediaStream.getVideoTracks(); if (videoTracks.length !== 0) { return [2 /*return*/, resolve(videoTracks[0])]; } } return [3 /*break*/, 4]; case 2: _a = _b.sent(); return [3 /*break*/, 4]; case 3: resolve(); return [7 /*endfinally*/]; case 4: return [2 /*return*/]; } }); }); }); } return initialCameraAccessPromise; }; BarcodePickerCameraManager.prototype.updateActiveCameraCurrentResolution = function (camera) { this.activeCamera = camera; this.activeCamera.currentResolution = { width: this.barcodePickerGui.videoElement.videoWidth, height: this.barcodePickerGui.videoElement.videoHeight }; this.barcodePickerGui.setMirrorImageEnabled(this.barcodePickerGui.isMirrorImageEnabled(), false); }; BarcodePickerCameraManager.prototype.postStreamInitialization = function () { var _this = this; window.clearTimeout(this.getCapabilitiesTimeout); this.getCapabilitiesTimeout = window.setTimeout(function () { _this.storeStreamCapabilities(); _this.setupAutofocus(); if (_this.torchToggleEnabled && _this.mediaStream != null && _this.mediaTrackCapabilities != null && _this.mediaTrackCapabilities.torch != null && _this.mediaTrackCapabilities.torch) { _this.barcodePickerGui.setTorchTogglerVisible(true); } }, BarcodePickerCameraManager.getCapabilitiesTimeoutMs); }; BarcodePickerCameraManager.prototype.videoTrackUnmuteRecovery = function () { this.reinitializeCamera(); }; BarcodePickerCameraManager.prototype.triggerManualFocusForContinuous = function () { return tslib_1.__awaiter(this, void 0, void 0, function () { var _a; var _this = this; return tslib_1.__generator(this, function (_b) { switch (_b.label) { case 0: this.manualToAutofocusResumeTimeout = window.setTimeout(function () { return tslib_1.__awaiter(_this, void 0, void 0, function () { return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.triggerFocusMode(MeteringMode.CONTINUOUS)]; case 1: _a.sent(); return [2 /*return*/]; } }); }); }, BarcodePickerCameraManager.manualToAutofocusResumeTimeoutMs); _b.label = 1; case 1: _b.trys.push([1, 3, , 4]); return [4 /*yield*/, this.triggerFocusMode(MeteringMode.CONTINUOUS)]; case 2: _b.sent(); this.manualFocusWaitTimeout = window.setTimeout(function () { return tslib_1.__awaiter(_this, void 0, void 0, function () { return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.triggerFocusMode(MeteringMode.MANUAL)]; case 1: _a.sent(); return [2 /*return*/]; } }); }); }, BarcodePickerCameraManager.manualFocusWaitTimeoutMs); return [3 /*break*/, 4]; case 3: _a = _b.sent(); return [3 /*break*/, 4]; case 4: return [2 /*return*/]; } }); }); }; BarcodePickerCameraManager.prototype.triggerManualFocusForSingleShot = function () { return tslib_1.__awaiter(this, void 0, void 0, function () { var _a; var _this = this; return tslib_1.__generator(this, function (_b) { switch (_b.label) { case 0: window.clearInterval(this.autofocusInterval); this.manualToAutofocusResumeTimeout = window.setTimeout(function () { _this.autofocusInterval = window.setInterval(_this.triggerAutoFocus.bind(_this), BarcodePickerCameraManager.autofocusIntervalMs); }, BarcodePickerCameraManager.manualToAutofocusResumeTimeoutMs); _b.label = 1; case 1: _b.trys.push([1, 3, , 4]); return [4 /*yield*/, this.triggerFocusMode(MeteringMode.SINGLE_SHOT)]; case 2: _b.sent(); return [3 /*break*/, 4]; case 3: _a = _b.sent(); return [3 /*break*/, 4]; case 4: return [2 /*return*/]; } }); }); }; BarcodePickerCameraManager.prototype.triggerManualFocus = function (event) { return tslib_1.__awaiter(this, void 0, void 0, function () { var focusModeCapability; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: if (event != null) { event.preventDefault(); if (event.type === "touchend" && event.touches.length !== 0) { return [2 /*return*/]; } // Check if we were using pinch-to-zoom if (this.pinchToZoomDistance != null) { this.pinchToZoomDistance = undefined; return [2 /*return*/]; } } window.clearTimeout(this.manualFocusWaitTimeout); window.clearTimeout(this.manualToAutofocusResumeTimeout); if (!(this.mediaStream != null && this.mediaTrackCapabilities != null)) return [3 /*break*/, 4]; focusModeCapability = this.mediaTrackCapabilities.focusMode; if (!(focusModeCapability instanceof Array && focusModeCapability.includes(MeteringMode.SINGLE_SHOT))) return [3 /*break*/, 4]; if (!(focusModeCapability.includes(MeteringMode.CONTINUOUS) && focusModeCapability.includes(MeteringMode.MANUAL))) return [3 /*break*/, 2]; return [4 /*yield*/, this.triggerManualFocusForContinuous()]; case 1: _a.sent(); return [3 /*break*/, 4]; case 2: if (!!focusModeCapability.includes(MeteringMode.CONTINUOUS)) return [3 /*break*/, 4]; return [4 /*yield*/, this.triggerManualFocusForSingleShot()]; case 3: _a.sent(); _a.label = 4; case 4: return [2 /*return*/]; } }); }); }; BarcodePickerCameraManager.prototype.triggerZoomStart = function (event) { if (event == null || event.touches.length !== 2) { return; } event.preventDefault(); this.pinchToZoomDistance = Math.hypot((event.touches[1].screenX - event.touches[0].screenX) / screen.width, (event.touches[1].screenY - event.touches[0].screenY) / screen.height); if (this.mediaStream != null && this.mediaTrackCapabilities != null && this.mediaTrackCapabilities.zoom != null) { var videoTracks = this.mediaStream.getVideoTracks(); // istanbul ignore else if (videoTracks.length !== 0 && typeof videoTracks[0].getConstraints === "function") { this.pinchToZoomInitialZoom = this.mediaTrackCapabilities.zoom.min; var currentConstraints = videoTracks[0].getConstraints(); if (currentConstraints.advanced != null) { var currentZoomConstraint = currentConstraints.advanced.find(function (constraint) { return "zoom" in constraint; }); if (currentZoomConstraint != null && currentZoomConstraint.zoom != null) { this.pinchToZoomInitialZoom = currentZoomConstraint.zoom; } } } } }; BarcodePickerCameraManager.prototype.triggerZoomMove = function (event) { return tslib_1.__awaiter(this, void 0, void 0, function () { return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: if (this.pinchToZoomDistance == null || event == null || event.touches.length !== 2) { return [2 /*return*/]; } event.preventDefault(); return [4 /*yield*/, this.setZoom((Math.hypot((event.touches[1].screenX - event.touches[0].screenX) / screen.width, (event.touches[1].screenY - event.touches[0].screenY) / screen.height) - this.pinchToZoomDistance) * 2, this.pinchToZoomInitialZoom)]; case 1: _a.sent(); return [2 /*return*/]; } }); }); }; BarcodePickerCameraManager.prototype.storeStreamCapabilities = function () { // istanbul ignore else if (this.mediaStream != null) { var videoTracks = this.mediaStream.getVideoTracks(); // istanbul ignore else if (videoTracks.length !== 0 && typeof videoTracks[0].getCapabilities === "function") { this.mediaTrackCapabilities = videoTracks[0].getCapabilities(); } } }; BarcodePickerCameraManager.prototype.setupAutofocus = function () { window.clearTimeout(this.manualFocusWaitTimeout); window.clearTimeout(this.manualToAutofocusResumeTimeout); // istanbul ignore else if (this.mediaStream != null && this.mediaTrackCapabilities != null) { var focusModeCapability = this.mediaTrackCapabilities.focusMode; if (focusModeCapability instanceof Array && !focusModeCapability.includes(MeteringMode.CONTINUOUS) && focusModeCapability.includes(MeteringMode.SINGLE_SHOT)) { window.clearInterval(this.autofocusInterval); this.autofocusInterval = window.setInterval(this.triggerAutoFocus.bind(this), BarcodePickerCameraManager.autofocusIntervalMs); } } }; BarcodePickerCameraManager.prototype.triggerAutoFocus = function () { this.triggerFocusMode(MeteringMode.SINGLE_SHOT).catch( /* istanbul ignore next */ function () { // Ignored }); }; BarcodePickerCameraManager.prototype.triggerFocusMode = function (focusMode) { // istanbul ignore else if (this.mediaStream != null) { var videoTracks = this.mediaStream.getVideoTracks(); if (videoTracks.length !== 0 && typeof videoTracks[0].applyConstraints === "function") { return videoTracks[0].applyConstraints({ advanced: [{ focusMode: focusMode }] }); } } return Promise.reject(undefined); }; BarcodePickerCameraManager.prototype.enableTapToFocusListeners = function () { var _this = this; ["touchend", "mousedown"].forEach(function (eventName) { _this.barcodePickerGui.videoElement.addEventListener(eventName, _this.triggerManualFocusListener); }); }; BarcodePickerCameraManager.prototype.enablePinchToZoomListeners = function () { this.barcodePickerGui.videoElement.addEventListener("touchstart", this.triggerZoomStartListener); this.barcodePickerGui.videoElement.addEventListener("touchmove", this.triggerZoomMoveListener); }; BarcodePickerCameraManager.prototype.disableTapToFocusListeners = function () { var _this = this; ["touchend", "mousedown"].forEach(function (eventName) { _this.barcodePickerGui.videoElement.removeEventListener(eventName, _this.triggerManualFocusListener); }); }; BarcodePickerCameraManager.prototype.disablePinchToZoomListeners = function () { this.barcodePickerGui.videoElement.removeEventListener("touchstart", this.triggerZoomStartListener); this.barcodePickerGui.videoElement.removeEventListener("touchmove", this.triggerZoomMoveListener); }; BarcodePickerCameraManager.prototype.initializeCameraAndCheckUpdatedSettings = function (camera, resolutionFallbackLevel) { return tslib_1.__awaiter(this, void 0, void 0, function () { var _this = this; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: _a.trys.push([0, , 2, 3]); return [4 /*yield*/, this.initializeCamera(camera, resolutionFallbackLevel)]; case 1: _a.sent(); // Check if due to asynchronous behaviour camera settings were changed while camera was initialized if (this.selectedCameraSettings !== this.activeCameraSettings && (this.selectedCameraSettings == null || this.activeCameraSettings == null || Object.keys(this.selectedCameraSettings).some(function (cameraSettingsProperty) { return (_this.selectedCameraSettings[cameraSettingsProperty] !== _this.activeCameraSettings[cameraSettingsProperty]); }))) { this.activeCameraSettings = this.selectedCameraSettings; return [2 /*return*/, this.initializeCameraAndCheckUpdatedSettings(camera, resolutionFallbackLevel)]; } return [3 /*break*/, 3]; case 2: this.cameraInitializationPromise = undefined; return [7 /*endfinally*/]; case 3: return [2 /*return*/]; } }); }); }; BarcodePickerCameraManager.prototype.retryInitializeCameraIfNeeded = function (camera, resolutionFallbackLevel, resolve, reject, error) { if (resolutionFallbackLevel < 6) { return this.initializeCamera(camera, resolutionFallbackLevel + 1) .then(resolve) .catch(reject); } else { return reject(error); } }; BarcodePickerCameraManager.prototype.handleCameraInitializationError = function (error, resolutionFallbackLevel, camera, resolve, reject) { return tslib_1.__awaiter(this, void 0, void 0, function () { var cameras, newCamera; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: // istanbul ignore if if (error.name === "SourceUnavailableError") { error.name = "NotReadableError"; } if (!(error.message === "Invalid constraint" || // tslint:disable-next-line:no-any (error.name === "OverconstrainedError" && error.constraint === "deviceId"))) return [3 /*break*/, 2]; return [4 /*yield*/, cameraAccess_1.CameraAccess.getCameras()]; case 1: cameras = _a.sent(); newCamera = cameras.find(function (currentCamera) { return (currentCamera.label === camera.label && currentCamera.cameraType === camera.cameraType && currentCamera.deviceId !== camera.deviceId); }); if (newCamera == null) { return [2 /*return*/, this.retryInitializeCameraIfNeeded(camera, resolutionFallbackLevel, resolve, reject, error)]; } else { return [2 /*return*/, this.initializeCamera(newCamera, resolutionFallbackLevel) .then(resolve) .catch(reject)]; } _a.label = 2; case 2: if (["PermissionDeniedError", "PermissionDismissedError", "NotAllowedError", "NotFoundError", "AbortError"].includes(error.name)) { // Camera is not accessible at all return [2 /*return*/, reject(error)]; } return [2 /*return*/, this.retryInitializeCameraIfNeeded(camera, resolutionFallbackLevel, resolve, reject, error)]; } }); }); }; BarcodePickerCameraManager.prototype.initializeCamera = function (camera, resolutionFallbackLevel) { var _this = this; if (resolutionFallbackLevel === void 0) { resolutionFallbackLevel = 0; } if (camera == null) { return Promise.reject(new customError_1.CustomError(BarcodePickerCameraManager.noCameraErrorParameters)); } this.stopStream(); this.torchEnabled = false; this.barcodePickerGui.setTorchTogglerVisible(false); return new Promise(function (resolve, reject) { return tslib_1.__awaiter(_this, void 0, void 0, function () { var stream, mediaTrackSettings, error_1; var _this = this; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: _a.trys.push([0, 2, , 4]); return [4 /*yield*/, cameraAccess_1.CameraAccess.accessCameraStream(resolutionFallbackLevel, camera)]; case 1: stream = _a.sent(); // Detect weird browser behaviour that on unsupported resolution returns a 2x2 video instead if (typeof stream.getTracks()[0].getSettings === "function") { mediaTrackSettings = stream.getTracks()[0].getSettings(); if (mediaTrackSettings.width != null && mediaTrackSettings.height != null && (mediaTrackSettings.width === 2 || mediaTrackSettings.height === 2)) { if (resolutionFallbackLevel === 6) { return [2 /*return*/, reject(new customError_1.CustomError({ name: "NotReadableError", message: "Could not initialize camera correctly" }))]; } else { return [2 /*return*/, this.initializeCamera(camera, resolutionFallbackLevel + 1) .then(resolve) .catch(reject)]; } } } this.mediaStream = stream; this.mediaStream.getVideoTracks().forEach(function (track) { // Reinitialize camera on weird pause/resumption coming from the OS // This will add the listener only once in the case of multiple calls, identical listeners are ignored track.addEventListener("unmute", _this.videoTrackUnmuteListener); }); // This will add the listener only once in the case of multiple calls, identical listeners are ignored this.barcodePickerGui.videoElement.addEventListener("loadedmetadata", this.postStreamInitializationListener); if (this.tapToFocusEnabled) { this.enableTapToFocusListeners(); } if (this.pinchToZoomEnabled) { this.enablePinchToZoomListeners(); } this.resolveInitializeCamera(camera, resolve, reject); this.barcodePickerGui.videoElement.srcObject = stream; this.barcodePickerGui.videoElement.load(); this.barcodePickerGui.playVideo(); return [3 /*break*/, 4]; case 2: error_1 = _a.sent(); return [4 /*yield*/, this.handleCameraInitializationError(error_1, resolutionFallbackLevel, camera, resolve, reject)]; case 3: _a.sent(); return [3 /*break*/, 4]; case 4: return [2 /*return*/]; } }); }); }); }; BarcodePickerCameraManager.prototype.resolveInitializeCamera = function (camera, resolve, reject) { var _this = this; var cameraNotReadableError = new customError_1.CustomError({ name: "NotReadableError", message: "Could not initialize camera correctly" }); window.clearTimeout(this.cameraAccessTimeout); this.cameraAccessTimeout = window.setTimeout(function () { _this.stopStream(); reject(cameraNotReadableError); }, BarcodePickerCameraManager.cameraAccessTimeoutMs); this.barcodePickerGui.videoElement.onresize = function () { _this.updateActiveCameraCurrentResolution(camera); }; this.barcodePickerGui.videoElement.onloadeddata = function () { _this.barcodePickerGui.videoElement.onloadeddata = null; window.clearTimeout(_this.cameraAccessTimeout); // Detect weird browser behaviour that on unsupported resolution returns a 2x2 video instead // Also detect failed camera access with no error but also no video stream provided if (_this.barcodePickerGui.videoElement.videoWidth > 2 && _this.barcodePickerGui.videoElement.videoHeight > 2 && _this.barcodePickerGui.videoElement.currentTime > 0) { if (camera.deviceId !== "") { _this.updateActiveCameraCurrentResolution(camera); } return resolve(); } var cameraMetadataCheckStartTime = performance.now(); window.clearInterval(_this.cameraMetadataCheckInterval); _this.cameraMetadataCheckInterval = window.setInterval(function () { // Detect weird browser behaviour that on unsupported resolution returns a 2x2 video instead // Also detect failed camera access with no error but also no video stream provided if (_this.barcodePickerGui.videoElement.videoWidth === 2 || _this.barcodePickerGui.videoElement.videoHeight === 2 || _this.barcodePickerGui.videoElement.currentTime === 0) { if (performance.now() - cameraMetadataCheckStartTime > BarcodePickerCameraManager.cameraMetadataCheckTimeoutMs) { window.clearInterval(_this.cameraMetadataCheckInterval); _this.stopStream(); return reject(cameraNotReadableError); } return; } window.clearInterval(_this.cameraMetadataCheckInterval); if (camera.deviceId !== "") { _this.updateActiveCameraCurrentResolution(camera); _this.barcodePickerGui.videoElement.dispatchEvent(new Event("canplay")); } return resolve(); }, BarcodePickerCameraManager.cameraMetadataCheckIntervalMs); }; }; BarcodePickerCameraManager.cameraAccessTimeoutMs = 4000; BarcodePickerCameraManager.cameraMetadataCheckTimeoutMs = 4000; BarcodePickerCameraManager.cameraMetadataCheckIntervalMs = 50; BarcodePickerCameraManager.getCapabilitiesTimeoutMs = 500; BarcodePickerCameraManager.autofocusIntervalMs = 1500; BarcodePickerCameraManager.manualToAutofocusResumeTimeoutMs = 5000; BarcodePickerCameraManager.manualFocusWaitTimeoutMs = 400; BarcodePickerCameraManager.noCameraErrorParameters = { name: "NoCameraAvailableError", message: "No camera available" }; return BarcodePickerCameraManager; }(cameraManager_1.CameraManager)); exports.BarcodePickerCameraManager = BarcodePickerCameraManager; //# sourceMappingURL=barcodePickerCameraManager.js.map