quaggaJS: how to "pause" the decoder - javascript

I'm using quaggaJS (https://github.com/serratus/quaggaJS) to read barcodes in a web application. It works very well, and this is my initialization code:
Quagga.init({
inputStream: {
name: "Live",
type: "LiveStream",
constraints: {
width: 1280,
height: 720,
facingMode: "environment"
}
},
decoder: {
readers: ["code_39_reader"],
debug: {
drawBoundingBox: true,
showFrequency: false,
drawScanline: true,
showPattern: true
},
multiple: false
},
locator: {
halfSample: true,
patchSize: "medium"
}
}, function (err) {
if (err) {
alert(err);
return;
}
Quagga.registerResultCollector(resultCollector);
Quagga.start();
});
here the handling of the onDetected event:
Quagga.onDetected(function (data) {
Quagga.stop(); // <-- I want to "pause"
// dialog to ask the user to accept or reject
});
What does that mean?
When it recognize a barcode I need to ask the user if he wants to accept or reject the decoded value - and therefore repeat the process.
It would be nice to leave the captured image so he can actually see what he just captured.
Quagga.stop() works in most cases but it's not reliable because sometimes the canvas will turn black. I guess this is due the behavior of the stop() method:
the decoder does not process any more images. Additionally, if a camera-stream was requested upon initialization, this operation also disconnects the camera.
For this reason I'm looking for a way to pause the decoding, so the last frame is still there and the camera has not disconnected yet.
Any suggestion how to achieve this?

A better way to do it would be to first pause the video and then call Quagga.stop() so that the video element that Quagga creates for you will be paused and you don't see the blacked out image. Additionally, you can also have a restart/re-scan button to resume or rather restart the scanning process.
To get the view element you can do something like below:
Quagga.onDetected(function (result) {
var cameraFeed = document.getElementById("cameraFeedContainer")
cameraFeed.getElementsByTagName("video")[0].pause();
return;
});

You can get the image frame via Quagga.canvas.dom.image.
With that, you can overlay the videostream.
HTML
<div class="scanArea">
<div id="interactive" class="viewport"></div>
<div class="scanArea__freezedFrame"></div>
</div>
CSS
.scanArea {
position: relative;
}
.scanArea__freezedFrame {
position: absolute;
left: 0;
top: 0;
}
JavaScript
Quagga.onDetected(function(result) {
var canvas = Quagga.canvas.dom.image;
var $img = $('<img/>');
$img.attr("src", canvas.toDataURL());
$('.scanArea__freezedFrame').html($img);
});

Related

Ziggeo meta-profiles parameter for recording video in javascript

I've been playing around with the ziggeo API and I'm trying to attach some events for a recording. as far as I can tell, the best way to do this is to create a div with a specific id and then create the ziggeo recorder using attribs, etc.
<div id="video_section"></div>
<script>
ZiggeoApi.Events.on("system_ready", function() {
var recorder = new ZiggeoApi.V2.Recorder({
element: document.getElementById("video_section"),
attrs: {
width: 320,
height: 240,
theme: "modern",
themecolor: "red",
}
});
recorder.activate();
});
</script>
yet, unlike the use of the simple form <ziggeorecorder></ziggeorecorder> which allows the passing of a meta-profile parameter,
<ziggeorecorder ziggeo-theme='minimalist' ziggeo-themecolor="red" ziggeo-meta-profile='META_PROFILE_TOKEN'></ziggeorecorder>
when adding meta-profile in the attribs, initializing the recorder (as indicated in the API reference) results in meta-profile being misinterpreted. when changing the attribute to meta_profile, nothing gets processed.
attrs: {
width: 320,
height: 240,
theme: "modern",
themecolor: "red",
meta_profile: 'META PROFILE ID',
}
beyond that, when trying to attach the event.
<script>
var element = document.getElementById('video_section');
var embedding = ZiggeoApi.V2.Recorder.findByElement(element);
embedding.on("submitted", function(data) {
alert("Video " + data.video.token + " was submitted!");
});
</script>
I keep getting an error:
Uncaught TypeError: Cannot read property 'on' of null
does anyone have a good grip on how to do this properly? - create a recorder, set a meta-profile, and attach an event (either submission or completion of processing) to redirect back to a root path.
I think you need to use meta-profile instead of meta_profile. You may try this code:
<div id="video_section"></div>
<script>
ZiggeoApi.Events.on("system_ready", function() {
var recorder = new ZiggeoApi.V2.Recorder({
element: document.getElementById("video_section"),
attrs: {
width: 320,
height: 240,
theme: "modern",
themecolor: "red",
"meta-profile":"META PROFILE ID"
}
});
recorder.activate();
recorder.on("verified", function(data){
console.log(data);
});
});
</script>
Javascript doesn't allow using - outside quote when defining object property (CMIIW).

JointJS show message on validation Failed

I'm trying to show a toaster when the user tries to connect two elements that cannot be linked. The problem is JointJS calls the function validateConnection for all elements on the Graph when I start dragging the arrow not only when the arrow reaches the target, so I cannot place the toaster code there. I'm looking a way to check if a invalid connection attempt was done.
I know that I can listen to
paper.on('link:connect', function(linkView, evt, elementViewConnected, magnet, arrowhead) {console.log('Valid connection');});
But only to valid connections. Is there a way to get a invalid connection attempt?
My Paper:
const paper = this.paper = new rappid.joint.dia.Paper({
width: 1000,
height: 1000,
gridSize: 10,
drawGrid: true,
model: graph,
multiLinks: false,
linkPinning: false,
markAvailable: true,
perpendicularLinks: true,
defaultLink: function (cellView, magnet, link) {
return LinksService.getMyLink(cellView.model.attributes.link, data);
},
validateConnection: function (cellViewS, magnetS, cellViewT, magnetT, end) {
const idS = cellViewS.model.id;
const idT = cellViewT.model.id;
const links = appInstance.graph.getLinks();
if (flowContext.existsConnection(idS, idT, links)) {
return false;
}
return true;
},
});
validateConnection is used to prevent the user from creating invalid connections at all while they are interacting with the link. If you want to react to invalid connections (with a toast/message) you can use allowLink instead. (doc: https://resources.jointjs.com/docs/jointjs/v2.1/joint.html#dia.Paper.prototype.options.allowLink)

Why won't my webstream show?

I tried to test the code below on an android device, it didn't work (the switch button appeared but the camera output didn't.). I then decided to test it on a Mac and it worked (it just showed the camera output and the button, the button didn't do anything because there is no back camera.). Here is my code (the javascript portion of it.):
var constraints = {
audio: true,
video: {
width: 1280,
height: 720
}
};
navigator.mediaDevices.getUserMedia(constraints).then(function(mediaStream) {
var video = document.querySelector('#webcam');
video.srcObject = mediaStream;
video.onloadedmetadata = function(e) {
video.play();
};
}).catch(function(err) {
console.log(err.name + ": " + err.message);
});
var front = false;
document.getElementById('flip-button').onclick = function() {
front = !front;
};
var constraints = {
video: {
facingMode: (front ? "user" : "environment")
}
};
Here's the HTML portion of my code:
<video id="webcam">
</video>
<button Id="flip-button">switch
</button>
here's the css portion of my code:
#webcam {} #flip-button {
background-color: #202060;
height: 15%;
width: 20%;
border: none;
margin-left: 40%;
}
Thanks for your time.
You got your id wrong. Replace #webcam with #video.
Or just remove this line:
var video = document.querySelector('#webcam');
The latter works because ids are implicitly available in global scope for backwards compatibility. Some people frown on this, but it's neat for tidy fiddles.
Some beginner's advice: Always check your browser's web console for errors. Here it said:
TypeError: video is null
which was the clue that the result from querySelector was null.
PS: You also have two competing definitions of constraints, leaving your facingMode unused. Lastly, flipping front won't do much, unless front is used again, which it is not.

How to stop chrome from capturing a tab?

I'm trying to build an chrome extension similar to the chromecast one. I am using chrome.tabCapture to successfully start a audio/video stream. How do I stop the screen capture? I want to have a stop button, but I am not sure what to call to stop it. I can stop the LocalMediaStream, but the tab is still capturing and does not allow me to start a new capture without closing the tab. Any suggestions or maybe an api page I may have missed?
Try stream.getVideoTracks()[0].stop(); to stop the screen capture. And to record the stream caught using chrome.tabCapture API , you could use RecordRTC.js
var video_constraints = {
mandatory: {
chromeMediaSource: 'tab'
}
};
var constraints = {
audio: false,
video: true,
videoConstraints: video_constraints
};
chrome.tabCapture.capture(constraints, function(stream) {
console.log(stream)
var options = {
type: 'video',
mimeType : 'video/webm',
// minimum time between pushing frames to Whammy (in milliseconds)
frameInterval: 20,
video: {
width: 1280,
height: 720
},
canvas: {
width: 1280,
height: 720
}
};
var recordRTC = new RecordRTC(stream, options);
recordRTC.startRecording();
setTimeout(function(){
recordRTC.stopRecording(function(videoURL) {
stream.getVideoTracks()[0].stop();
recordRTC.save();
});
},10*1000);
});
I hope the above code snippet would help you :)
Edit 1: corrected the RecordRTC initialization.

How to change video (and start playing immediately) in Flowplayer via Javascript?

It should change the video and start playing regardless of whether or not a video is currently loaded and playing.
Thanks.
See example below where api is your flowplayer instance and replaceclip is the one you want to start plating
var api = flashembed("player", {src:'FlowPlayerDark.swf'}, {config: ...}});
var replaceclip = {'url':'myvideo.mp4', 'autoplay':true};
<button onClick="api.playClip(replaceclip)">Play</button>
See my example in Github https://github.com/Teaonly/android-eye/blob/master/assets/droideye.js
var initAudioPlayer = function () {
// install flowplayer into container
// http://flash.flowplayer.org/
$f("player", "flowplayer-3.2.15.swf", {
plugins: {
controls: {
fullscreen: false,
height: 30,
autoHide: false,
play: false,
}
},
clip: {
autoPlay: false,
url: "stream/live.mp3",
}
});
audioPlayer = $f();
};
var newClip = {'url':'stream/live.mp3?id='+audioCount,'autoplay':true};
audioCount ++;
audioPlayer.play(newClip);
$f().play([{url:'yourmovie.flv'}]);
In this way you can change the video dynamically in Ajax.
You can check out the javascript api for the flowplayer here
Specifically, you'll probably want to check out the flowplayer objects 'Clip' and 'Player'

Categories

Resources