mirror of
https://github.com/serratus/quaggaJS.git
synced 2026-08-12 21:21:42 +08:00
Merged master
This commit is contained in:
@@ -60,6 +60,11 @@ The following APIs need to be implemented in your browser:
|
|||||||
In addition to the APIs mentioned above:
|
In addition to the APIs mentioned above:
|
||||||
- [MediaDevices](http://caniuse.com/#feat=stream)
|
- [MediaDevices](http://caniuse.com/#feat=stream)
|
||||||
|
|
||||||
|
__Important:__ Accessing `getUserMedia` requires a secure origin in most
|
||||||
|
browsers, meaning that `http://` can only be used on `localhost`. All other
|
||||||
|
hostnames need to be served via `https://`. You can find more information in the
|
||||||
|
[Chrome M47 WebRTC Release Notes](https://groups.google.com/forum/#!topic/discuss-webrtc/sq5CVmY69sc).
|
||||||
|
|
||||||
## <a name="installing">Installing</a>
|
## <a name="installing">Installing</a>
|
||||||
|
|
||||||
QuaggaJS can be installed using __npm__, __bower__, or by including it with
|
QuaggaJS can be installed using __npm__, __bower__, or by including it with
|
||||||
|
|||||||
Vendored
+751
-1098
File diff suppressed because it is too large
Load Diff
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+4
-4
File diff suppressed because one or more lines are too long
+754
-1102
File diff suppressed because it is too large
Load Diff
+1
-1
File diff suppressed because one or more lines are too long
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "quagga",
|
"name": "quagga",
|
||||||
"version": "1.0.0-beta.1",
|
"version": "1.0.0-beta.2",
|
||||||
"description": "An advanced barcode-scanner written in JavaScript",
|
"description": "An advanced barcode-scanner written in JavaScript",
|
||||||
"main": "lib/quagga.js",
|
"main": "lib/quagga.js",
|
||||||
"browser": "dist/quagga.min.js",
|
"browser": "dist/quagga.min.js",
|
||||||
@@ -109,6 +109,6 @@
|
|||||||
"lodash": "^4.6.1",
|
"lodash": "^4.6.1",
|
||||||
"ndarray": "^1.0.18",
|
"ndarray": "^1.0.18",
|
||||||
"ndarray-linear-interpolate": "^1.0.0",
|
"ndarray-linear-interpolate": "^1.0.0",
|
||||||
"webrtc-adapter": "^1.3.0"
|
"webrtc-adapter": "^2.0.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+21
-47
@@ -1,4 +1,4 @@
|
|||||||
import {merge, pick, omit} from 'lodash';
|
import {pick} from 'lodash';
|
||||||
|
|
||||||
var streamRef;
|
var streamRef;
|
||||||
|
|
||||||
@@ -32,19 +32,24 @@ function waitForVideo(video) {
|
|||||||
* @param {Object} video
|
* @param {Object} video
|
||||||
*/
|
*/
|
||||||
function initCamera(video, constraints) {
|
function initCamera(video, constraints) {
|
||||||
return navigator.mediaDevices.getUserMedia(constraints)
|
if (navigator.mediaDevices
|
||||||
.then((stream) => {
|
&& typeof navigator.mediaDevices.getUserMedia === 'function') {
|
||||||
return new Promise((resolve) => {
|
return navigator.mediaDevices
|
||||||
streamRef = stream;
|
.getUserMedia(constraints)
|
||||||
video.setAttribute("autoplay", 'true');
|
.then((stream) => {
|
||||||
video.srcObject = stream;
|
return new Promise((resolve) => {
|
||||||
video.addEventListener('loadedmetadata', () => {
|
streamRef = stream;
|
||||||
video.play();
|
video.setAttribute("autoplay", 'true');
|
||||||
resolve();
|
video.srcObject = stream;
|
||||||
});
|
video.addEventListener('loadedmetadata', () => {
|
||||||
});
|
video.play();
|
||||||
})
|
resolve();
|
||||||
.then(waitForVideo.bind(null, video));
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.then(waitForVideo.bind(null, video));
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error('getUserMedia is not defined'));
|
||||||
}
|
}
|
||||||
|
|
||||||
function deprecatedConstraints(videoConstraints) {
|
function deprecatedConstraints(videoConstraints) {
|
||||||
@@ -63,47 +68,16 @@ function deprecatedConstraints(videoConstraints) {
|
|||||||
return normalized;
|
return normalized;
|
||||||
}
|
}
|
||||||
|
|
||||||
function applyCameraFacing(facing, constraints) {
|
|
||||||
if (typeof constraints.video.deviceId === 'string' && constraints.video.deviceId.length > 0) {
|
|
||||||
return Promise.resolve({
|
|
||||||
...constraints,
|
|
||||||
video: {
|
|
||||||
...omit(constraints.video, "facingMode")
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else if (!facing) {
|
|
||||||
return Promise.resolve(constraints);
|
|
||||||
}
|
|
||||||
if ( typeof MediaStreamTrack !== 'undefined' &&
|
|
||||||
typeof MediaStreamTrack.getSources !== 'undefined') {
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
MediaStreamTrack.getSources((sourceInfos) => {
|
|
||||||
const videoSource = sourceInfos.filter((sourceInfo) => (
|
|
||||||
sourceInfo.kind === "video" && sourceInfo.facing === facing
|
|
||||||
))[0];
|
|
||||||
if (videoSource) {
|
|
||||||
return resolve(merge({}, constraints,
|
|
||||||
{video: {deviceId: videoSource.id}}));
|
|
||||||
}
|
|
||||||
return resolve(constraints);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return Promise.resolve(merge({}, constraints, {video: {facingMode: facing}}));
|
|
||||||
}
|
|
||||||
|
|
||||||
function pickConstraints(videoConstraints) {
|
function pickConstraints(videoConstraints) {
|
||||||
const constraints = {
|
return {
|
||||||
audio: false,
|
audio: false,
|
||||||
video: deprecatedConstraints(videoConstraints)
|
video: deprecatedConstraints(videoConstraints)
|
||||||
};
|
};
|
||||||
return applyCameraFacing(constraints.video.facingMode, constraints);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
request: function(video, videoConstraints) {
|
request: function(video, videoConstraints) {
|
||||||
return pickConstraints(videoConstraints)
|
return initCamera(video, pickConstraints(videoConstraints));
|
||||||
.then(initCamera.bind(null, video));
|
|
||||||
},
|
},
|
||||||
release: function() {
|
release: function() {
|
||||||
var tracks = streamRef && streamRef.getVideoTracks();
|
var tracks = streamRef && streamRef.getVideoTracks();
|
||||||
|
|||||||
@@ -91,46 +91,14 @@ describe("CameraAccess", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('facingMode fallback in Chrome', () => {
|
it('should release the camera', function (done) {
|
||||||
beforeEach(() => {
|
CameraAccess.request(video, {})
|
||||||
window.MediaStreamTrack.getSources = (cb) => {
|
.then(function () {
|
||||||
return cb([
|
expect(video.srcObject).to.deep.equal(stream);
|
||||||
{kind: "video", facing: "environment", id: "environment"},
|
CameraAccess.release();
|
||||||
{kind: "audio", id: "audio"},
|
expect(video.srcObject.getVideoTracks()).to.have.length(1);
|
||||||
{kind: "video", facing: "user", id: "user"}
|
expect(video.srcObject.getVideoTracks()[0].stop.calledOnce).to.equal(true);
|
||||||
]);
|
done();
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
window.MediaStreamTrack = {};
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should set deviceId in case facingMode is not supported", (done) => {
|
|
||||||
CameraAccess.request(video, {
|
|
||||||
facing: "user"
|
|
||||||
})
|
|
||||||
.then(function () {
|
|
||||||
const call = navigator.mediaDevices.getUserMedia.getCall(0),
|
|
||||||
args = call.args;
|
|
||||||
expect(call).to.be.defined;
|
|
||||||
expect(args[0].video.facingMode).not.to.be.defined;
|
|
||||||
expect(args[0].video.deviceId).to.equal("user");
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('release', function () {
|
|
||||||
it('should release the camera', function (done) {
|
|
||||||
CameraAccess.request(video, {})
|
|
||||||
.then(function () {
|
|
||||||
expect(video.srcObject).to.deep.equal(stream);
|
|
||||||
CameraAccess.release();
|
|
||||||
expect(video.srcObject.getVideoTracks()).to.have.length(1);
|
|
||||||
expect(video.srcObject.getVideoTracks()[0].stop.calledOnce).to.equal(true);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user