No barcode detected using QuaggaJS - javascript

I have been trying to decode barcodes using QuaggaJS for a few days now. I am trying to decode UPC barcodes. I also have a high quality camera, so it is not the issue.
When I run my code, I only get the "onProcessed" event, never the "onDetected".
Here is my JS code for the camera:
const width = 640; // We will scale the photo width to this
let height = 0; // This will be computed based on the input stream
let streaming = false;
let video = null;
let lastQr = null;
function startup() {
video = document.getElementById("video");
navigator.mediaDevices
.getUserMedia({ video: { facingMode: "environment" }, audio: false })
.then((stream) => {
video.srcObject = stream;
video.play();
})
.catch((err) => {
console.error(`An error occurred: ${err}`);
});
video.addEventListener(
"canplay",
(ev) => {
if (!streaming) {
height = video.videoHeight / (video.videoWidth / width);
// Firefox currently has a bug where the height can't be read from
// the video, so we will make assumptions if this happens.
if (isNaN(height)) {
height = width / (4 / 3);
}
video.setAttribute("width", width);
video.setAttribute("height", height);
streaming = true;
}
},
false
);
Quagga.init({
inputStream : {
name : "Live",
type : "LiveStream",
target: document.querySelector('#camera') // Or '#yourElement' (optional)
},
decoder : {
readers : ["upc_reader"]
}
}, function(err) {
if (err) {
console.log(err);
return
}
console.log("Initialization finished. Ready to start");
Quagga.start();
Quagga.onProcessed(function(pr) {
if(pr != undefined) {
console.log(pr)
}
});
Quagga.onDetected(function(result) {
console.log('DETECTED');
var code = result.codeResult.code;
console.log(code);
});
});
document.getElementById('camera').style.display = 'block';
document.getElementById('startup-button').style.display = 'none';
}
Here is the HTML for the video stream:
<div id="camera" style="display: none;">
<video id="video">Video stream not available.</video>
</div>
<x-button id="startup-button" class="mb-4" onclick="startup()">{{ __('track.open_camera') }}</x-button>

Related

How to upload a webcam stream of video and send bytes as soon as they arrive to the server using javascript and python3?

How do you upload a webcam to the server as the bytes are created from the webcam?
This is my starting code.
let mediaRecorder = new MediaRecorder(mediaStreamObj);
let chunks = [];
Here is the solution. Tested and Works in both Firefox and Chrome.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>MediaCapture and Streams API</title>
<meta name="viewport" content="width=device-width">
<script type="text/javascript" src="js/jquery.min.js"></script>
</head>
<body>
<header>
<h1>MediaCapture, MediaRecorder and Streams API</h1>
</header>
<main>
<p></p>
<p><button id="btnStart">START RECORDING</button><br/>
<button id="btnStop">STOP RECORDING</button></p>
<video controls></video>
<video id="vid2" controls></video>
<!-- could save to canvas and do image manipulation and saving too -->
</main>
<script>
let constraintObj = {
audio: true,
video: {
facingMode: "user",
width: { min: 640, ideal: 1280, max: 1920 },
height: { min: 480, ideal: 720, max: 1080 }
}
};
// width: 1280, height: 720 -- preference only
// facingMode: {exact: "user"}
// facingMode: "environment"
//handle older browsers that might implement getUserMedia in some way
if (navigator.mediaDevices === undefined) {
navigator.mediaDevices = {};
navigator.mediaDevices.getUserMedia = function(constraintObj) {
let getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
if (!getUserMedia) {
return Promise.reject(new Error('getUserMedia is not implemented in this browser'));
}
return new Promise(function(resolve, reject) {
getUserMedia.call(navigator, constraintObj, resolve, reject);
});
}
}else{
navigator.mediaDevices.enumerateDevices()
.then(devices => {
devices.forEach(device=>{
console.log(device.kind.toUpperCase(), device.label);
//, device.deviceId
})
})
.catch(err=>{
console.log(err.name, err.message);
})
}
navigator.mediaDevices.getUserMedia(constraintObj)
.then(function(mediaStreamObj) {
//connect the media stream to the first video element
let video = document.querySelector('video');
if ("srcObject" in video) {
video.srcObject = mediaStreamObj;
} else {
//old version
video.src = window.URL.createObjectURL(mediaStreamObj);
}
video.onloadedmetadata = function(ev) {
//show in the video element what is being captured by the webcam
video.play();
};
//add listeners for saving video/audio
let start = document.getElementById('btnStart');
let stop = document.getElementById('btnStop');
let vidSave = document.getElementById('vid2');
let mediaRecorder = new MediaRecorder(mediaStreamObj);
let chunks = [];
start.addEventListener('click', (ev)=>{
mediaRecorder.start(1000); // milliseconds, so 1 second is 1000
console.log(mediaRecorder.state);
})
stop.addEventListener('click', (ev)=>{
mediaRecorder.stop();
console.log(mediaRecorder.state);
});
mediaRecorder.ondataavailable = function(ev) {
chunks.push(ev.data);
var res;
var pos;
var b = "base64," ;
var fr = new FileReader();
fr.onload = function(){
res = this.result;
pos = res.search(b);
pos = pos + b.length;
res = res.substring(pos);
$.ajax({
type: 'POST',
url: 'server.py',
dataType: "html",
data: { chunk: res },
success: function(data){
//alert(data + ' yes');
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert('Status: ' + textStatus + ' ' + ' Error: ' + errorThrown);
}
});
}
fr.readAsDataURL(ev.data);
}
mediaRecorder.onstop = (ev)=>{
let blob = new Blob(chunks, { 'type' : 'video/mp4;' });
chunks = [];
let videoURL = window.URL.createObjectURL(blob);
vidSave.src = videoURL;
}
})
.catch(function(err) {
console.log(err.name, err.message);
});
</script>
</body>
</html>
And the Python3 server.py file to accept the real time webcam video is the following.
import os
import sys
import cgi
import cgitb
import base64
include_path = '/var/webcam_project/www'
cgitb.enable(display=0, logdir=f"""{include_path}/tmp_errors""") # include_path is OUTDIR
sys.path.insert(0, include_path)
def enc_print(string='', encoding='utf8'):
sys.stdout.buffer.write(string.encode(encoding) + b'\n')
from html import escape
args = cgi.FieldStorage()
chunk = '' if not args.getvalue( "chunk" ) else escape( args.getvalue( "chunk" ) )
mp4 = 'webcam.mp4'
with open (mp4, 'ab') as f:
f.write( base64.b64decode(chunk) )
html = 'success'
enc_print("Content-Type:text/html;charset=utf-8;")
enc_print()
enc_print(html)
Vote up if you like these kinds of solutions of value.

track.stop is not turning the camera off anymore

I have a webpage where I want user to take a picture with his laptop/phone camera.
Once he clicks on a button a modal is shown and the following js will start the camera stream to take the picture:
function startStreaming() {
if (null != cameraStream) {
var track = cameraStream.getTracks()[0];
track.stop();
stream.load();
cameraStream = null;
}
//const audioSource = audioInputSelect.value;
const videoSource = videoSelect.value;
const constraints = {
//audio: {deviceId: audioSource ? {exact: audioSource} : undefined},
video: {
deviceId: videoSource ? {
exact: videoSource
} : undefined
}
};
navigator.mediaDevices.getUserMedia(constraints).then(gotStream).then(gotDevices).catch(handleError);
var mediaSupport = 'mediaDevices' in navigator;
if (mediaSupport && null == cameraStream) {
const videoSource = videoSelect.value;
const constraints = {
video: {
deviceId: videoSource ? {
exact: videoSource
} : undefined
}
};
navigator.mediaDevices.getUserMedia(constraints)
.then(function (mediaStream) {
cameraStream = mediaStream;
stream.srcObject = mediaStream;
stream.play();
})
.catch(handleError);
} else {
alert('Your browser does not support media devices.');
return;
}
}
This is triggered by
$('#photoStudio').on('show.bs.modal', function (event) {
navigator.mediaDevices.enumerateDevices().then(gotDevices).catch(handleError);
startStreaming();
});
Then when I close the modal I want to stop the streaming but the led indicator next to my camera is still on)
$('#photoStudio').on('hide.bs.modal', function (event) {
stopStreaming();
});
where stopStreaming() is:
function stopStreaming() {
if (null != cameraStream) {
var track = cameraStream.getTracks()[0];
track.stop();
stream.load();
cameraStream = null;
}
}
I don't get any kind of error and I cannot find a way to debug why the camera is still running. Am I missing anything in the stopStreaming function?
If any track has not been stopped then your camera will still be active. In your stopStreaming function you only stop the first track in the returned array.
If you instead iterate through the tracks you may catch ones you aren't currently:
function stopStreaming() {
if (null != cameraStream) {
var tracks = cameraStream.getTracks();
// stop all the tracks, not just the first
tracks.forEach((track) => {
track.stop();
});
stream.load();
cameraStream = null;
}
}
this.camera_stream.getTracks().forEach((track) => {
console.log(track);
track.stop();
**track.enabled = false**
});
video.load()
this.camera_stream = null

camera no popping up when deployed on buildfire

I am developing a QRcode scanner with https://rawgit.com/sitepoint-editors/jsqrcode/master/src/qr_packed.js on buildfire. is working fine on development but when deployed on markeenter code heret place the camera is not popping up.
this is my code.
//const qrcode = window.qrcode;
enter code here
const video = document.createElement("video");
const canvasElement = document.getElementById("qr-canvas");
const canvas = canvasElement.getContext("2d");
const qrResult = document.getElementById("qr-result");
const outputData = document.getElementById("outputData");
const btnScanQR = document.getElementById("btn-scan-qr");
let scanning = false;
qrcode.callback = res => {
if (res) {
outputData.innerText = res;
scanning = false;
video.srcObject.getTracks().forEach(track => {
track.stop();
});
qrResult.hidden = false;
canvasElement.hidden = true;
btnScanQR.hidden = false;
}
};
buildfire.services.camera.barcodeScanner.scan(
{
preferFrontCamera: true,
showFlipCameraButton: true,
formats: "QR_CODE,PDF_417",
},
btnScanQR.onclick = () => {
navigator.mediaDevices
.getUserMedia({ video: { facingMode: "environment" } })
.then(function(stream) {
scanning = true;
qrResult.hidden = true;
btnScanQR.hidden = true;
canvasElement.hidden = false;
video.setAttribute("playsinline", true); // required to tell iOS safari we don't want fullscreen
video.srcObject = stream;
video.play();
tick();
scan();
});
}
);
function tick() {
canvasElement.height = video.videoHeight;
canvasElement.width = video.videoWidth;
canvas.drawImage(video, 0, 0, canvasElement.width, canvasElement.height);
scanning && requestAnimationFrame(tick);
}
function scan() {
try {
qrcode.decode();
} catch (e) {
setTimeout(scan, 300);
}
}

getUserMedia() can't release the camera

There is somewhere very silly mistake in my code that I can't find. Basically what I'm doing is, I'm using two separate buttons to start and stop recording the stream that I get from WebRTC getUserMedia() (I'm using RecordRTC for recording). My stop function stops the recording but does not release the camera.
<script type="text/javascript">
$(document).ready(function () {
var recorder;
var video = document.getElementById("video");
var videoConstraints = {
video: {
mandatory: {
minWidth: 1280,
minHeight: 720,
maxWidth: 1920,
maxHeight: 1080,
minFrameRate: 29.97,
maxFrameRate: 60,
minAspectRatio: 1.77
}
},
audio: true
};
function captureCamera(callback) {
navigator.mediaDevices.getUserMedia(videoConstraints).then(function (camera) {
callback(camera);
}).catch(function (error) {
alert('Unable to capture your camera. Please check console logs.');
console.error(error);
});
}
function stopRecordingCallback() {
video.src = video.srcObject = null;
video.src = URL.createObjectURL(recorder.getBlob());
video.play();
//recorder.camera.stop(); //its the deprecated way
recorder.camera.getTracks().forEach(track => track.stop()); //modern way as per documentation
recorder.destroy();
recorder = null;
}
hasGetUserMedia() {
return (navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia);
}
$('#startRecord').on("click", function () {
if (hasGetUserMedia()) {
/*----------------recording process start----------------*/
this.disabled = true;
captureCamera(function (camera) {
setSrcObject(camera, video);
video.play();
var options = {
recorderType: MediaStreamRecorder,
mimeType: 'video/webm\;codecs=h264',
audioBitsPerSecond: 128000,
videoBitsPerSecond: 2097152, // 2 mbps
};
recorder = RecordRTC(camera, options);
recorder.startRecording();
// release camera on stopRecording
recorder.camera = camera;
document.getElementById('stopRecord').disabled = false;
});
/*----------------recording process end----------------*/
}
else {
alert('getUserMedia() is not supported by your browser');
}
});
$('#stopRecord').on("click", function () {
this.disabled = true;
document.getElementById('startRecord').disabled = false;
recorder.stopRecording(stopRecordingCallback);
});
});
</script>
So I can't find the reason why the camera isn't released when the $('#stopRecord').on("click", function (){}) is called. Any help?
You can stop your stream's tracks, like this:
navigator.getUserMedia({audio: false, video: true},
function(stream) {
// can also use getAudioTracks() or getVideoTracks()
var track = stream.getTracks()[0]; // if only one media track
// ...
track.stop();
},
function(error){
console.log('getUserMedia() error', error);
});
So, in your case, I believe you can do something like this:
var track = recorder.camera.getTracks()[0]; // if only one media track
// ...
track.stop();

Turn off camera after photo

I am reverse-engineering a project and am running into some perplexing problems. The project is in Meteor, which I like, but doesn't seem to follow Meteors conventions.
This is essentially a javascript file to allow users to take a selfie using the laptop devices camera. However, after taking the photo, the camera does not turn off.
After having tried a number of suggestions online, I am putting the question: how does one turn off the camera?
Thank you for your help!
Template.newSelfie.rendered = function(){
// Grab elements, create settings, etc.
var canvas = document.getElementById("canvas"),
context = canvas.getContext("2d"),
video = document.getElementById("video"),
videoObj = { "video": true },
errBack = function(error) {
console.log("Video capture error: ", error.code);
};
// Put video listeners into place
if(navigator.getUserMedia) { // Standard
navigator.getUserMedia(videoObj, function(stream) {
video.src = stream;
video.play();
}, errBack);
} else if(navigator.webkitGetUserMedia) { // WebKit-prefixed
navigator.webkitGetUserMedia(videoObj, function(stream){
video.src = window.webkitURL.createObjectURL(stream);
video.play();
}, errBack);
}
else if(navigator.mozGetUserMedia) { // Firefox-prefixed
navigator.mozGetUserMedia(videoObj, function(stream){
video.src = window.URL.createObjectURL(stream);
video.play();
}, errBack);
}
// Converts canvas to an image
function convertCanvasToImage(canvas) {
var image = new Image();
image.src = canvas.toDataURL("image/png");
return image.src;
}
$('#take-selfie').click(function() {
context.drawImage(video, 0, 0, 450, 350);
var selfieImg = convertCanvasToImage(canvas);
Posts.insert({
ownerId: Meteor.userId(),
userWallId: Meteor.userId(),
content: '<img src="'+selfieImg+'">',
postedOn: new Date()
}, function(err, res) {
console.log(err || res);
});
Selfies.insert({
ownerId: Meteor.userId(),
image: selfieImg,
postedOn: moment().format('MM/DD/YYYY hh:mm a'),
createdAt: moment().format('YYYY-MM-DD')
}, function(err, res) {
console.log(err || res);
if(err){
console.log(err);
} else {
Router.go('profileSelfies');
}
});
});
};
const video = document.querySelector('video');
// A video's MediaStream object is available through its srcObject attribute
const mediaStream = video.srcObject;
// Through the MediaStream, you can get the MediaStreamTracks with getTracks():
const tracks = mediaStream.getTracks();
// Tracks are returned as an array, so if you know you only have one, you can stop it with:
tracks[0].stop();
// Or stop all like so:
tracks.forEach(track => track.stop())
https://dev.to/morinoko/stopping-a-webcam-with-javascript-4297

Categories

Resources