clmtrackr.js使用示例代码
html代码:
<div class="video-con">
<video id="video" playsinline autoplay width="300" height="300"></video>
<canvas style="visibility: hidden" id="canvas" width="300" height="300"></canvas>
</div>
js代码:
import clm from "./clmtrackr.js";
export class FaceDemo {
constructor(options, successFunction) {
const opts = {
videoId: "video",
canvasId: "canvas",
mediaConfig: {
audio: false,
video: {
width: { min: 320, ideal: 720 },
height: { min: 320, ideal: 720 },
facingMode: "user"
}
}
};
this.video = document.getElementById(videoId);
this.canvasId = canvasId;
this.trackingStarted = false; // 是否开始检测人脸
this.chunks = []; // 视频文件
this.mediaRecorder = null; // 录制的视频对象
this.getUserMedia();
}
// 原生设备摄像头兼容性getUserMedia
getUserMedia() {
window.URL = window.URL || window.webkitURL || window.msURL || window.mozURL;
if (navigator.mediaDevices === undefined) {
navigator.mediaDevices = {};
}
if (navigator.mediaDevices.getUserMedia === undefined) {
navigator.mediaDevices.getUserMedia = function (constraints) {
const getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
if (!getUserMedia) {
return Promise.reject(new Error("当前浏览器不支持getUserMedia"));
}
return new Promise(function (resolve, reject) {
getUserMedia.call(navigator, constraints, resolve, reject);
});
};
}
}
// 初始化多媒体视频录制实例
initRecorder(stream) {
const self = this;
this.mediaRecorder = new MediaRecorder(stream);
this.chunks = [];
this.mediaRecorder.ondataavailable = function (event) {
if (event.data && event.data.size > 0) {
self.chunks.push(event.data);
}
};
this.mediaRecorder.onstop = () => {
let recorderFile = new Blob(this.chunks, {
type: "video/mp4"
});
// 供下载视频文件
const url = window.URL.createObjectURL(recorderFile);
const a = document.createElement("a");
a.style.display = "none";
a.href = url;
a.download = "video.mp4";
document.body.appendChild(a);
a.click();
// 供提交视频流
const file = new File([recorderFile], "video.mp4", {
type: "video/mp4"
});
};
}
// 开始录制视频
startRecorder() {
this.mediaRecorder.start();
}
// 结束视频录制
endRecorder() {
this.mediaRecorder.stop();
}
init() {
if (window.stream) {
window.stream.getTracks().forEach((track) => {
track.stop();
});
}
return new Promise((resolve, reject) => {
const self = this;
navigator.mediaDevices
.getUserMedia(this.options.mediaConfig)
.then((stream) => {
if ("srcObject" in this.video) {
window.stream = stream;
this.video.srcObject = stream;
} else {
this.video.src = window.URL && window.URL.createObjectURL(stream);
}
this.initRecorder(stream); // 初始化视频录制实例
this.startRecorder(); // 开始录制视频
this.video.onloadedmetadata = function () {
self.video.play();
setTimeout(() => {
self.positionLoop();
}, 1000);
};
this.video.onresize = function () {
if (self.trackingStarted) {
this.ctrack.stop();
this.ctrack.reset();
this.ctrack.start(self.video);
}
};
resolve();
})
.catch((err) => {
console.log("失败:" + err.message);
reject(err);
});
});
}
positionLoop() {
const self = this;
this.ctrack = new clm.tracker();
this.ctrack.init();
this.ctrack.start(this.video);
this.trackingStarted = true;
this.drawCanvas = document.getElementById(this.canvasId);
this.canvasCtx = this.drawCanvas.getContext("2d");
function drawLoop() {
requestAnimationFrame(drawLoop);
const positions = self.ctrack && self.ctrack.getCurrentPosition();
if (positions) {
// 检测到人脸模型数据,进行相应的操作
} else {
// 没有检测到人脸
console.log("没有检测到人脸");
}
}
drawLoop();
}
}
常见代码片段整理
navigator.mediaDevices.getUserMedia兼容处理
根据官方文档,目前navigator.mediaDevices.getUserMedia
在ios上只支持11版本以上,且只能在safari正常运行。安卓目前没有发现版本限制,需要兼容的代码:
getUserMedia() {
window.URL = window.URL || window.webkitURL || window.msURL || window.mozURL;
if (navigator.mediaDevices === undefined) {
navigator.mediaDevices = {};
}
if (navigator.mediaDevices.getUserMedia === undefined) {
navigator.mediaDevices.getUserMedia = function (constraints) {
const getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
if (!getUserMedia) {
return Promise.reject(new Error("当前浏览器不支持getUserMedia"));
}
return new Promise(function (resolve, reject) {
getUserMedia.call(navigator, constraints, resolve, reject);
});
};
}
}
第一次启用成功调用前置摄像头,第二次需要调用后置却黑屏或者失败
前置摄像头调用后,摄像功能需要关闭后才能正常执行第二次调用,否则会报错:设备被占用。解决方法,在每次执行调用方法前,先关闭摄像设备。
if (window.stream) {
window.stream.getTracks().forEach((track) => {
track.stop();
});
}
设置录制视频分辨率
navigator.mediaDevices.getUserMedia({
audio: true,
video: {
width: { min: 320, ideal: 720 },
height: { min: 320, ideal: 720 },
facingMode: "user"
}
})
MediaRecorder录制视频
initRecorder(stream) {
const self = this;
this.mediaRecorder = new MediaRecorder(stream);
this.chunks = [];
this.mediaRecorder.ondataavailable = function (event) {
if (event.data && event.data.size > 0) {
self.chunks.push(event.data);
}
};
this.mediaRecorder.onstop = () => {
let recorderFile = new Blob(this.chunks, {
type: "video/mp4"
});
// 供下载视频文件
const url = window.URL.createObjectURL(recorderFile);
const a = document.createElement("a");
a.style.display = "none";
a.href = url;
a.download = "video.mp4";
document.body.appendChild(a);
a.click();
// 供提交视频流
const file = new File([recorderFile], "video.mp4", {
type: "video/mp4"
});
};
}
参考地址
- clmtrackr.js官网API
- clmtrackr.js官网示例代码
- 基于前端的人脸探测小DEMO
- HTML5通过navigator.mediaDevices.getUserMedia调用手机摄像头问题