前端代码
<template>
<view class="takePhotoBeforView">
<!-- 活体提示 -->
<div class="face-tips" v-if="step === 1">
<div class="title">多动作活体验证</div>
<div class="img">
<div class="img-bg"></div>
<div class="img-line"></div>
<img src="../static/images/face/face_tips4.png" >
</div>
<div class="content">
<p>请根据动作提示,按动作顺序</p>
<p>录制 <span class="red-text">1-3秒动作</span> 视频</p>
<p>请正对手机摄像头,确保面部光源充足</p>
</div>
<div class="btn" @click="nextStep">开始验证</div>
</div>
<!-- 活体视频录制 -->
<div class="face-box" v-show="step === 2">
<div class="title">多动作活体验证</div>
<div class="action-box">
<div class="action-box-p" v-if="actionVal.length > 1"><span class="txt">先{{ actionList[actionVal[0]].text }}、后{{ actionList[actionVal[1]].text }}</span></div>
<div class="action-box-list">
<div class="item" v-for="(item, index) in actionVal" :key="index">
<img :src="actionList[item].icon" >
</div>
</div>
</div>
<div class="face-success">
<div class="face-success-imgs">
<video ref="videoRef" style="object-fit:fill" :show-center-play-btn="false" muted preload></video>
</div>
</div>
<div class="btn" @click="saveVideo">{{ recordStatus === 0 ? '开始录制' : '结束录制(' + recordCount + 's)' }}</div>
</div>
<!-- 成功 -->
<div class="face-tips" v-if="step === 3">
<div class="title">多动作活体验证</div>
<div class="face-success">
<div class="face-success-img">
<img :src="videoImg" >
</div>
</div>
<div class="btn" @click="successBack">确定</div>
</div>
<!-- 失败 -->
<div class="face-tips" v-if="step === 4">
<div class="title">多动作活体验证</div>
<div class="error-wrap">
<div class="error-tips">{{ errorTips }}</div>
<div class="error-p">请确保本人操作,并避免以下问题</div>
<ul class="error-list">
<li>
<img src="../static/images/face/face_error1.jpg" >
<p>没有对焦</p>
</li>
<li>
<img src="../static/images/face/face_error2.jpg" >
<p>遮挡人脸</p>
</li>
<li>
<img src="../static/images/face/face_error3.jpg" >
<p>光照不均</p>
</li>
<li>
<img src="../static/images/face/face_error4.jpg" >
<p>手机晃动</p>
</li>
</ul>
</div>
<div class="btn" @click="again">重新检测</div>
</div>
</view>
</template
js代码
export default {
name: "VideoVerify",
data() {
return {
show: false,
step: 1, // 1 提示 2 录制 3 成功 4 失败
name: '',
idnum: '',
actionList: {
1: {
text: '眨眼',
icon: require('../static/images/face/face_tips1.png')
},
2: {
text: '张嘴',
icon: require('../static/images/face/face_tips2.png')
},
5: {
text: '转头',
icon: require('../static/images/face/face_tips3.png')
},
},
actionVal: [],
mediaRecorder: null,
MediaStreamTrack: null,
recordStatus: 0, // 0 未开始 1 正在录制
recordCount: 5,
recordedBlobs: [],
错误提示:'', 视频图片:'',// 人像识别图片 画布:null, }, mounted() {}, beforeDestroy() { this.MediaStreamTrack && this.MediaStreamTrack.stop() this.countTimer && clearTimeout(this.countTimer) }, methods: { showChoose(data) { this.again() this.show = true this.name = data.name this.idnum = data.idnum }, cancelChoose() { th
// 老的浏览器可能根本没有实现 mediaDevices,所以我们可以先设置一个空的对象
if (navigator.mediaDevices === undefined) {
navigator.mediaDevices = {}
}
// 一些浏览器部分支持 mediaDevices。我们不能直接给对象设置 getUserMedia
// 因为这样可能会覆盖已有的属性。这里我们只会在没有getUserMedia属性的时候添加它。
if (navigator.mediaDevices.getUserMedia === undefined) {
navigator.mediaDevices.getUserMedia = function (constraints) {
// 首先,如果有getUserMedia的话,就获得它
// var getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia
var getUserMedia = navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia
// 一些浏览器根本没实现它 - 那么就返回一个error到promise的reject来保持一个统一的接口
if (!getUserMedia) {
that.$modal.confirm('摄像头开启失败,请检查摄像头是否授权或是否可用!').then(() => {
that.cancelChoose()
})
return Promise.reject(new Error('getUserMedia is not implemented in this browser'))
}
// 否则,为老的navigator.getUserMedia方法包裹一个Promise
return new Promise(function (resolve, reject) {
getUserMedia.call(navigator, constraints, resolve, reject)
})
}
}
navigator.mediaDevices.getUserMedia(constraints) .then((stream) => { that.MediaStreamTrack = typeof stream.stop === 'function' ? stream : stream.getTracks()[0]; console.log(stream); console.log(that.MediaStreamTrack); let winURL = window.URL || window.webkitURL; const vide
let options = {
videoBitsPerSecond: 2500000
}
that.mediaRecorder = new MediaRecorder(stream, options)
``` this.getActionData() .catch((err) => { that.$modal.confirm('摄像头开启失败,请检查摄像头是否授权或是否可用!') .then(() => { that.cancelChoose() }) }) }, // 生成随 ```
return function walk() {
that.countTimer = setTimeout(function() {
that.countTimer && clearTimeout(that.countTimer)
let diff = sendTime + 5 - Math.round(+new Date() / 1000)
if (diff > 0) {
that.recordCount = diff
walk()
} else {
console.log('倒计时结束')
that.recordStatus = 1
that.saveVideo()
}
}, 1000)
}
},
// 保存录制视频
saveVideo() {
this.canvas = document.createElement("canvas");
let context = this.canvas.getContext("2d");
const video = document.querySelector("video");
this.canvas.width = 720;
this.canvas.height = 864;
context.drawImage(video, 0, 0, this.canvas.width,this.canvas.height);
let canvas = this.canvas.toDataURL("image/png");
this.videoImg=canvas;
if (this.recordStatus === 1) {
this.countTimer && clearTimeout(this.countTimer)
//当录制的数据可用时
this.mediaRecorder.ondataavailable = (e) => {
console.log(e)
if (e.data && e.data.size > 0) {
this.recordedBlobs.push(e.data)
}
}
this.mediaRecorder.stop()
setTimeout(() => {
var blob = new Blob(this.recordedBlobs, {type: 'video/mp4'})
console.log(blob)
this.isAlreadyRecord = false
this.MediaStreamTrack && this.MediaStreamTrack.stop()
var reader = new FileReader();
reader.readAsDataURL(blob, 'utf-8')
reader.onload = () => {
console.log(reader.result); // base64格式
let result = reader.result.replace(/^data:video\/\w+;base64,/, '')
this.faceReco(result)
}
}, 1000)
if (condition) { this.count = 8; this.recordStatus = 1; this.mediaRecorder.start(5000); this.countDown()(); } else { console.log(视频识别活检比对中); console.log(video); let that = this; that.$modal.loading(验证中...); setTimeout(() => { let random_boolean = Math.random()
还木有评论哦,快来抢沙发吧~