<template>
<div class="face">
<div class="face-meiti">
<div class="tip">{{tip}}</div>
<video ref="video" id="video" objectFit="cover" :controls="false" :show-center-play-btn="false" :autoplay="true" :loop="true"></video>
<canvas ref="canvas" :style="canvasStyle" canvas-id="myCanvas" id="myCanvas"></canvas>
<view style="display: flex;justify-content: space-between;align-items: center;position: fixed;bottom: 0;left: 0;right:0;">
<template v-if="src && src.length > 0">
<template v-for="(item, index) in src">
<image style="width: 100%;" :key="index" :src="item.src" mode="widthFix"></image>
</template>
</template>
</view>
</div>
</div>
</template>
<script>
import '@/static/tracking/tracking-min.js';
import '@/static/tracking/data/face-min.js';
export default {
data() {
return {
tip:'请正对摄像头',
mediaStreamTrack:null,
video:null,// 播放器实例
trackerTask:null, //tracking实例
uploadLock: true, // 上传锁
faceflag:false,//是否进行拍照
src:[],
canvasStyle:{}
}
},
mounted() {
const _this = this;
uni.getSystemInfo({
success(res) {
_this.canvasStyle = {
width:res.windowWidth+'px',
height:res.windowWidth+'px',
}
_this.init({width:res.windowWidth, height:res.windowWidth});
}
})
},
methods: {
init(options) {
const _this = this;
if(document.getElementById('video') && document.getElementById('video').children[0] !== null && document.getElementById('video').children[0].children[0] !== null && document.getElementById('myCanvas') && document.getElementById('myCanvas').children[0] !== null) {
this.video = this.mediaStreamTrack = document.getElementById('video').children[0].children[0];
console.log(this.video)
this.getUserMedia = navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
navigator.getUserMedia({'video':true},function (stream) {
_this.video.srcObject = stream
},function (err) {
this.tip = '摄像头调用失败'
})
_this.initTracker(options)
}
},
initTracker(options){
const _this = this;
// 固定写法
let tracker = new window.tracking.ObjectTracker('face');
tracker.setInitialScale(4);
tracker.setStepSize(2);
tracker.setEdgesDensity(0.1);
// //摄像头初始化
this.trackerTask = window.tracking.track(this.video, tracker, {
camera: true
});
tracker.on('track', function (event){
if(event.data.length == 0){
if(!_this.faceflag){
_this.tip = '未检测到人脸'
}
}else if(event.data.length > 0){
_this.tip = '识别成功,正在拍照,请勿乱动~';
// const ctx = uni.createCanvasContext('myCanvas');
let canvas = document.getElementById('myCanvas').children[0];
const context = canvas.getContext('2d', {willReadFrequently: true});
event.data.forEach(function(rect) {
if(!_this.faceflag){
_this.faceflag = true;
context.drawImage(_this.video, 0, 0, options.width, options.height);
const base64Img = canvas.toDataURL('image/jpeg');
if(_this.src.length < 3){
_this.src.push({
src:base64Img
})
setTimeout(function (){
_this.faceflag = false
}, 500)
}else{
uni.showToast({
title:'检测认证已完成'
})
}
}
});
}
})
}
}
}
</script>
<style lang="scss">
.face{
width: 100vw;
height: 100vh;
display: flex;
justify-content: center;
align-items: flex-start;
padding: 60rpx 0;
box-sizing: border-box;
.face-meiti{
position: relative;
.tip{
text-align: center;
font-size: 24rpx;
padding-bottom: 30rpx;
}
video{
display: block;
width: 360rpx;
height: 360rpx;
-webkit-border-radius: 180rpx;
-moz-border-radius: 180rpx;
border-radius: 180rpx;
object-fit: cover;
border: 2rpx solid #000;
box-sizing: border-box;
margin: 0 auto;
}
canvas{
position: fixed;
top: 0;
left: 100vw;
}
}
img{
width: 100%;
height: auto;
}
}
</style>
注意:运行环境需要配置成https,否则是无法在移动设备上使用的
网友评论