Face detection stops when back/forwarding on video (React)
See original GitHub issueHi! I’ve written this piece of code to have a video player with some basic functions: go 5 seconds backward-forward, play/pause buttons, and a checkbox to show/hide the face-api canvas with its detections.
import {React, useRef} from "react";
import './App.css';
import * as faceapi from "face-api.js/dist/face-api.min.js";
function App() {
let container = useRef();
let video = useRef();
let modelsLoaded = false;
let checkboxChecked = false;
let canvas;
let displaySize;
function backward(){
video.current.currentTime -= 5;
}
function forward(){
video.current.currentTime += 5;
}
function play(){
video.current.play();
}
function pause(){
video.current.pause();
}
function checkboxChanged() {
checkboxChecked = !checkboxChecked;
if(checkboxChecked === true)
loadModels();
}
function loadModels(){
if(modelsLoaded === false){
console.log("Loading models...")
Promise.all([
faceapi.nets.tinyFaceDetector.loadFromUri('./models'),
faceapi.nets.faceLandmark68Net.loadFromUri('./models'),
faceapi.nets.faceRecognitionNet.loadFromUri('./models'),
faceapi.nets.faceExpressionNet.loadFromUri('./models')
])
.then(() => {
console.log("Models loaded");
modelsLoaded = true;
createCanvas();
drawCanvas();
})
.catch((err) => console.log(err));
}
else{
drawCanvas();
}
}
function createCanvas(){
canvas = faceapi.createCanvasFromMedia(video.current);
canvas.style.position = "absolute";
container.current.append(canvas);
displaySize = { width: video.current.videoWidth, height: video.current.videoHeight };
faceapi.matchDimensions(canvas, displaySize);
}
async function drawCanvas(){
if(checkboxChecked){
canvas.style.display = "block";
const detections = await faceapi
.detectAllFaces(video.current, new faceapi.TinyFaceDetectorOptions())
.withFaceLandmarks()
.withFaceExpressions();
const resizedDetections = faceapi.resizeResults(detections, displaySize);
canvas.getContext('2d').clearRect(0, 0, canvas.width, canvas.height);
faceapi.draw.drawDetections(canvas, resizedDetections);
faceapi.draw.drawFaceLandmarks(canvas, resizedDetections);
faceapi.draw.drawFaceExpressions(canvas, resizedDetections);
requestAnimationFrame(drawCanvas);
}
else{
canvas.style.display = "none";
}
}
return (
<>
<div ref={container} id={"face-api-container"} style={{display: "flex"}}>
<video ref={video} id={"video"} controls autoPlay={true} muted={true} src="sintel.mp4"></video>
</div>
<button id={"backward_btn"} onClick={backward}>Bwd 5s</button>
<button id={"forward_btn"} onClick={forward}>Fwd 5s</button>
<button id={"play_btn"} onClick={play}>Play</button>
<button id={"pause_btn"} onClick={pause}>Pause</button>
<br/>
<input type={"checkbox"} onChange={checkboxChanged}
/>face-api
</>
);
}
export default App;
This works fine, despite a slight framerate drop in the video while face-api is enabled. When I press the backward (or forward) button, though, the face detection stops: the canvas stops being updated. Curiously, this does not happen with the play and pause buttons.
How should I change my code in order to prevent this behaviour and keep the face-api canvas updated?
Thanks in advance.
Issue Analytics
- State:
- Created 3 years ago
- Comments:12
Top Results From Across the Web
React Face Detection In 10 Minutes + Tag Your Friends App
Face detection app project using a free JavaScript library (face-api.js) and React.js. ... Your browser can't play this video.
Read more >Strict Mode - React
Detecting unexpected side effects. Conceptually, React does work in two phases: The render phase determines what changes need to be made to e.g....
Read more >An Update On Our Use of Face Recognition | Meta - Facebook
We're shutting down the Face Recognition system on Facebook, ... opted in will no longer be automatically be recognized in photos and videos....
Read more >princess memes funny
Here's all the best memes and reactions to Meghan Markle and Prince Harry's interview with ... However, with the help of advanced face...
Read more >react-use-face-detection - npm
Face detection React hook powered by @mediapipe/face_detection, ... to detect faces from an HTMLImageElement or react-webcam video source.
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
re:
video.paused
- yes, it’s ok to display canvas while paused, but you don’t want to run processing again and again on the same still frame. and since ifvideo.paused
you’d be also skipping call toclearRect
so last frame will stay displayed.but anyhow, glad it helped 😃
off-topic: i’m maintaining newer fork of
face-api.js
, optimized for ES2018 and TensorFlow 3.xhttps://github.com/vladmandic/face-api
there are better solutions, but this would be quick & easy - inside your
drawCanvas
function have that if statement just before callingfaceapi.detectAllFaces
so if it’s false, it basically skips entire faceapi processing block and immediately triggersrequestAnimationFrame
.since
requestAnimationFrame
is frame-limited, its ok.also extend the if with null check and paused check - something like
but on the other hand, you’re calling
drawCanvas
immeditely when models are loaded and it’s luck that loading of models takes longer than preparing of video - you should call that fromvideo.onloadeddata
event instead to make sure you don’t even triggerdrawCanvas
before video is ready.