Source: webcam.js

import * as THREE from "three";

/** Class to setup the webcam. */
class Webcam {
  /**
   * Create a Webcam.
   * @param options {Object} - options to use for initialising the camera. 
   * Currently idealWidth and idealHeight properties are understood as well as 
   * onVideoStarted(), a *required* callback which runs when the camera has
   * been initialised. 
   * This takes a THREE.VideoTexture as an argument which can be used to set 
   * the background of your three.js scene within a callback.
   * @param {string} videoElementSelector - selector to obtain the HTML video 
   * element to render the webcam feed. If a falsy value (e.g. null or 
   * undefined), a video element will be created.
   */
 constructor(options={}, videoElementSelector) {
    this.sceneWebcam = new THREE.Scene();
    let video;
    if (!videoElementSelector) {
      video = document.createElement("video");
      video.setAttribute("autoplay", true);
      video.setAttribute("playsinline", true);
      video.style.display = "none";
      document.body.appendChild(video);
    } else {
      video = document.querySelector(videoElementSelector);
    }
    this.texture = new THREE.VideoTexture(video);
    if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
      const constraints = {
        video: {
          width: { ideal: options.idealWidth || 1280 },
          height: { ideal: options.idealHeight || 720 },
          facingMode: "environment",
        },
      };
      navigator.mediaDevices.getUserMedia(constraints).then ( stream => {
        video.addEventListener('loadedmetadata', () => {
          video.setAttribute('width', video.videoWidth);
          video.setAttribute('height', video.videoHeight);
          video.play();
          options.onVideoStarted?.call(this, this.texture);
        });
        video.srcObject = stream;
      })
      .catch(e => {
        setTimeout(() => {
          alert(
            "Webcam Error\nName: " + e.name + "\nMessage: " + e.message
          );
        }, 1000)
      })
    } else {
      setTimeout(() => {
          alert("sorry - media devices API not supported");
        }, 1000);
    }
  }

  /**
   * Free up the memory associated with the webcam.
   * Should be called when your application closes.
   */
  dispose() {
    this.texture.dispose();
  }
}

export default Webcam;