I want to load the user's webcam to a canvas, and then save an image from that canvas as a blob. Hopefully, I will get 1 image every 1 second.
Unfortunately, I only get 1 image saved 5 times, rather than 5 different images. My code is fairly straightforward, but I suspect the issue is with my takeASnap()
function. What is going wrong?
Edit: This is observed on Safari on iPad/iPhone, but not in desktop chrome.
var NUM_IMAGES = 5;
const vid = document.querySelector('video');
navigator.mediaDevices.getUserMedia({ video: true }) // request cam
.then(stream => {
vid.srcObject = stream; // don't use createObjectURL(MediaStream)
return vid.play(); // returns a Promise
})
.then(() => { // enable the button
const btn = document.getElementById('download-button');
btn.disabled = false;
btn.onclick = e => {
imageId = 0;
userId = Math.floor(Math.random() * 10000);
recursiveDelay(kickOff, NUM_IMAGES, 1000)
};
});
function kickOff() {
takeASnap().then(saveBlob); // saveBlob out of scope of this question.
}
function recursiveDelay(functionToCall, executionsNumber, timeoutInMilliseconds) {
if (executionsNumber) { //exit condition
functionToCall(); // external function execution
setTimeout(
() => {
recursiveDelay(functionToCall, executionsNumber - 1, timeoutInMilliseconds); //recursive call
}, timeoutInMilliseconds);
}
}
function takeASnap() {
const canvas = document.createElement('canvas'); // create a canvas
const ctx = canvas.getContext('2d'); // get its context
canvas.width = vid.videoWidth; // set its size to the one of the video
canvas.height = vid.videoHeight;
ctx.drawImage(vid, 0, 0); // the video
return new Promise((res, rej) => {
canvas.toBlob(res, 'image/jpeg'); // request a Blob from the canvas
});
}