From 6caea95e572aad5830f0b6dd9ce2c0b0094e2a9d Mon Sep 17 00:00:00 2001 From: Christoph Oberhofer Date: Sun, 25 Jan 2015 21:07:14 +0100 Subject: [PATCH] Configuring camera-resolution --- README.md | 7 +++- dist/quagga.js | 75 +++++++++++++++++++++++++------------- spec/camera_access.spec.js | 4 +- src/camera_access.js | 70 ++++++++++++++++++++++++----------- src/config.js | 7 +++- src/quagga.js | 2 +- test-main.js | 3 +- 7 files changed, 115 insertions(+), 53 deletions(-) diff --git a/README.md b/README.md index fc18f52..cd553f2 100644 --- a/README.md +++ b/README.md @@ -167,7 +167,12 @@ The default `config` object is set as followed: ```javascript { inputStream: { name: "Live", - type: "LiveStream" + type: "LiveStream", + constraints: { + width: 640, + height: 480, + facing: "environment" + } }, tracking: false, debug: false, diff --git a/dist/quagga.js b/dist/quagga.js index 76a435e..65aab97 100644 --- a/dist/quagga.js +++ b/dist/quagga.js @@ -6810,7 +6810,12 @@ define('html_utils',[], function() { define('config',[],function(){ var config = { inputStream: { name: "Live", - type: "LiveStream" + type: "LiveStream", + constraints: { + width: 640, + height: 480, + facing: "environment" // or user + } }, tracking: false, debug: false, @@ -6943,7 +6948,7 @@ define('events',[],function() { /* jshint undef: true, unused: true, browser:true, devel: true */ /* global define, MediaStreamTrack */ -define('camera_access',[],function() { +define('camera_access',["html_utils"], function(HtmlUtils) { var streamRef; @@ -6996,43 +7001,63 @@ define('camera_access',[],function() { }); } - /** - * Requests the back-facing camera of the user. The callback is called - * whenever the stream is ready to be consumed, or if an error occures. - * @param {Object} video - * @param {Object} callback - */ - function request(video, callback) { + function normalizeConstraints(config, cb) { + var constraints = { + audio: false, + video: true + }, + videoConstraints = HtmlUtils.mergeObjects({ + width: 640, + height: 480, + facing: "environment" + }, config); + if ( typeof MediaStreamTrack.getSources !== 'undefined') { MediaStreamTrack.getSources(function(sourceInfos) { var videoSourceId; for (var i = 0; i != sourceInfos.length; ++i) { var sourceInfo = sourceInfos[i]; - if (sourceInfo.kind == "video" && sourceInfo.facing == "environment") { + if (sourceInfo.kind == "video" && sourceInfo.facing == videoConstraints.facing) { videoSourceId = sourceInfo.id; } } - var constraints = { - audio : false, - video : { - optional : [{ - sourceId : videoSourceId - }] - } + constraints.video = { + mandatory: { + minWidth: videoConstraints.width, + minHeight: videoConstraints.height + }, + optional: [{ + sourceId: videoSourceId + }] }; - initCamera(constraints, video, callback); + return cb(constraints); }); } else { - initCamera({ - video : true, - audio : false - }, video, callback); + constraints.video = { + mediaSource: "camera", + width: { min: videoConstraints.width, max: videoConstraints.width }, + height: { min: videoConstraints.height, max: videoConstraints.height }, + require: ["width", "height"] + }; + return cb(constraints); } } + /** + * Requests the back-facing camera of the user. The callback is called + * whenever the stream is ready to be consumed, or if an error occures. + * @param {Object} video + * @param {Object} callback + */ + function request(video, videoConstraints, callback) { + normalizeConstraints(videoConstraints, function(constraints) { + initCamera(constraints, video, callback); + }); + } + return { - request : function(video, callback) { - request(video, callback); + request : function(video, constraints, callback) { + request(video, constraints, callback); }, release : function() { var tracks = streamRef && streamRef.getVideoTracks(); @@ -8232,7 +8257,7 @@ function(Code128Reader, EANReader, InputStream, ImageWrapper, BarcodeLocator, Ba $viewport.appendChild(video); } _inputStream = InputStream.createLiveStream(video); - CameraAccess.request(video, function(err) { + CameraAccess.request(video, _config.inputStream.constraints, function(err) { if (!err) { _inputStream.trigger("canrecord"); } else { diff --git a/spec/camera_access.spec.js b/spec/camera_access.spec.js index 6c2df66..2254c4b 100644 --- a/spec/camera_access.spec.js +++ b/spec/camera_access.spec.js @@ -52,7 +52,7 @@ define(['camera_access'], function(CameraAccess){ describe('request', function() { it('should request the camera', function(done) { - CameraAccess.request(video, function() { + CameraAccess.request(video, {}, function() { expect(navigator.getUserMedia.calledOnce).to.equal(true); expect(video.src).to.deep.equal(stream); done(); @@ -62,7 +62,7 @@ define(['camera_access'], function(CameraAccess){ describe('release', function() { it('should release the camera', function(done) { - CameraAccess.request(video, function() { + CameraAccess.request(video, {}, function() { expect(video.src).to.deep.equal(stream); CameraAccess.release(); expect(video.src.getVideoTracks()).to.have.length(1); diff --git a/src/camera_access.js b/src/camera_access.js index c11b5ac..f97504a 100644 --- a/src/camera_access.js +++ b/src/camera_access.js @@ -1,7 +1,7 @@ /* jshint undef: true, unused: true, browser:true, devel: true */ /* global define, MediaStreamTrack */ -define(function() { +define(["html_utils"], function(HtmlUtils) { "use strict"; var streamRef; @@ -20,7 +20,7 @@ define(function() { } /** - * Tries to attach the camer-stream to a given video-element + * Tries to attach the camera-stream to a given video-element * and calls the callback function when the content is ready * @param {Object} constraints * @param {Object} video @@ -55,42 +55,68 @@ define(function() { } /** - * Requests the back-facing camera of the user. The callback is called - * whenever the stream is ready to be consumed, or if an error occures. - * @param {Object} video - * @param {Object} callback + * Normalizes the incoming constraints to satisfy the current browser + * @param config + * @param cb Callback which is called whenever constraints are created + * @returns {*} */ - function request(video, callback) { + function normalizeConstraints(config, cb) { + var constraints = { + audio: false, + video: true + }, + videoConstraints = HtmlUtils.mergeObjects({ + width: 640, + height: 480, + facing: "environment" + }, config); + if ( typeof MediaStreamTrack.getSources !== 'undefined') { MediaStreamTrack.getSources(function(sourceInfos) { var videoSourceId; for (var i = 0; i != sourceInfos.length; ++i) { var sourceInfo = sourceInfos[i]; - if (sourceInfo.kind == "video" && sourceInfo.facing == "environment") { + if (sourceInfo.kind == "video" && sourceInfo.facing == videoConstraints.facing) { videoSourceId = sourceInfo.id; } } - var constraints = { - audio : false, - video : { - optional : [{ - sourceId : videoSourceId - }] - } + constraints.video = { + mandatory: { + minWidth: videoConstraints.width, + minHeight: videoConstraints.height + }, + optional: [{ + sourceId: videoSourceId + }] }; - initCamera(constraints, video, callback); + return cb(constraints); }); } else { - initCamera({ - video : true, - audio : false - }, video, callback); + constraints.video = { + mediaSource: "camera", + width: { min: videoConstraints.width, max: videoConstraints.width }, + height: { min: videoConstraints.height, max: videoConstraints.height }, + require: ["width", "height"] + }; + return cb(constraints); } } + /** + * Requests the back-facing camera of the user. The callback is called + * whenever the stream is ready to be consumed, or if an error occures. + * @param {Object} video + * @param {Object} callback + */ + function request(video, videoConstraints, callback) { + normalizeConstraints(videoConstraints, function(constraints) { + initCamera(constraints, video, callback); + }); + } + return { - request : function(video, callback) { - request(video, callback); + request : function(video, constraints, callback) { + request(video, constraints, callback); }, release : function() { var tracks = streamRef && streamRef.getVideoTracks(); diff --git a/src/config.js b/src/config.js index d090951..6cf894e 100644 --- a/src/config.js +++ b/src/config.js @@ -5,7 +5,12 @@ define(function(){ var config = { inputStream: { name: "Live", - type: "LiveStream" + type: "LiveStream", + constraints: { + width: 640, + height: 480, + facing: "environment" // or user + } }, tracking: false, debug: false, diff --git a/src/quagga.js b/src/quagga.js index 08e3012..832e6e6 100644 --- a/src/quagga.js +++ b/src/quagga.js @@ -63,7 +63,7 @@ function(Code128Reader, EANReader, InputStream, ImageWrapper, BarcodeLocator, Ba $viewport.appendChild(video); } _inputStream = InputStream.createLiveStream(video); - CameraAccess.request(video, function(err) { + CameraAccess.request(video, _config.inputStream.constraints, function(err) { if (!err) { _inputStream.trigger("canrecord"); } else { diff --git a/test-main.js b/test-main.js index 9606297..79cd514 100644 --- a/test-main.js +++ b/test-main.js @@ -21,7 +21,8 @@ require.config({ 'glMatrixAddon': 'src/glMatrixAddon', 'cluster': 'src/cluster', 'camera_access': 'src/camera_access', - 'events': 'src/events' + 'events': 'src/events', + 'html_utils': 'src/html_utils' }, deps: allTestFiles, callback: window.__karma__.start