目录
效果展示
核心代码
相关问题
Error: getUserMedia is not implemented in this browser
DOMException: Permission denied
代码解析
HTML+JavaScript实现人脸识别页面,点击“人脸识别”按钮开始识别,扫描过程中有扫描条上下扫描,并且设置loading,扫描中不能再次人脸识别,前端捕获base64格式照片转file形式传递给后端做处理,若识别成功则跳转到主页面,识别失败则自动关闭人脸识别返回到本页面。
效果展示
人脸识别
核心代码
人脸识别:
<template>
<div>
<video id="videoCamera" :width="videoWidth" :height="videoHeight" class="camera_facing" autoplay >
</video>
<div class="saomiao" v-if="isVideo"></div>
<canvas style="display:none;" id="canvasCamera" :width="videoWidth" :height="videoHeight" ></canvas>
<div class="main-item-btn" @click="getCompetence()">
<el-button class="main-foot-button" :disabled="isVideo" >人脸识别</el-button>
</div>
</div>
</template>
<script>
import { faceRecognize } from "@/request/api/faceRecognize.js";
export default {
inject:['reload'],
data() {
return {
videoWidth: 435,
videoHeight: 435,
thisCancas: null,
thisContext: null,
thisVideo: null,
isVideo : false,
}
},
methods: {
getCompetence () {
this.isVideo = true;
var _this = this
this.thisCancas = document.getElementById('canvasCamera')
this.thisContext = this.thisCancas.getContext('2d')
this.thisVideo = document.getElementById('videoCamera')
if (navigator.mediaDevices === undefined) {
navigator.mediaDevices = {}
}
if (navigator.mediaDevices.getUserMedia === undefined) {
navigator.mediaDevices.getUserMedia = function (constraints) {
var getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.getUserMedia
if (!getUserMedia) {
return Promise.reject(new Error('getUserMedia is not implemented in this browser'))
}
return new Promise(function (resolve, reject) {
getUserMedia.call(navigator, constraints, resolve, reject)
})
}
}
var constraints = { audio: false, video: { width: this.videoWidth, height: this.videoHeight, transform: 'scaleX(-1)' } }
navigator.mediaDevices.getUserMedia(constraints).then(function (stream) {
if ('srcObject' in _this.thisVideo) {
_this.thisVideo.srcObject = stream
} else {
_this.thisVideo.src = window.URL.createObjectURL(stream)
}
_this.thisVideo.onloadedmetadata = function (e) {
_this.thisVideo.play()
}
}).catch(err => {
console.log(err)
this.isVideo = false;
})
setTimeout(() => {
_this.setImage();
}, 5000)
},
// 绘制图片(拍照功能)
setImage () {
var _this = this
// 按比例压缩4倍
var rate = (_this.videoWidth < _this.videoHeight ? _this.videoWidth / _this.videoHeight : _this.videoHeight / _this.videoWidth) / 5;
this.thisCancas.width = _this.videoWidth * rate;
this.thisCancas.height = _this.videoHeight * rate;
// 点击,canvas画图
_this.thisContext.drawImage(_this.thisVideo, 0, 0, _this.videoWidth, _this.videoHeight, 0, 0, _this.videoWidth * rate, _this.videoHeight * rate)
// 获取图片base64链接
var image = this.thisCancas.toDataURL('image/png');
var imgSrc = this.dataURLtoFile(image, "person.png");
let formData = new FormData();
formData.append("file", imgSrc);
faceRecognize(formData).then(res => {
if(res.code === 200) {
this.$store.commit("userInfo/UPDATE_ALL_USER_INFO", res.data)
this.$router.push("/index");
}else if(res.code === 500){
this.$message.error(res.msg);
this.reload();
}else{
this.$message.error("认证失败");
this.reload();
}
this.isVideo = false;
})
.catch(()=>{
this.$message.error("认证失败");
this.reload();
this.isVideo = false;
})
},
// base64转文件
dataURLtoFile (dataurl, filename) {
var arr = dataurl.split(',')
var mime = arr[0].match(/:(.*?);/)[1]
var bstr = atob(arr[1])
var n = bstr.length
var u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
return new File([u8arr], filename, { type: mime })
},
fullScreen() {
var el = document.documentElement;
var rfs = el.requestFullScreen || el.webkitRequestFullScreen || el.mozRequestFullScreen || el.msRequestFullScreen;
if (typeof rfs != "undefined" && rfs) {
rfs.call(el);
} else if (typeof window.ActiveXObject != "undefined") {
// for Internet Explorer
var wscript = new ActiveXObject("WScript.Shell");
if (wscript != null) {
wscript.SendKeys("{F11}");
}
}
}
}
}
</script>
<style lang="less" scoped>
.saomiao {
width: 75%;
margin-top: 20%;
height: 2px;
background: linear-gradient(244deg, rgba(255, 255, 255, 0) 0%, #56dafe 50%, rgba(255, 255, 255, 0) 100%);
position: absolute;
left: 50%;
transform: translateX(-50%);
top: 0px;
animation: move 3s ease-in-out infinite;
-webkit-animation: move 3s ease-in-out infinite;
}
@keyframes move {
from {
top: 0px
}
/*网格移动到显示区域的外面*/
to {
top: 400px
}
}
</style>
APP:
<template>
<div id="app">
<router-view v-if="isRouterAlive"/>
</div>
</template>
<script>
export default {
provide() {
return {
reload: this.reload
};
},
data() {
return {
isRouterAlive: true
},
methods: {
reload() {
this.isRouterAlive = false;
this.$nextTick(function() {
this.isRouterAlive = true;
});
},
}
}
</script>
相关问题
Error: getUserMedia is not implemented in this browser
后端接口可以调用,但是人脸识别摄像头未打开,报错:
若是edge浏览器则打开edge://flags/#unsafely-treat-insecure-origin-as-secure,chrome谷歌浏览器打开chrome://flags/#unsafely-treat-insecure-origin-as-secure,在Insecure origins treated as secure中输入自己的项目对应的ip和端口,点击Enabled并且重启。
DOMException: Permission denied
调用报的该异常,因为摄像头被禁止使用了,解决方法开启摄像头权限。
点击地址栏右侧摄像头图表,点击允许
代码解析
利用dom中HTML特征id属性查找其对应的<video><canvas>标签,在getCompetence()方法中若浏览器中缺少相关属性则添加mediaDevices和getUserMedia属性,并且设置人脸识别相机大小形状,在识别过程中利用isVideo属性确定是否显示扫描条,利用CSS3设置上下扫描动画,并且在扫描过程中利用isVideo不能点击按钮,以免重复不停调用后端接口,5秒后利用canvas画图获取base64图片,再次转换成file形式传到后端,若成功则自动跳转到index页面,若失败利用 provide
和 inject
实现页面刷新并且没有空白页面闪烁,重新返回到此页面。