ImageCapture API support
See original GitHub issueI extended the code (Version 1.0) to support the (currently experimental) MediaStream Image Capture. It creates an ImageCapture from the active VideoStreamTrack and uses ImageCapture#grabFrame() to grab a frame from the stream. By using this API the PhoneSettings can be specified which means that e.g. flash light or focus can be configured. Note that this feature is currently only supported by Chrome for Android when the flag “chrome://flags/#enable-experimental-web-platform-features” is set to “true”.
Example configuration (note inputStream.photoSettings and flag inputStream.imageCapture to enable use of the API):
{
numOfWorkers: 4,
locate: true,
inputStream: {
name: "Live",
type: "LiveStream",
constraints: {
width: {min: 640},
height: {min: 480},
facingMode: "environment",
aspectRatio: {min: 1, max: 2}
},
photoSettings: {
fillLightMode: "torch", /* or "flash" */
focusMode: "continuous"
},
imageCapture: true
},
frequency: 10,
decoder: {
readers: [{
format: "ean_reader",
config: {}
}]
},
locator: {
patchSize: "medium",
halfSample: true
}
}
Modifications:
--- a/src/input/camera_access.js
+++ b/src/input/camera_access.js
@@ -127,6 +127,14 @@
streamRef = null;
},
enumerateVideoDevices,
+ getActiveStreamTrack: function () {
+ if (streamRef) {
+ const tracks = streamRef.getVideoTracks();
+ if (tracks && tracks.length) {
+ return tracks[0];
+ }
+ }
+ },
getActiveStreamLabel: function() {
if (streamRef) {
const tracks = streamRef.getVideoTracks();
--- a/src/input/frame_grabber.js
+++ b/src/input/frame_grabber.js
@@ -69,12 +69,13 @@
* The image-data is converted to gray-scale and then half-sampled if configured.
*/
_that.grab = function() {
+ return new Promise(function (resolve, reject) {
+ inputStream.getFrame()
+ .then(function (frame) {
var doHalfSample = _streamConfig.halfSample,
- frame = inputStream.getFrame(),
drawable = frame,
drawAngle = 0,
ctxData;
- if (drawable) {
adjustCanvasSize(_canvas, _canvasSize);
if (_streamConfig.type === 'ImageStream') {
drawable = frame.img;
@@ -106,10 +107,12 @@
} else {
computeGray(ctxData, _data, _streamConfig);
}
- return true;
- } else {
- return false;
- }
+
+ resolve();
+ }).catch(function (err) {
+ console.error('Error occured while getting frame: ' + err);
+ });
+ })
};
_that.getSize = function() {
--- a/src/input/input_stream.js
+++ b/src/input/input_stream.js
@@ -134,7 +134,9 @@
};
that.getFrame = function() {
- return video;
+ return new Promise(function (resolve) {
+ resolve(video);
+ });
};
return that;
@@ -142,8 +144,27 @@
InputStream.createLiveStream = function(video) {
video.setAttribute("autoplay", true);
- var that = InputStream.createVideoStream(video);
+ var that = InputStream.createVideoStream(video),
+ _imageCapture = null;
+ that.setImageCapture = function (imageCapture) {
+ _imageCapture = imageCapture;
+ };
+
+ that.getFrame = function () {
+ if (_imageCapture !== null) {
+ console.log('Getting frame from ImageCapture...');
+
+ return _imageCapture.grabFrame();
+ } else {
+ console.warn('ImageCapture not set, using video as fallback!');
+
+ return new Promise(function (resolve, reject) {
+ resolve(video);
+ });
+ }
+ };
+
that.ended = function() {
return false;
};
@@ -305,13 +326,9 @@
};
that.getFrame = function() {
- var frame;
-
- if (!loaded){
- return null;
- }
- if (!paused) {
- frame = imgArray[frameIdx];
+ return new Promise(function (resolve, reject) {
+ if (loaded && !paused) {
+ var frame = imgArray[frameIdx];
if (frameIdx < (size - 1)) {
frameIdx++;
} else {
@@ -320,8 +337,11 @@
publishEvent("ended", []);
}, 0);
}
+ resolve(frame);
+ } else {
+ reject();
}
- return frame;
+ });
};
return that;
--- a/src/quagga.js
+++ b/src/quagga.js
@@ -60,6 +60,20 @@
_inputStream = InputStream.createLiveStream(video);
CameraAccess.request(video, _config.inputStream.constraints)
.then(() => {
+ if (_config.inputStream.imageCapture === true) {
+ var activeStreamTrack = CameraAccess.getActiveStreamTrack();
+ if (activeStreamTrack) {
+ var imageCapture = new ImageCapture(activeStreamTrack);
+ if (imageCapture) {
+ var photoSettings = _config.inputStream.photoSettings;
+
+ // set the image capture options (e.g. flash light, autofocus, ...)
+ imageCapture.setOptions(photoSettings)
+ .then(function () {_inputStream.setImageCapture(imageCapture)})
+ .catch(function (err) {console.error('setOptions(' + JSON.stringify(photoSettings) + ') failed: ', err)});
+ }
+ }
+ }
_inputStream.trigger("canrecord");
}).catch((err) => {
return cb(err);
@@ -281,7 +295,7 @@
} else {
_framegrabber.attachData(_inputImageWrapper.data);
}
- if (_framegrabber.grab()) {
+ _framegrabber.grab().then(function () {
if (availableWorker) {
availableWorker.busy = true;
availableWorker.worker.postMessage({
@@ -291,7 +305,7 @@
} else {
locateAndDecode();
}
- }
+ });
} else {
locateAndDecode();
}
Issue Analytics
- State:
- Created 7 years ago
- Comments:8 (1 by maintainers)
Top Results From Across the Web
ImageCapture API | Can I use... Support tables for HTML5 ...
The Image Capture API provides access to the Video Camera for taking photos while configuring picture-specific settings such as e.g. zoom or auto...
Read more >ImageCapture - Web APIs | MDN
The ImageCapture interface of the MediaStream Image Capture API provides methods to enable the capture of images or photos from a camera or ......
Read more >Alternative for the ImageCapture API for better browser support
First check if your browser supports the MediaStream Image Capture API by checking if the constructor exists in the window object.
Read more >ImageCapture - Web APIs
Chrome Edge
ImageCapture. Experimental Chrome Full support 59 Edge Full support...
ImageCapture() constructor. ⚠️. Experimental Chrome Full support 59 Edge Full support...
getPhotoCapabilities. ⚠️. Experimental Chrome...
Read more >Interactive Guide To Image Capture API - RapidAPI
If your browser supports the API, a video stream will start. You can also stop the stream and take a picture using the...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Torch/Focus/etc can be specified now, does that leave this with any valid changes still to be made?
Light/torch support has been released with v.12.0.