mirror of
https://github.com/serratus/quaggaJS.git
synced 2026-08-12 21:21:42 +08:00
Added orientation-dependent constraints; extended constrain-matching;
This commit is contained in:
@@ -146,11 +146,20 @@ $(function() {
|
|||||||
inputStream: {
|
inputStream: {
|
||||||
type : "LiveStream",
|
type : "LiveStream",
|
||||||
constraints: {
|
constraints: {
|
||||||
width: {ideal: 480},
|
width: {ideal: 800},
|
||||||
height: {ideal: 480},
|
height: {ideal: 800},
|
||||||
zoom: {exact: 2},
|
|
||||||
facingMode: "environment",
|
facingMode: "environment",
|
||||||
aspectRatio: 1,
|
landscape: {
|
||||||
|
width: {ideal: 640},
|
||||||
|
height: {ideal: 480},
|
||||||
|
zoom: 1.5,
|
||||||
|
},
|
||||||
|
portrait: {
|
||||||
|
width: {ideal: 640},
|
||||||
|
height: {ideal: 640},
|
||||||
|
zoom: 1.5,
|
||||||
|
aspectRatio: 1,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
locator: {
|
locator: {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
export const PORTRAIT = "portrait";
|
export const PORTRAIT = "portrait";
|
||||||
export const LANDSCAPE = "landscape";
|
export const LANDSCAPE = "landscape";
|
||||||
|
export const SQUARE = "square";
|
||||||
|
|
||||||
const matchingScreens = {
|
const matchingScreens = {
|
||||||
[PORTRAIT]: /portrait/i,
|
[PORTRAIT]: /portrait/i,
|
||||||
|
|||||||
+136
-16
@@ -1,8 +1,81 @@
|
|||||||
import {clone} from 'lodash';
|
import {clone} from 'lodash';
|
||||||
import {determineOrientation, PORTRAIT} from '../common/device';
|
import {determineOrientation, PORTRAIT, LANDSCAPE, SQUARE} from '../common/device';
|
||||||
import CameraAccess from './camera_access';
|
import CameraAccess from './camera_access';
|
||||||
import {getViewport} from '../common/utils';
|
import {getViewport} from '../common/utils';
|
||||||
|
|
||||||
|
const ConstraintPresets = [
|
||||||
|
{
|
||||||
|
width: 720,
|
||||||
|
height: 1280,
|
||||||
|
}, {
|
||||||
|
width: 540,
|
||||||
|
height: 960,
|
||||||
|
}, {
|
||||||
|
width: 600,
|
||||||
|
height: 800,
|
||||||
|
}, {
|
||||||
|
width: 480,
|
||||||
|
height: 640,
|
||||||
|
}, {
|
||||||
|
width: 1280,
|
||||||
|
height: 720,
|
||||||
|
}, {
|
||||||
|
width: 960,
|
||||||
|
height: 540,
|
||||||
|
}, {
|
||||||
|
width: 800,
|
||||||
|
height: 600,
|
||||||
|
}, {
|
||||||
|
width: 640,
|
||||||
|
height: 480,
|
||||||
|
}, {
|
||||||
|
width: 1280,
|
||||||
|
height: 1280,
|
||||||
|
}, {
|
||||||
|
width: 1080,
|
||||||
|
height: 1080,
|
||||||
|
}, {
|
||||||
|
width: 960,
|
||||||
|
height: 960,
|
||||||
|
}, {
|
||||||
|
width: 800,
|
||||||
|
height: 800,
|
||||||
|
}, {
|
||||||
|
width: 640,
|
||||||
|
height: 640,
|
||||||
|
},
|
||||||
|
].map((preset) => Object.assign({}, preset, {aspectRatio: preset.width / preset.height}));
|
||||||
|
|
||||||
|
function getFilter(aspectRatio) {
|
||||||
|
if (aspectRatio === 1) {
|
||||||
|
return pre => pre.aspectRatio === aspectRatio;
|
||||||
|
} else if (aspectRatio > 1) {
|
||||||
|
return pre => pre.aspectRatio > 1;
|
||||||
|
}
|
||||||
|
return pre => pre.aspectRatio < 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolveMinWidthToAdvanced({aspectRatio, minPixels}) {
|
||||||
|
return [...ConstraintPresets]
|
||||||
|
.filter(getFilter(aspectRatio))
|
||||||
|
.map((pre) => {
|
||||||
|
return {
|
||||||
|
error: Math.abs((pre.width * pre.height) - minPixels),
|
||||||
|
pre,
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.sort(({error: errorA}, {error: errorB}) => {
|
||||||
|
if (errorB > errorA) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (errorB < errorA) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
})
|
||||||
|
.map(({pre}) => pre);
|
||||||
|
}
|
||||||
|
|
||||||
function getOrCreateVideo(source, target) {
|
function getOrCreateVideo(source, target) {
|
||||||
const $viewport = getViewport(target);
|
const $viewport = getViewport(target);
|
||||||
if ($viewport) {
|
if ($viewport) {
|
||||||
@@ -16,21 +89,70 @@ function getOrCreateVideo(source, target) {
|
|||||||
return document.createElement("video");
|
return document.createElement("video");
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fromCamera(constraints) {
|
function constraintToNumber(constraint) {
|
||||||
var orientation = determineOrientation();
|
if (!constraint) {
|
||||||
var videoConstraints = clone(constraints);
|
return null;
|
||||||
if (orientation === PORTRAIT) {
|
}
|
||||||
videoConstraints = Object.assign({}, videoConstraints, {
|
if (typeof constraint === 'number') {
|
||||||
width: videoConstraints.height,
|
return constraint;
|
||||||
height: videoConstraints.width,
|
}
|
||||||
});
|
const {ideal, exact, min, max} = constraint;
|
||||||
|
if (typeof exact !== 'undefined') {
|
||||||
|
return exact;
|
||||||
|
}
|
||||||
|
if (typeof ideal !== 'undefined') {
|
||||||
|
return ideal;
|
||||||
|
}
|
||||||
|
if (typeof min !== 'undefined') {
|
||||||
|
return min;
|
||||||
|
}
|
||||||
|
if (typeof max !== 'undefined') {
|
||||||
|
return max;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (videoConstraints.zoom && videoConstraints.zoom.exact > 1) {
|
return null;
|
||||||
videoConstraints.width.ideal = Math.floor(videoConstraints.width.ideal * videoConstraints.zoom.exact);
|
}
|
||||||
videoConstraints.height.ideal = Math.floor(videoConstraints.height.ideal * videoConstraints.zoom.exact);
|
|
||||||
delete videoConstraints.zoom;
|
function adjustWithZoom(videoConstraints) {
|
||||||
|
const constraints = clone(videoConstraints);
|
||||||
|
const orientation = determineOrientation();
|
||||||
|
|
||||||
|
let zoom = constraintToNumber(constraints.zoom) || 1,
|
||||||
|
width = constraintToNumber(constraints.width),
|
||||||
|
height = constraintToNumber(constraints.height),
|
||||||
|
aspectRatio = constraintToNumber(constraints.aspectRatio) || (width / height);
|
||||||
|
|
||||||
|
if (constraints[orientation]) {
|
||||||
|
zoom = constraintToNumber(constraints[orientation].zoom) || zoom;
|
||||||
|
width = constraintToNumber(constraints[orientation].width) || width;
|
||||||
|
height = constraintToNumber(constraints[orientation].height) || height;
|
||||||
|
aspectRatio = constraintToNumber(constraints[orientation].aspectRatio) || (width / height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (zoom > 1) {
|
||||||
|
width = Math.floor(width * zoom);
|
||||||
|
height = Math.floor(height * zoom);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete constraints.zoom;
|
||||||
|
delete constraints.orientation;
|
||||||
|
delete constraints.landscape;
|
||||||
|
delete constraints.portrait;
|
||||||
|
|
||||||
|
const advanced = resolveMinWidthToAdvanced({minPixels: (width * height), aspectRatio});
|
||||||
|
return {
|
||||||
|
zoom,
|
||||||
|
video: Object.assign({}, constraints, {
|
||||||
|
width: {ideal: advanced[0].width},
|
||||||
|
height: {ideal: advanced[0].height},
|
||||||
|
aspectRatio: {exact: advanced[0].aspectRatio || aspectRatio},
|
||||||
|
advanced,
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function fromCamera(constraints) {
|
||||||
|
var {video: videoConstraints, zoom} = adjustWithZoom(constraints);
|
||||||
console.log(videoConstraints);
|
console.log(videoConstraints);
|
||||||
|
|
||||||
const video = getOrCreateVideo();
|
const video = getOrCreateVideo();
|
||||||
@@ -46,9 +168,7 @@ export function fromCamera(constraints) {
|
|||||||
width: video.videoWidth,
|
width: video.videoWidth,
|
||||||
height: video.videoHeight,
|
height: video.videoHeight,
|
||||||
};
|
};
|
||||||
|
if (zoom > 1) {
|
||||||
if (constraints.zoom && constraints.zoom.exact > 1) {
|
|
||||||
const zoom = constraints.zoom.exact;
|
|
||||||
viewport.width = Math.floor(video.videoWidth / zoom);
|
viewport.width = Math.floor(video.videoWidth / zoom);
|
||||||
viewport.height = Math.floor(video.videoHeight / zoom);
|
viewport.height = Math.floor(video.videoHeight / zoom);
|
||||||
viewport.x = Math.floor((video.videoWidth - viewport.width) / 2);
|
viewport.x = Math.floor((video.videoWidth - viewport.width) / 2);
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import {merge} from 'lodash';
|
|||||||
import CameraAccess from './input/camera_access';
|
import CameraAccess from './input/camera_access';
|
||||||
import * as PixelCapture from './input/PixelCapture';
|
import * as PixelCapture from './input/PixelCapture';
|
||||||
import * as Source from './input/Source';
|
import * as Source from './input/Source';
|
||||||
|
import {PORTRAIT, LANDSCAPE, SQUARE} from './common/device';
|
||||||
|
|
||||||
function fromConfig(pixelCapturer, config) {
|
function fromConfig(pixelCapturer, config) {
|
||||||
const scanner = createScanner(pixelCapturer);
|
const scanner = createScanner(pixelCapturer);
|
||||||
@@ -162,6 +163,11 @@ function createApi() {
|
|||||||
ResultCollector,
|
ResultCollector,
|
||||||
_worker: {
|
_worker: {
|
||||||
createScanner
|
createScanner
|
||||||
|
},
|
||||||
|
Orientation: {
|
||||||
|
PORTRAIT,
|
||||||
|
LANDSCAPE,
|
||||||
|
SQUARE,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user