Appearance
Access Cameara with MediaDevices API 
A snippet to show how we can access camera to capture an image with MediaDevices API:
html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Cam test</title>
  </head>
  <body>
    <video autoplay></video>
    <button id="capture-btn">Capture</button>
    <canvas style="display:none;"></canvas>
    <img src="" />
    <script>
      const video = document.querySelector('video');
      const captureBtn = document.querySelector('#capture-btn');
      const canvas = document.querySelector('canvas');
      const img = document.querySelector('img');
      navigator.mediaDevices.getUserMedia({ video: true }).then((stream) => {
        video.srcObject = stream;
      });
      captureBtn.addEventListener('click', () => {
        canvas.width = video.videoWidth;
        canvas.height = video.videoHeight;
        canvas.getContext('2d').drawImage(video, 0, 0);
        // Other browsers will fall back to image/png
        img.src = canvas.toDataURL('image/webp');
      });
    </script>
  </body>
</html>What’s happening here?
- The video tag receives video stream from the camera instead of a source video URL. autoplay attribute is needed, otherwise the video display will be frozen on the first frame.
- navigator.mediaDevices.getUserMediais where the camera is accessed. The parameters could include audio: true if you want to access audio. After accessing camera successfully, the video feed streams video data into the video element
- To capture a screenshot, the canvas is used to draw the image, which then gets displayed within the img element.
Switching Cameras 
A crude implementation of switching cameras (back vs front in mobile):
html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Cam test</title>
  </head>
  <body>
    <video autoplay></video>
    <button id="capture-btn">Capture</button>
    <button id="change-cam-btn">Change camera</button>
    <canvas style="display:none;"></canvas>
    <img src="" />
    <script>
      const video = document.querySelector('video');
      const captureBtn = document.querySelector('#capture-btn');
      const changeCamBtn = document.querySelector('#change-cam-btn');
      const canvas = document.querySelector('canvas');
      const img = document.querySelector('img');
      let deviceIdArr = [];
      let index = 0;
      let constraints = {
        video: {
          deviceId: {
            exact: '',
          },
        },
      };
      let videoStream;
      function displayVideoFeed() {
        navigator.mediaDevices.getUserMedia(constraints).then((stream) => {
          videoStream = stream;
          video.srcObject = stream;
        });
      }
      function stopAllVideoTracks() {
        if (videoStream && videoStream.getVideoTracks().length > 0) {
          videoStream.getVideoTracks().forEach((track) => {
            track.stop();
          });
        }
      }
      function incrementIndex() {
        index++;
        if (index >= deviceIdArr.length) {
          index = 0;
        }
      }
      navigator.mediaDevices.enumerateDevices().then((devices) => {
        const videoDevices = devices.filter(
          (device) => device.kind === 'videoinput',
        );
        deviceIdArr = videoDevices.map((device) => device.deviceId);
        constraints.video.deviceId.exact = deviceIdArr[index];
        displayVideoFeed();
      });
      changeCamBtn.addEventListener('click', () => {
        incrementIndex();
        constraints.video.deviceId.exact = deviceIdArr[index];
        stopAllVideoTracks();
        displayVideoFeed();
      });
      captureBtn.addEventListener('click', () => {
        canvas.width = video.videoWidth;
        canvas.height = video.videoHeight;
        canvas.getContext('2d').drawImage(video, 0, 0);
        // Other browsers will fall back to image/png
        img.src = canvas.toDataURL('image/webp');
      });
    </script>
  </body>
</html>