JSFiddle - React, Tailwind, and code Playground

Multi face analysis with SDK, sequential

by morphcast

HTML

<script src="https://ai-sdk.morphcast.com/v1.15/ai-sdk.js"></script>

JavaScript

const cameraSource = CY.createSource.fromCamera({
  constraints: {
    audio: false,
    video: {
      width: 1280,
      height: 720
    }
  }
});


let crtImgData;
let resolver;
let nextFace = null;

const customSource = {
  /*
    frame producer
  */
  analyzeFrame(imageData) {
    if (resolver) {
      resolver(imageData);
      resolver = null;
    } else {
      crtImgData = imageData;
    }
  },
  /*
    frame consumer
  */
  getFrame(...args) {
    if (crtImgData) {
      const p = Promise.resolve(crtImgData);
      crtImgData = null;
      return p;
    } else {
      return new Promise(res => resolver = res);
    }
  },
  start() {
    return cameraSource.start();
  },
  stop() {
    return cameraSource.stop();
  },
  get stopped() {
    return cameraSource.stopped;
  }
};

CY.loader()
  .licenseKey("9087cfd2037a28a79769fdcaa4962252379cd2e2fd0b") // Alessandro Beltramin key
  .source(customSource)
  .addModule(CY.modules().FACE_DETECTOR.name, {
    multiFace: true
  }) // disables tracker to enable one-shot analysis
  .addModule(CY.modules().FACE_EMOTION.name, {
    smoothness: 0
  })
  .load().then(({
    start,
    stop
  }) => {
    start().then(() => tick());
    setTimeout(() => stop(), 10000);
    /* This event is called after each face analysis */

  }).catch((err) => {
    console.error(err);
  });
  
function addCanvas(imageData) {
}

function updateCanvas(canvas, imageData) {
}

function addDiv(text) {
}

window.addEventListener(CY.modules().EVENT_BARRIER.eventName, (evt) => {
  // It's better to use raw output for one-shot photo analysis.
  // This output is not documented because it should not be used in the normal scenario and could change in the future.
  console.log("EVENT_BARRIER", evt.detail); 
  const faces = evt.detail.face_detector.faces;
  
  if (evt.detail.face_emotion) {
  	const dominantEmotion = evt.detail.face_emotion.dominantEmotion; 
  	showResult(faces[0], dominantEmotion);
  }
  
  if (faces.length > 1) {
    frameArray =...