<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
video,
canvas {
width: 640px;
}
</style>
</head>
<body>
<button id="start" onclick="start()" class="btn btn-lg btn-primary">Start capture</button>
<button id="detect" onclick="detect()" class="btn btn-lg btn-primary">Detect the face</button>
<br />
<video id="video" autoplay="true" muted="true"></video>
<canvas id="canvas"></canvas>
<script>
const detectBtn = document.getElementById('detect')
detectBtn.disabled = true;
function start() {
navigator.mediaDevices
.enumerateDevices()
.then((devices) => {
console.log('devices => ', devices);
var videoSource = null;
devices.forEach((device) => {
if (device.kind == 'videoinput') {
videoSource = device.deviceId;
}
});
const constraints = {
video: { deviceId: { exact: videoSource }, width: { max: 320 } },
};
console.log('constraints => ', constraints);
return navigator.mediaDevices.getUserMedia(constraints);
})
.then((stream) => {
document.getElementById('video').srcObject = stream;
document.getElementById('start').disabled = true;
document.getElementById('detect').disabled = false;
})
.catch((e) => {
console.error('getUserMedia() failed: ', e);
});
}
function detect() {
if (!Reflect.has(globalThis, 'FaceDetector')) {
document.body.innerHTML = `<h1>不支持人脸检测</h1>`;
return;
}
/** @type {HTMLCanvasElement} */
var canvas = document.getElementById('canvas');
/** @type {HTMLVideoElement} */
var video = document.getElementById('video');
if (video.videoWidth < video.offsetWidth) {
canvas.width = video.offsetWidth * devicePixelRatio;
canvas.height = video.offsetHeight * devicePixelRatio;
} else {
canvas.width = video.videoWidth * devicePixelRatio;
canvas.height = video.videoHeight * devicePixelRatio;
}
var ctx = canvas.getContext('2d');
var faceDetector = new FaceDetector();
video.requestVideoFrameCallback(_detect);
function _detect() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
faceDetector
.detect(canvas)
.then((faces) => {
ctx.lineWidth = 3;
ctx.strokeStyle = 'red';
for (var i = 0; i < faces.length; i++) {
const { x, y, width, height } = faces[i].boundingBox;
ctx.beginPath();
ctx.rect(
Math.floor(x),
Math.floor(y),
Math.floor(width),
Math.floor(height)
);
ctx.stroke();
}
ctx.closePath();
})
.catch((err) => {
console.log('error: => ' + err);
})
.finally(() => {
video.requestVideoFrameCallback(_detect);
});
}
}
</script>
</body>
</html>