|
@@ -21,7 +21,7 @@
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<div class="tc">
|
|
<div class="tc">
|
|
- <p v-if="errMsg" style="font-size: 30px;color: red;"> {{errMsg}}</p>
|
|
|
|
|
|
+ <p v-if="errMsg && identifyFace" style="font-size: 30px;color: red;"> {{errMsg}}</p>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
</el-col>
|
|
</el-col>
|
|
@@ -91,19 +91,25 @@
|
|
</el-col>
|
|
</el-col>
|
|
|
|
|
|
</el-row>
|
|
</el-row>
|
|
- <div class="left-float" v-if="!closeFace" v-drag v-show="identifyFacePass">
|
|
|
|
|
|
+<!-- <div class="left-float" v-if="!closeFace" v-drag v-show="identifyFacePass">
|
|
<video ref="video" width="240" height="180" autoplay></video>
|
|
<video ref="video" width="240" height="180" autoplay></video>
|
|
<canvas ref="canvas" v-show="ontakebtn" width="240" height="180"></canvas>
|
|
<canvas ref="canvas" v-show="ontakebtn" width="240" height="180"></canvas>
|
|
|
|
+ </div> -->
|
|
|
|
+
|
|
|
|
+ <div class="left-float-dialog" v-drag v-show="identifyFace">
|
|
|
|
+ <i-collect :updateTime="updateTime" @getface="getface" />
|
|
</div>
|
|
</div>
|
|
|
|
|
|
- <el-dialog title="人脸认证" center :visible.sync="identifyFace" width="500px" :close-on-click-modal="false">
|
|
|
|
|
|
+ <!-- <el-dialog class="left-float-dialog" title="人脸认证" center
|
|
|
|
+ :visible.sync="identifyFace" width="460px" :close-on-click-modal="false">
|
|
|
|
+ <i-collect @getface="getface" />
|
|
<div style="width: 240px;margin: 100px auto;">
|
|
<div style="width: 240px;margin: 100px auto;">
|
|
<video ref="video2" width="240" height="180" autoplay></video>
|
|
<video ref="video2" width="240" height="180" autoplay></video>
|
|
<p style="margin-top: 20px;">当前照片:</p>
|
|
<p style="margin-top: 20px;">当前照片:</p>
|
|
<canvas ref="canvas" width="240" height="180"></canvas>
|
|
<canvas ref="canvas" width="240" height="180"></canvas>
|
|
<p v-if="errMsg" style="font-size: 30px;color: red;"> {{errMsg}}</p>
|
|
<p v-if="errMsg" style="font-size: 30px;color: red;"> {{errMsg}}</p>
|
|
</div>
|
|
</div>
|
|
- </el-dialog>
|
|
|
|
|
|
+ </el-dialog> -->
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</template>
|
|
|
|
|
|
@@ -118,6 +124,7 @@
|
|
videoPlayer
|
|
videoPlayer
|
|
} from 'vue-video-player';
|
|
} from 'vue-video-player';
|
|
import IMessage from '@/components/message/iMessage.vue'
|
|
import IMessage from '@/components/message/iMessage.vue'
|
|
|
|
+ import ICollect from '@/components/face/iCollect.vue'
|
|
import 'video.js/dist/video-js.css'
|
|
import 'video.js/dist/video-js.css'
|
|
// import html2canvas from "html2canvas";
|
|
// import html2canvas from "html2canvas";
|
|
import {
|
|
import {
|
|
@@ -140,12 +147,17 @@
|
|
curTimes: 0,
|
|
curTimes: 0,
|
|
errMsg: '',
|
|
errMsg: '',
|
|
errCount: 0,
|
|
errCount: 0,
|
|
|
|
+ prevCollect: 0,
|
|
|
|
+ onIdentify: false,
|
|
|
|
+ updateTime: 0,
|
|
|
|
+ imgbase64: '',
|
|
onPlay: false
|
|
onPlay: false
|
|
}
|
|
}
|
|
},
|
|
},
|
|
components: {
|
|
components: {
|
|
videoPlayer,
|
|
videoPlayer,
|
|
- IMessage
|
|
|
|
|
|
+ IMessage,
|
|
|
|
+ ICollect
|
|
},
|
|
},
|
|
props: ['media', 'options', 'heartbeat', 'maxErrorCount', 'collectBeat', 'closeFace', 'chapter', 'list'],
|
|
props: ['media', 'options', 'heartbeat', 'maxErrorCount', 'collectBeat', 'closeFace', 'chapter', 'list'],
|
|
filters: {
|
|
filters: {
|
|
@@ -186,7 +198,7 @@
|
|
},
|
|
},
|
|
beforeDestroy() {
|
|
beforeDestroy() {
|
|
this.destroyTimer()
|
|
this.destroyTimer()
|
|
- this.closeCamera( "video" )
|
|
|
|
|
|
+ // this.closeCamera( "video" )
|
|
},
|
|
},
|
|
created() {
|
|
created() {
|
|
this.startTick()
|
|
this.startTick()
|
|
@@ -201,43 +213,58 @@
|
|
this.tickNum = 0
|
|
this.tickNum = 0
|
|
this.errMsg = ''
|
|
this.errMsg = ''
|
|
this.errCount = 0
|
|
this.errCount = 0
|
|
|
|
+ this.prevCollect = 0;
|
|
this.startIdentify()
|
|
this.startIdentify()
|
|
this.setposition( this.media.position )
|
|
this.setposition( this.media.position )
|
|
}
|
|
}
|
|
},
|
|
},
|
|
methods: {
|
|
methods: {
|
|
|
|
+ getface( val){
|
|
|
|
+ this.imgbase64 = val;
|
|
|
|
+ let now = parseInt( Date.now()/1000 );
|
|
|
|
+ if( !this.identifyFacePass && this.prevCollect != now ){
|
|
|
|
+ this.prevCollect = now
|
|
|
|
+ this.photograph("video2")
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ handler_msg(pause, identify, msg ){
|
|
|
|
+ this.errMsg = msg || '';
|
|
|
|
+ if (msg) {
|
|
|
|
+ this.errCount++
|
|
|
|
+ } else {
|
|
|
|
+ if( identify ){
|
|
|
|
+ this.identifyPassAndPlay()
|
|
|
|
+ }
|
|
|
|
+ this.errCount = 0;
|
|
|
|
+ }
|
|
|
|
+ if (!identify && this.errCount > this.maxErrorCount) {
|
|
|
|
+ this.doPause();
|
|
|
|
+ }
|
|
|
|
+ },
|
|
photograph( ref ) {
|
|
photograph( ref ) {
|
|
let identify = (ref=="video2");
|
|
let identify = (ref=="video2");
|
|
- let ctx = this.$refs["canvas"].getContext("2d");
|
|
|
|
- // 把当前视频帧内容渲染到canvas上
|
|
|
|
this.ontakebtn = true
|
|
this.ontakebtn = true
|
|
- ctx.drawImage(this.$refs[ref], 0, 0, 240, 180);
|
|
|
|
- // 转base64格式、图片格式转换、图片质量压缩
|
|
|
|
- let imgBase64 = this.$refs["canvas"].toDataURL("image/jpeg", 1); // 由字节转换为KB 判断大小
|
|
|
|
- this.ontakebtn = false
|
|
|
|
- let str = imgBase64.replace("data:image/jpeg;base64,", "");
|
|
|
|
|
|
+ if( this.onIdentify ){
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ if( !this.imgbase64 ){
|
|
|
|
+ this.handler_msg(false, identify, "人脸不在视频上" );
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ this.onIdentify = true;
|
|
let param = {
|
|
let param = {
|
|
id: this.media.id,
|
|
id: this.media.id,
|
|
ref,
|
|
ref,
|
|
- image: str
|
|
|
|
|
|
+ image: this.imgbase64
|
|
}
|
|
}
|
|
|
|
+ this.imgbase64 = '';
|
|
httpServer("course.collect", param).then(res => {
|
|
httpServer("course.collect", param).then(res => {
|
|
let {
|
|
let {
|
|
msg,
|
|
msg,
|
|
pause
|
|
pause
|
|
} = res.data
|
|
} = res.data
|
|
- this.errMsg = msg || '';
|
|
|
|
- if (msg) {
|
|
|
|
- this.errCount++
|
|
|
|
- } else {
|
|
|
|
- if( identify ){
|
|
|
|
- this.identifyPassAndPlay()
|
|
|
|
- }
|
|
|
|
- this.errCount = 0;
|
|
|
|
- }
|
|
|
|
- if (!identify && this.errCount > this.maxErrorCount) {
|
|
|
|
- this.doPause();
|
|
|
|
- }
|
|
|
|
|
|
+ this.onIdentify = false;
|
|
|
|
+ this.handler_msg(pause, identify, msg )
|
|
})
|
|
})
|
|
},
|
|
},
|
|
destroyTimer() {
|
|
destroyTimer() {
|
|
@@ -253,39 +280,6 @@
|
|
goSubState(item, index) {
|
|
goSubState(item, index) {
|
|
this.$emit('loadMedia', item, index)
|
|
this.$emit('loadMedia', item, index)
|
|
},
|
|
},
|
|
- callCamera( ref ) {
|
|
|
|
- // H5调用电脑摄像头API
|
|
|
|
- if (this.closeFace) {
|
|
|
|
- this.identifyFacePass = true;
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- navigator.mediaDevices
|
|
|
|
- .getUserMedia({
|
|
|
|
- video: true,
|
|
|
|
- })
|
|
|
|
- .then((success) => {
|
|
|
|
- // 摄像头开启成功
|
|
|
|
- this.$refs[ref].srcObject = success;
|
|
|
|
- // 实时拍照效果
|
|
|
|
- this.$refs[ref].play();
|
|
|
|
- })
|
|
|
|
- .catch((error) => {
|
|
|
|
- this.$message.error(
|
|
|
|
- "摄像头开启失败,请检查摄像头是否可用!或者打开摄影头"
|
|
|
|
- );
|
|
|
|
- console.error("摄像头开启失败,请检查摄像头是否可用!");
|
|
|
|
- });
|
|
|
|
- },
|
|
|
|
- closeCamera( ref ) {
|
|
|
|
- if (!this.$refs[ref]) return;
|
|
|
|
- if (!this.$refs[ref].srcObject) return;
|
|
|
|
- let stream = this.$refs[ref].srcObject;
|
|
|
|
- let tracks = stream.getTracks();
|
|
|
|
- tracks.forEach((track) => {
|
|
|
|
- track.stop();
|
|
|
|
- });
|
|
|
|
- this.$refs[ref].srcObject = null;
|
|
|
|
- },
|
|
|
|
startTick() {
|
|
startTick() {
|
|
let tick = this.tryTick;
|
|
let tick = this.tryTick;
|
|
this.destroyTimer();
|
|
this.destroyTimer();
|
|
@@ -351,7 +345,7 @@
|
|
this.reportErr("play", 'close')
|
|
this.reportErr("play", 'close')
|
|
this.doPause()
|
|
this.doPause()
|
|
this.$emit("close")
|
|
this.$emit("close")
|
|
- this.closeCamera( "video")
|
|
|
|
|
|
+ // this.closeCamera( "video")
|
|
},
|
|
},
|
|
doPause() {
|
|
doPause() {
|
|
this.onPlay = false
|
|
this.onPlay = false
|
|
@@ -372,6 +366,7 @@
|
|
this.onPlay = true
|
|
this.onPlay = true
|
|
if( !this.identifyFacePass){
|
|
if( !this.identifyFacePass){
|
|
this.startIdentify()
|
|
this.startIdentify()
|
|
|
|
+ return
|
|
}
|
|
}
|
|
this.reportErr("play", 'start');
|
|
this.reportErr("play", 'start');
|
|
this.startTick();
|
|
this.startTick();
|
|
@@ -380,16 +375,12 @@
|
|
if( !this.closeFace){
|
|
if( !this.closeFace){
|
|
this.identifyFace = true
|
|
this.identifyFace = true
|
|
this.identifyFacePass = false
|
|
this.identifyFacePass = false
|
|
- this.closeCamera("video")
|
|
|
|
- this.callCamera("video2")
|
|
|
|
|
|
+ this.updateTime = Date.now()
|
|
}
|
|
}
|
|
this.startTick()
|
|
this.startTick()
|
|
},
|
|
},
|
|
identifyPassAndPlay(){
|
|
identifyPassAndPlay(){
|
|
this.identifyFacePass = true
|
|
this.identifyFacePass = true
|
|
- this.identifyFace = false;
|
|
|
|
- this.closeCamera("video2")
|
|
|
|
- this.callCamera("video")
|
|
|
|
this.$message.successMsg("人脸认证通过", 2)
|
|
this.$message.successMsg("人脸认证通过", 2)
|
|
this.doPlay()
|
|
this.doPlay()
|
|
},
|
|
},
|
|
@@ -548,6 +539,19 @@
|
|
text-align: center;
|
|
text-align: center;
|
|
border-radius: 5px;
|
|
border-radius: 5px;
|
|
}
|
|
}
|
|
|
|
+ .left-float-dialog{
|
|
|
|
+ width: 240px;
|
|
|
|
+ height: 180px;
|
|
|
|
+ /* background-color: #8bbdf5; */
|
|
|
|
+ position: fixed;
|
|
|
|
+ transition: bottom ease .9s;
|
|
|
|
+ z-index: 0;
|
|
|
|
+ left: 20px;
|
|
|
|
+ top: 140px;
|
|
|
|
+ text-align: center;
|
|
|
|
+ border-radius: 5px;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
|
|
.p-process {
|
|
.p-process {
|
|
width: 100%;
|
|
width: 100%;
|