Home  >  Q&A  >  body text

Safari: Webcamjs does not accurately capture live images

I'm developing a surveillance system where we need to take an image of the user every x minutes (with their permission) and make the webcam HTML element invisible to the user.

However, sometimes captured images show old images in Safari. I have created a mock application using webcamjs and I can reproduce this application in safari only when the webcam node is hidden from the viewport.

To hide the webcam element from the viewport, I used the following styles

#webcam{
  position: fixed;
  top: -10000px;
  left: -10000px;
}

Steps to reproduce

Specification

Browser: Safari version 16.0 Operating system: MacOS 12.6 WebcamJS: 1.0.26

Code

function loadWebcamJS(){
        const webcam = document.getElementById("webcam");
        Webcam.set({
          width: 640,
          height: 480
        });
        Webcam.attach(webcam);
        Webcam.on('load', afterLoad);
      }
      const getTime = (d) =>
          `${d.getHours()}:${d.getMinutes()}:${d.getSeconds()}`;

      function snap(){
        Webcam.snap((dataURI) => {
          const results = document.getElementById('results');
          const date = new Date();
          const time = getTime(date);
          
          results.innerHTML += `
          <div class="image">
            <img src=${dataURI}
              alt="Snapped Image">
            <h4>${time}</h4>
          </div>
          
          `

        })
      }
      loadWebcamJS();
      function afterLoad(){
        
        setInterval(() => {
          snap();
        }, 1000 * 10); //Snap images every 10 seconds
        
      }

P粉338969567P粉338969567244 days ago333

reply all(1)I'll reply

  • P粉144705065

    P粉1447050652024-02-18 09:40:52

    Please note that I'm not used to this library, so maybe they have a cleaner way to handle this.

    Autoplay seems to be failing on Safari. You can work around this by calling your own play() method of the <video> library that will be attached to your element.
    Note that if you don't want the element to be visible in the page, you don't need to include it in the DOM at all. I would even recommend against doing this, since browsers do use IntersectionObserver instances to pause invisible mute <video> elements. But they won't pause the separated <video>.

    So you can remove your <div> and associated CSS and just do something like

    const webcam = document.createElement("div");
    function loadWebcamJS() {
      Webcam.set({
        width: 640,
        height: 480
      });
      Webcam.attach(webcam);
      // force playing for Safari
      webcam.querySelector("video").play();
      Webcam.on("load", afterLoad);
    }
    

    Updated codepen (gUM does not allow the use of StackSnippets).

    reply
    0
  • Cancelreply