Search code examples
javascriptcanvashtml5-videoface-api

face-api.js Use face expression model on hidden video feed


Just found out about the awesome face-api.js repo, and I'm having a great time using the face expressions API. Maybe because I was smiling too much (for the testing).

Anyway, In my app, I want to check if the user is smiling but without displaying the camera video on the screen.

For now, I can check if the user is smiling or not with a pretty good accuracy, but the video has to be on my screen.

How can I remove the video from the screen?

Here is the js code:

<video id="video" width="500" height="500" autoplay muted ></video>

async startVideo() {
      let stream = null;
      try {
        stream = await navigator.mediaDevices.getUserMedia({
          audio: false,
          video: { width: 1280, height: 720 },
        });
        this.video.srcObject = stream;
      } catch (e) {
        console.log(e);
      }
    },

this.video = document.getElementById('video');
    Promise.all([
      faceapi.nets.tinyFaceDetector.loadFromUri('/models'),
      faceapi.nets.faceExpressionNet.loadFromUri('/models'),
    ]).then(this.startVideo);
    this.video.addEventListener('play', () => {
      console.log('video started');
      setInterval(async () => {
        const detections = await faceapi.detectAllFaces(
          this.video,
          new faceapi.TinyFaceDetectorOptions(),
        ).withFaceExpressions();
        detections.forEach((detection) => {
          if (detection.expressions.happy >= 0.7) {
            this.isHappy = true;
          } else {
            this.isHappy = false;
          }
        });
      }, 100);
    });

The app is in vue.js, so I only took the parts that matter.

Your help is greatly appreciated. Cheers,


Solution

  • I'm here to answer my own question just in case someone needs it in the future.

    The obvious answer should be to add a "display: none;" to the video tag. However, this doesn't work somehow.

    Instead, I created the element in javascript, appended it to the DOM, and changed its display to "none", and it worked.

    Here is the code that made it work:

    this.video = document.createElement('video');
    this.video.setAttribute('id', 'video');
    this.video.setAttribute('autoplay', 'muted');
    document.body.appendChild(this.video);
    document.getElementById('video').style.display = 'none';