diff --git a/misc/test.js b/misc/test.js deleted file mode 100644 index 54f53ba..0000000 --- a/misc/test.js +++ /dev/null @@ -1,413 +0,0 @@ -var Camera = {"Type":{"FRONT":"front","BACK":"back"}}; - -var CameraAccess = new (function (CameraAccess) { - const backCameraKeywords = [ - "rear", - "back", - "rück", - "arrière", - "trasera", - "trás", - "traseira", - "posteriore", - "后面", - "後面", - "背面", - "后置", - "後置", - "背置", - "задней", - "الخلفية", - "후", - "arka", - "achterzijde", - "หลัง", - "baksidan", - "bagside", - "sau", - "bak", - "tylny", - "takakamera", - "belakang", - "אחורית", - "πίσω", - "spate", - "hátsó", - "zadní", - "darrere", - "zadná", - "задня", - "stražnja", - "belakang", - "बैक" - ]; - const cameraObjects = new Map(); - let getCamerasPromise; - /** - * @hidden - * - * @param label The camera label. - * @returns Whether the label mentions the camera being a back-facing one. - */ - function isBackCameraLabel(label) { - const lowercaseLabel = label.toLowerCase(); - return backCameraKeywords.some(keyword => { - return lowercaseLabel.includes(keyword); - }); - } - /** - * Adjusts the cameras' type classification based on the given currently active video stream: - * If the stream comes from an environment-facing camera, the camera is marked to be a back-facing camera - * and the other cameras to be of other types accordingly (if they are not correctly set already). - * - * The method returns the currently active camera if it's actually the main (back or only) camera in use. - * - * @param mediaStreamTrack The currently active `MediaStreamTrack`. - * @param cameras The array of available [[Camera]] objects. - * @returns Whether the stream was actually from the main camera. - */ - function adjustCamerasFromMainCameraStream(mediaStreamTrack, cameras) { - let mediaTrackSettings; - if (typeof mediaStreamTrack.getSettings === "function") { - mediaTrackSettings = mediaStreamTrack.getSettings(); - } - const activeCamera = cameras.find(camera => { - return ((mediaTrackSettings != null && camera.deviceId === mediaTrackSettings.deviceId) || - camera.label === mediaStreamTrack.label); - }); - if (activeCamera !== undefined) { - const activeCameraIsBackFacing = (mediaTrackSettings != null && mediaTrackSettings.facingMode === "environment") || - isBackCameraLabel(mediaStreamTrack.label); - let activeCameraIsMainBackCamera = activeCameraIsBackFacing; - // TODO: also correct camera types when active camera is not back-facing - if (activeCameraIsBackFacing && cameras.length > 1) { - // Correct camera types if needed - cameras.forEach(camera => { - if (camera.deviceId === activeCamera.deviceId) { - // tslint:disable-next-line:no-any - camera.cameraType = Camera.Type.BACK; - } - else if (!isBackCameraLabel(camera.label)) { - // tslint:disable-next-line:no-any - camera.cameraType = Camera.Type.FRONT; - } - }); - const mainBackCamera = cameras - .filter(camera => { - return camera.cameraType === Camera.Type.BACK; - }) - .sort((camera1, camera2) => { - return camera1.label.localeCompare(camera2.label); - })[0]; - activeCameraIsMainBackCamera = activeCamera.deviceId === mainBackCamera.deviceId; - } - if (cameras.length === 1 || activeCameraIsMainBackCamera) { - return activeCamera; - } - } - return undefined; - } - CameraAccess.adjustCamerasFromMainCameraStream = adjustCamerasFromMainCameraStream; - /** - * @param devices The list of available devices. - * @returns The extracted list of camera objects initialized from the given devices. - */ - function extractCamerasFromDevices(devices) { - const cameras = devices - .filter(device => { - return device.kind === "videoinput"; - }) - .map(videoDevice => { - if (cameraObjects.has(videoDevice.deviceId)) { - return cameraObjects.get(videoDevice.deviceId); - } - const label = videoDevice.label != null ? videoDevice.label : ""; - const camera = { - deviceId: videoDevice.deviceId, - label, - cameraType: isBackCameraLabel(label) ? Camera.Type.BACK : Camera.Type.FRONT - }; - if (label !== "") { - cameraObjects.set(videoDevice.deviceId, camera); - } - return camera; - }); - if (cameras.length > 1 && - !cameras.some(camera => { - return camera.cameraType === Camera.Type.BACK; - })) { - // Check if cameras are labeled with resolution information, take the higher-resolution one in that case - // Otherwise pick the last camera - let backCameraIndex = cameras.length - 1; - const cameraResolutions = cameras.map(camera => { - const match = camera.label.match(/\b([0-9]+)MP?\b/i); - if (match != null) { - return parseInt(match[1], 10); - } - return NaN; - }); - if (!cameraResolutions.some(cameraResolution => { - return isNaN(cameraResolution); - })) { - backCameraIndex = cameraResolutions.lastIndexOf(Math.max(...cameraResolutions)); - } - // tslint:disable-next-line:no-any - cameras[backCameraIndex].cameraType = Camera.Type.BACK; - } - return cameras; - } - /** - * Get a list of cameras (if any) available on the device, a camera access permission is requested to the user - * the first time this method is called if needed. - * - * Depending on device features and user permissions for camera access, any of the following errors - * could be the rejected result of the returned promise: - * - `UnsupportedBrowserError` - * - `PermissionDeniedError` - * - `NotAllowedError` - * - `NotFoundError` - * - `AbortError` - * - `NotReadableError` - * - `InternalError` - * - * @returns A promise resolving to the array of available [[Camera]] objects (could be empty). - */ - function getCameras() { - if (getCamerasPromise != null) { - return getCamerasPromise; - } - const accessPermissionPromise = new Promise((resolve, reject) => { - return enumerateDevices() - .then(devices => { - if (devices - .filter(device => { - return device.kind === "videoinput"; - }) - .every(device => { - return device.label === ""; - })) { - resolve(navigator.mediaDevices.getUserMedia({ - video: true, - audio: false - })); - } - else { - resolve(); - } - }) - .catch(reject); - }); - getCamerasPromise = new Promise(async (resolve, reject) => { - let stream; - try { - stream = await accessPermissionPromise; - const devices = await enumerateDevices(); - const cameras = extractCamerasFromDevices(devices); - console.debug("Camera list: ", ...cameras); - return resolve(cameras); - } - catch (error) { - // istanbul ignore if - if (error.name === "SourceUnavailableError") { - error.name = "NotReadableError"; - } - return reject(error); - } - finally { - // istanbul ignore else - if (stream != null) { - stream.getVideoTracks().forEach(track => { - track.stop(); - }); - } - getCamerasPromise = undefined; - } - }); - return getCamerasPromise; - } - CameraAccess.getCameras = getCameras; - /** - * Call `navigator.mediaDevices.getUserMedia` asynchronously in a `setTimeout` call. - * - * @param getUserMediaParams The parameters for the `navigator.mediaDevices.getUserMedia` call. - * @returns A promise resolving when the camera is accessed. - */ - function getUserMediaDelayed(getUserMediaParams) { - console.debug("Camera access:", getUserMediaParams.video); - return new Promise((resolve, reject) => { - window.setTimeout(() => { - navigator.mediaDevices - .getUserMedia(getUserMediaParams) - .then(resolve) - .catch(reject); - }, 0); - }); - } - /** - * Get the *getUserMedia* *video* parameters to be used given a resolution fallback level and the browser used. - * - * @param resolutionFallbackLevel The number representing the wanted resolution, from 0 to 6, - * resulting in higher to lower video resolutions. - * @param isSafariBrowser Whether the browser is *Safari*. - * @returns The resulting *getUserMedia* *video* parameters. - */ - function getUserMediaVideoParams(resolutionFallbackLevel, isSafariBrowser) { - switch (resolutionFallbackLevel) { - case 0: - if (isSafariBrowser) { - return { - width: { min: 1400, ideal: 1920, max: 1920 }, - height: { min: 900, ideal: 1080, max: 1440 } - }; - } - else { - return { - width: { min: 1400, ideal: 1920, max: 1920 }, - height: { min: 900, ideal: 1440, max: 1440 } - }; - } - case 1: - if (isSafariBrowser) { - return { - width: { min: 1200, ideal: 1600, max: 1920 }, - height: { min: 900, ideal: 1080, max: 1200 } - }; - } - else { - return { - width: { min: 1200, ideal: 1920, max: 1920 }, - height: { min: 900, ideal: 1200, max: 1200 } - }; - } - case 2: - if (isSafariBrowser) { - return { - width: { min: 1080, ideal: 1600, max: 1920 }, - height: { min: 900, ideal: 900, max: 1080 } - }; - } - else { - return { - width: { min: 1080, ideal: 1920, max: 1920 }, - height: { min: 900, ideal: 1080, max: 1080 } - }; - } - case 3: - if (isSafariBrowser) { - return { - width: { min: 960, ideal: 1280, max: 1440 }, - height: { min: 480, ideal: 720, max: 960 } - }; - } - else { - return { - width: { min: 960, ideal: 1280, max: 1440 }, - height: { min: 480, ideal: 960, max: 960 } - }; - } - case 4: - if (isSafariBrowser) { - return { - width: { min: 720, ideal: 1024, max: 1440 }, - height: { min: 480, ideal: 768, max: 768 } - }; - } - else { - return { - width: { min: 720, ideal: 1280, max: 1440 }, - height: { min: 480, ideal: 720, max: 768 } - }; - } - case 5: - if (isSafariBrowser) { - return { - width: { min: 640, ideal: 800, max: 1440 }, - height: { min: 480, ideal: 600, max: 720 } - }; - } - else { - return { - width: { min: 640, ideal: 960, max: 1440 }, - height: { min: 480, ideal: 720, max: 720 } - }; - } - default: - return {}; - } - } - /** - * Try to access a given camera for video input at the given resolution level. - * @param resolutionFallbackLevel The number representing the wanted resolution, from 0 to 6, - * resulting in higher to lower video resolutions. - * @param camera The camera to try to access for video input. - * @returns A promise resolving to the `MediaStream` object coming from the accessed camera. - */ - function accessCameraStream(resolutionFallbackLevel, camera) { - var iOS = !!navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform); - const getUserMediaParams = { - audio: false, - video: getUserMediaVideoParams(resolutionFallbackLevel, iOS) - }; - if (camera.deviceId === "") { - getUserMediaParams.video.facingMode = { - ideal: camera.cameraType === Camera.Type.BACK ? "environment" : "user" - }; - } - else { - getUserMediaParams.video.deviceId = { - exact: camera.deviceId - }; - } - return (getUserMediaDelayed(getUserMediaParams), getUserMediaParams); - } - CameraAccess.accessCameraStream = accessCameraStream; - /** - * Get a list of available devices in a cross-browser compatible way. - * @returns A promise resolving to the `MediaDeviceInfo` array of all available devices. - */ - function enumerateDevices() { - if (typeof navigator.enumerateDevices === "function") { - return navigator.enumerateDevices(); - } - else if (typeof navigator.mediaDevices === "object" && - typeof navigator.mediaDevices.enumerateDevices === "function") { - return navigator.mediaDevices.enumerateDevices(); - } - else { - return new Promise((resolve, reject) => { - try { - if (window.MediaStreamTrack == null || window.MediaStreamTrack.getSources == null) { - throw new Error(); - } - window.MediaStreamTrack.getSources((devices) => { - resolve(devices - .filter(device => { - return device.kind.toLowerCase() === "video" || device.kind.toLowerCase() === "videoinput"; - }) - .map(device => { - return { - deviceId: device.deviceId != null ? device.deviceId : "", - groupId: device.groupId, - kind: "videoinput", - label: device.label, - toJSON: /* istanbul ignore next */ function () { - return this; - } - }; - })); - }); - } - catch (e) { - console.error(e); - } - }); - } - } - return CameraAccess; -})(CameraAccess || (CameraAccess = {})); - - -CameraAccess.getCameras().then((val) => { - console.log("output:",val); - console.log(CameraAccess.accessCameraStream(1234,val[0])); -}).catch((e)=>console.log(e));