quagga2
quagga2 copied to clipboard
Demos not working in Chrome for Android or other browsers in android
I've been using quaggajs for a while now and all of the sudden it doesn't work on mobile versions of chrome. I believe this could be a relatively new issue, but it could be a few months old.
I'm using the latest version of Chrome for Android and I'm on Android version 10.
Is there a known fix for this or has anyone else run into this problem?
Thank you for filing an issue! Please be patient. :-)
Hi @npsantini ! My phone just updated Chrome yesterday, 86.0.4240.75, and my application seems to be working as normal.
Are you able to provide any more specific details, as to what "doesn't work" means, or get to the console log or anything?
Facing this issue too when using live stream on Android -- image appears for a second then just turns black. Downgrading back to Chrome v80 or use Microsoft Edge works though. Devices are Redmi S2 and Vivo 1820
My code:
let quaggaStarted = false
let enteringQty = false
var App = {
init : function() {
Quagga.init(this.state, function(err) {
if (err) {
console.log(err);
return;
}
App.attachListeners();
App.checkCapabilities();
Quagga.start();
quaggaStarted = true
});
},
checkCapabilities: function() {
var track = Quagga.CameraAccess.getActiveTrack();
var capabilities = {};
if (typeof track.getCapabilities === 'function') {
capabilities = track.getCapabilities();
}
this.applySettingsVisibility('zoom', capabilities.zoom);
this.applySettingsVisibility('torch', capabilities.torch);
},
updateOptionsForMediaRange: function(node, range) {
console.log('updateOptionsForMediaRange', node, range);
var NUM_STEPS = 6;
var stepSize = (range.max - range.min) / NUM_STEPS;
var option;
var value;
while (node.firstChild) {
node.removeChild(node.firstChild);
}
for (var i = 0; i <= NUM_STEPS; i++) {
value = range.min + (stepSize * i);
option = document.createElement('option');
option.value = value;
option.innerHTML = value;
node.appendChild(option);
}
},
applySettingsVisibility: function(setting, capability) {
// depending on type of capability
if (typeof capability === 'boolean') {
var node = document.querySelector('input[name="settings_' + setting + '"]');
if (node) {
node.parentNode.style.display = capability ? 'block' : 'none';
}
return;
}
if (window.MediaSettingsRange && capability instanceof window.MediaSettingsRange) {
var node = document.querySelector('select[name="settings_' + setting + '"]');
if (node) {
this.updateOptionsForMediaRange(node, capability);
node.parentNode.style.display = 'block';
}
return;
}
},
initCameraSelection: function(){
var streamLabel = Quagga.CameraAccess.getActiveStreamLabel();
return Quagga.CameraAccess.enumerateVideoDevices()
.then(function(devices) {
function pruneText(text) {
return text.length > 30 ? text.substr(0, 30) : text;
}
var $deviceSelection = document.getElementById("deviceSelection");
while ($deviceSelection.firstChild) {
$deviceSelection.removeChild($deviceSelection.firstChild);
}
devices.forEach(function(device) {
var $option = document.createElement("option");
$option.value = device.deviceId || device.id;
$option.appendChild(document.createTextNode(pruneText(device.label || device.deviceId || device.id)));
$option.selected = streamLabel === device.label;
$deviceSelection.appendChild($option);
});
});
},
attachListeners: function() {
var self = this;
self.initCameraSelection();
$(".controls").on("click", "button.stop", function(e) {
e.preventDefault();
Quagga.stop();
quaggaStarted = false;
});
$(".controls .reader-config-group").on("change", "input, select", function(e) {
e.preventDefault();
var $target = $(e.target),
value = $target.attr("type") === "checkbox" ? $target.prop("checked") : $target.val(),
name = $target.attr("name"),
state = self._convertNameToState(name);
console.log("Value of "+ state + " changed to " + value);
self.setState(state, value);
});
},
_accessByPath: function(obj, path, val) {
var parts = path.split('.'),
depth = parts.length,
setter = (typeof val !== "undefined") ? true : false;
return parts.reduce(function(o, key, i) {
if (setter && (i + 1) === depth) {
if (typeof o[key] === "object" && typeof val === "object") {
Object.assign(o[key], val);
} else {
o[key] = val;
}
}
return key in o ? o[key] : {};
}, obj);
},
_convertNameToState: function(name) {
return name.replace("_", ".").split("-").reduce(function(result, value) {
return result + value.charAt(0).toUpperCase() + value.substring(1);
});
},
detachListeners: function() {
$(".controls").off("click", "button.stop");
$(".controls .reader-config-group").off("change", "input, select");
},
applySetting: function(setting, value) {
var track = Quagga.CameraAccess.getActiveTrack();
if (track && typeof track.getCapabilities === 'function') {
switch (setting) {
case 'zoom':
return track.applyConstraints({advanced: [{zoom: parseFloat(value)}]});
case 'torch':
return track.applyConstraints({advanced: [{torch: !!value}]});
}
}
},
setState: function(path, value) {
var self = this;
if (typeof self._accessByPath(self.inputMapper, path) === "function") {
value = self._accessByPath(self.inputMapper, path)(value);
}
if (path.startsWith('settings.')) {
var setting = path.substring(9);
return self.applySetting(setting, value);
}
self._accessByPath(self.state, path, value);
console.log(JSON.stringify(self.state));
App.detachListeners();
Quagga.stop();
App.init();
},
inputMapper: {
inputStream: {
constraints: function(value){
if (/^(\d+)x(\d+)$/.test(value)) {
var values = value.split('x');
return {
width: {min: parseInt(values[0])},
height: {min: parseInt(values[1])}
};
}
return {
deviceId: value
};
}
},
numOfWorkers: function(value) {
return parseInt(value);
},
decoder: {
readers: function(value) {
if (value === 'ean_extended') {
return [{
format: "ean_reader",
config: {
supplements: [
'ean_5_reader', 'ean_2_reader'
]
}
}];
}
return [{
format: value + "_reader",
config: {}
}];
}
}
},
state: {
inputStream: {
type : "LiveStream",
constraints: {
width: {min: 640},
height: {min: 480},
aspectRatio: {min: 1, max: 2}, //https://github.com/serratus/quaggaJS/issues/444
facingMode: "environment" // or user
}
},
locator: {
patchSize: "medium",
halfSample: true
},
numOfWorkers: 2,
frequency: 5,
decoder: {
readers : [{
format: "ean_reader",
config: {}
}]
},
locate: true
},
lastResult : null
};
Quagga.onProcessed(function(result) {
var drawingCtx = Quagga.canvas.ctx.overlay,
drawingCanvas = Quagga.canvas.dom.overlay;
if (result) {
if (result.boxes) {
drawingCtx.clearRect(0, 0, parseInt(drawingCanvas.getAttribute("width")), parseInt(drawingCanvas.getAttribute("height")));
result.boxes.filter(function (box) {
return box !== result.box;
}).forEach(function (box) {
Quagga.ImageDebug.drawPath(box, {x: 0, y: 1}, drawingCtx, {color: "green", lineWidth: 2});
});
}
if (result.box) {
Quagga.ImageDebug.drawPath(result.box, {x: 0, y: 1}, drawingCtx, {color: "#00F", lineWidth: 2});
}
if (result.codeResult && result.codeResult.code) {
Quagga.ImageDebug.drawPath(result.line, {x: 'x', y: 'y'}, drawingCtx, {color: 'red', lineWidth: 3});
}
}
});
Quagga.onDetected(function(result) {
if(!enteringQty){
enteringQty = true
var code = result.codeResult.code;
findBarSku(code, () => {
enteringQty = false
})
}
// if (App.lastResult !== code) {
// App.lastResult = code;
// var $node = null, canvas = Quagga.canvas.dom.image;
// $node = $('<li><div class="thumbnail"><div class="imgWrapper"><img /></div><div class="caption"><h4 class="code"></h4></div></div></li>');
// $node.find("img").attr("src", canvas.toDataURL());
// $node.find("h4.code").html(code);
// $("#result_strip ul.thumbnails").prepend($node);
// }
});
Any chance this is related to Android 11 ? https://github.com/ericblade/quagga2/issues/266
I am not able to repro using the most recent Chrome update on my Android 9 phone, and that's the best I've got access to.
If you have a public hosting of your code, I'd be happy to check it from my phone as well.
The devices I'm using are on Android 10. I would share the link, but we have the project limited to specific IP addresses.
@suparpat that's a bit of a long example for me to digest all at once, any chance you can simplify further?
@npsantini hmm. android 9 doesn't seem to be having any issues here, with latest chromium available there. At least not with any of my app code. I'm.. not sure how to proceed.
... I did not mean to close this.
@ericblade I have done some testing on a few other devices and it does appear to be an Android version problem. It works on Android 9, but not Android 10. All other devices I've tested seem to work fine included chrome for desktop on windows, iphone 14.2 in safari, and ipad os 14.1.
@ericblade The beta demos do seem to work in Chrome on Android 10. The live stream pulls up the front facing camera.
What would be the difference that causes the beta examples to work, but not the other non-beta demos?
@npsantini good question. i didn't even realize there was a "beta" branch in the old repo, until loooooooooooong after i forked. Might be worth doing a diff on the beta branch.
I.. don't know when i might have time to do that, things are pretty wild right now.
Has anyone been able to resolve this issue? I'm having problems on Android Version 9... which seems to be working for you guys 🤔
having not received any reports of obvious Android issues in a year now, I'm thinking this problem was resolved in a Chrome update. If anyone has an issue, lmk, open a new ticket. thanks!