276 lines
7.1 KiB
JavaScript
276 lines
7.1 KiB
JavaScript
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);
|