<span class="error"></span>
<br>
<label for="interval">Time between images in seconds: </label>
<input id="interval" type="text" value="1" min="1" pattern="\d+">
<br>
<button id="start">Start</button>
<br>
<label for="hideVid">Hide video element: </label>
<input id="hideVid" type="checkbox">
<br>
<p>Camera Settings</p>
<span id="settings"></span>
<p>Camera capabilities</p>
<span id="caps"></span>
<br>
<video autoplay muted playsinline></video>
<p>
  Images captured: <span id="image_count">0</span>
</p>
<br>
<button id="stop" disabled>Stop & Show Images</button>
<div id="images"></div>
    // check for support
    if(typeof ImageCapture === 'undefined'){
        const supportError = "ImageCapture is not supported by your browser";
        const errorSpan = document.querySelector('span.error');
        errorSpan.style = "color:red;font-size:larger;font-weight:bold";
        errorSpan.innerText = supportError;
        console.error(supportError);
    }

    const startBtn = document.querySelector('button#start');
    const stopBtn = document.querySelector('button#stop');
    const hideVid = document.querySelector('input#hideVid')
    const intervalSec = document.querySelector('input#interval');
    const videoElem = document.querySelector('video');
    const imageCountSpan = document.querySelector('span#image_count');
    const settingsSpan = document.querySelector('span#settings');
    const capsSpan = document.querySelector('span#caps');
    const imagesDiv = document.querySelector('div#images');
    const storage = [];     // Use this array as our database
    let stream, captureInterval;

    hideVid.onclick = () => videoElem.hidden = hideVid.checked;


    startBtn.onclick = async () => {
        startBtn.disabled = true;

        stream = await navigator.mediaDevices.getUserMedia({video: true});
        videoElem.onplaying = () => console.log("video playing stream:", videoElem.srcObject);
        videoElem.srcObject = stream;

        const [track] = stream.getVideoTracks();
        const imageCapture = new ImageCapture(track);
        const photoCapabilities = await imageCapture.getPhotoCapabilities();
        capsSpan.innerText = JSON.stringify(photoCapabilities);
        console.log("Photo Capabilities: ", photoCapabilities);
        const photoSettings = await imageCapture.getPhotoSettings();
        settingsSpan.innerText = JSON.stringify(photoSettings);
        console.log("Photo settings: ", photoSettings);

        // (data check on the interval value) * that value is in seconds  * frame timestamps are in microseconds
        const interval = (parseInt(intervalSec.value) >= 1 ? intervalSec.value * 1 : 1) * 1000;
        captureInterval = setInterval(async () => {
            const blob = await imageCapture.takePhoto()
                .catch(err => console.error(err)); // It took a few seconds for me the camera to get ready

            if(blob){
                console.log(blob);
                storage.push(blob);
                imageCountSpan.innerText++;
            }

        }, interval);

        stopBtn.disabled = false;
    }

    stopBtn.onclick = () => {
        // stop capture
        clearInterval(captureInterval);

        // close the camera
        stream.getTracks().forEach(track => track.stop());

        // Display each image
        function showImages() {
            const blob = storage.shift();
            const imageUrl = URL.createObjectURL(blob);
            const imgElem = new Image();
            imgElem.src = imageUrl;
            imagesDiv.appendChild(imgElem);

            if (storage.length > 0)
                showImages();
        }

        console.log("stored images");
        showImages();
    }

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.