diff --git a/src/static/js/webcam.js b/src/static/js/webcam.js index 9fe9a9a..2bf864c 100644 --- a/src/static/js/webcam.js +++ b/src/static/js/webcam.js @@ -1,4 +1,7 @@ let streaming; +var current_stream; +var current_camera_is; + var width = document.getElementById("video").parentNode.parentElement.clientWidth; var height = width / (4 / 3); @@ -9,58 +12,28 @@ function startup(){ switch_cameras = document.getElementById('flip') printButton = document.getElementById('print_button'); - if ( check_webcam() ){ + 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(){ - try { - // access video stream from webcam - navigator.mediaDevices.getUserMedia({ - video: true, - audio: false - }) - // on success, stream it in video tag - // the video tag is hidden, as is the canvas. - .then(function(stream) { - switch_cameras.removeAttribute("disabled",""); - - video.srcObject = stream; - video.play(); - }) - .catch(function(err) { - console.log("An error occurred: " + err); - - }); - } catch (err) { - console.log("An error occurred: " + err); - 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); - console.log("Should be a new div somewhere"); - throw new Error("Unable to get a video device, stopping the photobooth."); - } finally { - - + console.log("Cheking for a camera..."); + if (get_front_webcam()) { + console.log("Got front camera !"); + return true; } - return true; + + if (get_any_webcam()) { + console.log("Got a webcam !"); + return true; + } + console.log("Nope"); + return false; } function setup_events(){ @@ -86,17 +59,24 @@ function setup_events(){ streaming = true; printButton.removeAttribute("disabled",""); + switch_cameras.removeAttribute("disabled",""); + } }, false); switch_cameras.addEventListener('click', function(ev) { - alert("Just turn your phone."); + flip_cameras(); }, false ); printButton.addEventListener('click', function(ev){ data = take_picture(); - print_picture(data) + try { + print_picture(data); + } catch (e) { + alert("Failed to print a picture because : " + e); + } + ev.preventDefault(); }, false); @@ -152,9 +132,144 @@ function print_picture(data){ // headers:{ // 'Content-Type': 'multipart/form-data' // } - }).then(response => console.log('Success:', response), true) + }).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);