mirror of
https://github.com/eliasstepanik/vdo.ninja.git
synced 2026-01-14 15:18:28 +00:00
Delete test.js
This commit is contained in:
parent
93b1d8f0c7
commit
c809a345f2
413
misc/test.js
413
misc/test.js
@ -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));
|
||||
Loading…
x
Reference in New Issue
Block a user