目录
tracking-min.js
face-min.js
下载地址: https://github.com/eduardolundgren/tracking.js/
<div class="wrapper">
<video id="video" autoplay muted width="400" height="400"></video>
<canvas id="canvas" width="400" height="400"></canvas>
<canvas id="screenshotCanvas" width="400" height="400"></canvas>
</div>
var deviceList = [];
navigator.mediaDevices
.enumerateDevices()
.then(devices => {
devices.forEach(device => {
deviceList.push(device.kind);
});
if (deviceList.indexOf("videoinput") == "-1") {
console.info("没有摄像头");
return false;
} else {
console.info("有摄像头");
// flag = true; // 这是我自定义的一个状态,初始值为false
}
console.log(deviceList);
})
.catch(function (err) {
alert(err.name + ": " + err.message);
});
if (navigator.mediaDevices === undefined) {
navigator.mediaDevices = {}
}
// 一些浏览器实现了部分mediaDevices,我们不能只分配一个对象
// 使用getUserMedia,因为它会覆盖现有的属性。
// 这里,如果缺少getUserMedia属性,就添加它。
if (navigator.mediaDevices.getUserMedia === undefined) {
navigator.mediaDevices.getUserMedia = function (constraints) {
// 首先获取现存的getUserMedia(如果存在)
var getUserMedia =
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.getUserMedia
// 有些浏览器不支持,会返回错误信息
// 保持接口一致
if (!getUserMedia) {
return Promise.reject(
new Error('getUserMedia is not implemented in this browser')
)
}
// 否则,使用Promise将调用包装到旧的navigator.getUserMedia
return new Promise(function (resolve, reject) {
getUserMedia.call(navigator, constraints, resolve, reject)
})
}
}
const videoArr = []
await navigator.mediaDevices.enumerateDevices().then(function (devices) {
console.log(devices, '浏览器设备信息')
devices.map(function (device) {
if (device.kind === 'videoinput') {
// 获取所有摄像头
videoArr.push({
label: device.label,
id: device.deviceId
})
}
})
})
const videoDoM = document.getElementById('video')
const constraints = {
audio: false,
video: {
deviceId: videoArr[0].id,
width: videoDoM.offsetWidth,
height: videoDoM.offsetHeight,
transform: 'scaleX(-1)'
}
}
await navigator.mediaDevices
.getUserMedia(constraints)
.then(function (stream) {
// 旧的浏览器可能没有srcObject
if ('srcObject' in videoDoM) {
videoDoM.srcObject = stream
} else {
// 避免在新的浏览器中使用它,因为它正在被弃用。
videoDoM.src = window.URL.createObjectURL(stream)
}
videoDoM.onloadedmetadata = function (e) {
videoDoM.play()
}
})
.catch((err) => {
console.log(err)
})
// 固定写法
let trackerTask
const tracker = new window.tracking.ObjectTracker('face')
const context = canvas.getContext('2d')
tracker.setInitialScale(4)
tracker.setStepSize(2)
tracker.setEdgesDensity(0.1)
trackerTask = window.tracking.track('#video', tracker)
tracker.on('track', function (event) {
context.clearRect(0, 0, canvas.width, canvas.height)
if (event.data.length === 0) {
// 没有检测到
}
else if (event.data.length > 1) {
_this.$message.error({ content: '检测到多个人脸!', key: this.key, duration: 2})
_this.$message.error('检测到多个人脸!', 2)
}
else {
event.data.forEach(function (rect) {
context.strokeStyle = '#00bc12'
context.lineWidth = 3
context.strokeRect(rect.x, rect.y, rect.width, rect.height)
// 上传图片
// uploadLock 避免重复上传定义的flag
// _this.uploadLock && _this.screenshotAndUpload()
})
}
})
this.uploadLock = false
// 绘制当前帧图片转换为
const canvas = document.getElementById('screenshotCanvas')
const video = document.getElementById('video')
const ctx = canvas.getContext('2d')
ctx.clearRect(0, 0, canvas.width, canvas.height)
ctx.drawImage(video, 0, 0, canvas.width, canvas.height)
this.base64Img = canvas.toDataURL('image/jpeg')
// 使用 base64Img 请求接口即可
console.log('base64Img:', this.base64Img)
this.$set(this.infoData, 'faceImgBase64', this.base64Img)
this.infoData.faceImgBase64 = this.base64Img
console.log(this.infoData)
// do something 可以上传图片了
// this.$store.commit('SET_CHECKED', true) // 接口请求成功后再改变该值,测试需提前变更
// 请求接口成功以后打开锁
// this.uploadLock = true;