JSFiddle - React, Tailwind, and code Playground

by morphcast

HTML

<!DOCTYPE html>
<html>
<head>
  <title>Dynamic Camera Selector for MorphCast AI SDK</title>
  <script src="https://ai-sdk.morphcast.com/v1.16/ai-sdk.js"></script>
</head>
<body>
  <select id="cameraSelect"></select>
  <video id="video" autoplay playsinline muted width="320" height="240"></video>
  <script>
    let cyInstance;
    let currentSource;
    const video = document.getElementById('video');
    const cameraSelect = document.getElementById('cameraSelect');

    async function getCameras() {
      // 1. Request camera permission
      await navigator.mediaDevices.getUserMedia({ video: true });
      // 2. List all devices
      const devices = await navigator.mediaDevices.enumerateDevices();
      return devices.filter(d => d.kind === 'videoinput');
    }

    async function startCamera(deviceId) {
      // 4. Create new MorphCast source with selected deviceId
      const constraints = {
        audio: false,
        video: { deviceId: { exact: deviceId } }
      };
      if (currentSource && currentSource.stop) currentSource.stop();
      // Remove old stream (optional, for UI)
      video.srcObject = null;
      // Create a new source
      currentSource = CY.createSource.fromCamera({ constraints, video });
      // (Re)initialize the SDK
      if (cyInstance && cyInstance.stop) await cyInstance.stop();
      cyInstance = await CY.loader()
        .licenseKey("9087cfd2037a28a79769fdcaa4962252379cd2e2fd0b")
        .source(currentSource)
        .addModule(CY.modules().FACE_DETECTOR.name)
        .load();
      cyInstance.start(); // ### CREA ISTANZE MULTIPLE!! ERRATO
    }

    // 3. Populate <select> and handle changes
    getCameras().then(cameras => {
      cameras.forEach(cam => {
        const opt = document.createElement('option');
        opt.value = cam.deviceId;
        opt.text = cam.label || `Camera ${cameraSelect.length + 1}`;
        cameraSelect.appendChild(opt);
      });
      if...