let streaming; var current_stream; var current_camera_is; var width = document.getElementById("video").parentNode.parentElement.clientWidth; var height = width / (4 / 3); function startup(){ video = document.getElementById('video'); canvas = document.getElementById('canvas'); photo = document.getElementById('photo'); switch_cameras = document.getElementById('flip') printButton = document.getElementById('print_button'); if (check_webcam() === true ){ setup_events(); clear_canvas(); } else { no_webcam_error(); console.log("Seems like it's impossible to get a webcam."); } } function check_webcam(){ console.log("Cheking for a camera..."); if (get_front_webcam()) { console.log("Got front camera !"); return true; } if (get_any_webcam()) { console.log("Got a webcam !"); return true; } console.log("Nope"); return false; } function setup_events(){ // When the video is ready, we start streaming it to the canvas. // The canvas is hidden, but it still exists in the browser. video.addEventListener('canplay', function(ev) { if (!streaming) { height = video.videoHeight / (video.videoWidth / width); if (isNaN(height)) { height = width / (4 / 3); } video.setAttribute('width', width); video.setAttribute('height', height); canvas.setAttribute('width', width); canvas.setAttribute('height', height); photo.setAttribute('width', width); photo.setAttribute('height', height); streaming = true; printButton.removeAttribute("disabled",""); switch_cameras.removeAttribute("disabled",""); } }, false); switch_cameras.addEventListener('click', function(ev) { flip_cameras(); }, false ); printButton.addEventListener('click', function(ev){ data = take_picture(); try { print_picture(data); } catch (e) { alert("Failed to print a picture because : " + e); } ev.preventDefault(); }, false); } function clear_canvas() { var context = canvas.getContext('2d'); context.fillStyle = "#AAA"; context.fillRect(0, 0, canvas.width, canvas.height); var data = canvas.toDataURL('image/png'); photo.setAttribute('src', data); } function dataURLtoFile(dataurl, filename) { var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1], bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n); while(n--){ u8arr[n] = bstr.charCodeAt(n); } return new File([u8arr], filename, {type:mime}); } function take_picture(){ var context = canvas.getContext('2d'); if (width && height) { canvas.width = width; canvas.height = height; context.drawImage(video, 0, 0, width, height); var data = canvas.toDataURL('image/png'); photo.setAttribute('src', data); } else { clear_canvas(); } return data; } function print_picture(data){ var url = "/api/print/img" var picture = dataURLtoFile(data); const formData = new FormData(); let currentDate = new Date(); let time = currentDate.getHours() + ":" + currentDate.getMinutes() + ":" + currentDate.getSeconds(); formData.set("img", picture, "picture.png"); formData.set("signature", "Printed via the webcam @ " + time) fetch(url, { method: 'POST', // or 'PUT' body: formData, // headers:{ // 'Content-Type': 'multipart/form-data' // } }).then(function(response) { console.log('Success:', response); alert("Picture printed."); } , true) .catch(error => console.error('Error:', error), false); } function flip_cameras(){ switch (current_camera_is) { case "front": try { get_any_webcam(); } catch (e) { console.log("Could not get another camera"); get_front_webcam(); } break; case "any": try { get_front_webcam(); } catch (e) { console.log("Could not get another camera"); get_any_webcam(); } break; default: console.log("Impossible to switch cameras : none is selected."); } } function stop_video_streams(){ console.log("Stopping existing video streams."); // Stop the tracks try { if (current_stream) { const tracks = current_stream.getTracks(); tracks.forEach(track => track.stop()); console.log("Stopped playing current videostreams."); return true; } else { console.log("No streams currently playing."); } } catch (e) { console.log("Could not stop playing current streams." + e); } } async function get_webcam(options){ stop_video_streams(); try { await navigator.mediaDevices.getUserMedia(options) .then(function(stream) { // on success, stream it in video tag // the video tag is hidden, as is the canvas. console.log("Got a camera ( generic )"); printButton.removeAttribute("disabled",""); current_stream = stream; video.srcObject = stream; video.play(); return true; }) .catch(function(err) { console.log("Didn't manage to get a camera :" + err); return false; }); } catch (err) { console.log("Didn't manage to get a camera :" + err); return false; } } function get_any_webcam(){ var camera_options = { video: { facingMode: 'environment', // Or 'environment' if we want a camera facing away }, audio: false }; if(get_webcam(camera_options)){ console.log("Got any camera, or environment camera."); current_camera_is = "any"; return true; } else { return false; } } function get_front_webcam(){ // We try to start with the front facing camera, // if we have no support, we switch back to a normal camera. try { const supports = navigator.mediaDevices.getSupportedConstraints(); if (!supports['facingMode']) { throw new Error("This browser does not support facingMode!"); } else { var camera_options = { video: { facingMode: 'user', // Or 'environment' if we want a camera facing away }, audio: false }; } } catch (e) { console.log("Resetting to default camera : " + e); var camera_options = { video: true, audio: false }; } if(get_webcam(camera_options)){ console.log("Got the front camera"); current_camera_is = "front"; return true; } else { return false; } } function no_webcam_error(){ console.log("Seems like they is no webcam available.") // We disable the print button is it cannot be clicked. printButton.setAttribute("disabled",""); // We create an alert message. const frame_div = document.getElementById("image_dither"); frame_div.removeAttribute('class'); const alert_div = document.createElement("div"); alert_div.setAttribute("class", "alert alert-warning"); alert_div.setAttribute("role", "alert"); var alert_message = document.createTextNode("We where unable to get a Webcam device, this page will not work."); alert_div.appendChild(alert_message); frame_div.appendChild(alert_div); throw new Error("Unable to get a video device, stopping the photobooth."); } window.addEventListener('load', startup, false);