<title>JS in-browser barcode reader</title>
width: 320px; height: 240px;
video { position: absolute; top: 0; left: 0; width: 320px; height: 240px; }
width: 260px; height: 180px;
border: 30px solid rgba(64,64,64, 0.5);
background-color: rgba(255, 0, 0, 0.3);
<p>Based on <a href="https://github.com/yurydelendik/zbarjs">zbarjs</a> - Code: <a href="https://gist.github.com/jazzido/9435670">https://gist.github.com/jazzido/9435670</a></p>
<canvas style="display:none;"></canvas>
<script type="text/javascript">
var video = document.querySelector('video');
var canvas = document.querySelector('canvas');
var ctx = canvas.getContext('2d');
var localMediaStream = null;
var list = document.querySelector('ul#decoded');
var worker = new Worker('zbar-processor.js');
worker.onmessage = function(event) {
if (event.data.length == 0) return;
var entry = document.createElement('li');
entry.appendChild(document.createTextNode(d[2] + ' (' + d[0] + ')'));
if (localMediaStream === null) return;
var k = (320 + 240) / (video.videoWidth + video.videoHeight);
canvas.width = Math.ceil(video.videoWidth * k);
canvas.height = Math.ceil(video.videoHeight * k);
var ctx = canvas.getContext('2d');
ctx.drawImage(video, 0, 0, video.videoWidth, video.videoHeight,
0, 0, canvas.width, canvas.height);
var data = ctx.getImageData(0, 0, canvas.width, canvas.height);
worker.postMessage(data);
setInterval(snapshot, 500);
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
window.URL = window.URL || window.webkitURL || window.mozURL || window.msURL;
if (navigator.getUserMedia) {
navigator.getUserMedia({video: true},
function(stream) { // success callback
if (video.mozSrcObject !== undefined) {
video.mozSrcObject = stream;
video.src = (window.URL && window.URL.createObjectURL(stream)) || stream;