|
@@ -10,7 +10,6 @@
|
|
|
|
|
|
<div style="height: 540px;">
|
|
|
<video-player id="myVideo" class="video-player-box" ref="videoPlayer"
|
|
|
-
|
|
|
@pause="onPlayerPause($event)"
|
|
|
@play="onPlayerStart($event)"
|
|
|
@ready="playerReadied"
|
|
@@ -21,7 +20,7 @@
|
|
|
</div>
|
|
|
|
|
|
<div class="tc">
|
|
|
- <p v-if="errMsg && identifyFace" style="font-size: 30px;color: red;"> {{errMsg}}</p>
|
|
|
+ <p v-if="errMsg" style="font-size: 30px;color: red;"> {{errMsg}}</p>
|
|
|
</div>
|
|
|
|
|
|
</el-col>
|
|
@@ -91,30 +90,19 @@
|
|
|
</el-col>
|
|
|
|
|
|
</el-row>
|
|
|
-<!-- <div class="left-float" v-if="!closeFace" v-drag v-show="identifyFacePass">
|
|
|
- <video ref="video" width="240" height="180" autoplay></video>
|
|
|
- <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>
|
|
|
|
|
|
- <el-dialog title="开始人脸认证" center :visible.sync="identifyFaceDialog" width="400px" :append-to-body="true" >
|
|
|
+ <el-dialog title="开始人脸认证" center :visible.sync="identifyFaceDialog" width="540px" :append-to-body="true" >
|
|
|
<div>
|
|
|
- <p style="color: red;font-size: 24px;text-align: center;"> 请将人脸对准摄像头</p>
|
|
|
- <canvas id="canvas" width="240" height="180"></canvas>
|
|
|
+ <i-collect :updateTime="updateTime" @getface="getface" />
|
|
|
<div class="tc m20">
|
|
|
- <p v-if="errMsg && identifyFace" 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>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
- // import tracking from '@/assets/tracking/build/tracking-min.js';
|
|
|
- // import '@/assets/tracking/build/data/face-min.js';
|
|
|
import {
|
|
|
httpServer
|
|
|
} from "@/components/httpServer/httpServer.js";
|
|
@@ -125,7 +113,6 @@
|
|
|
import IMessage from '@/components/message/iMessage.vue'
|
|
|
import ICollect from '@/components/face/iCollect.vue'
|
|
|
import 'video.js/dist/video-js.css'
|
|
|
- // import html2canvas from "html2canvas";
|
|
|
import {
|
|
|
MessageBox
|
|
|
} from "element-ui";
|
|
@@ -138,17 +125,18 @@
|
|
|
tickNum: 0,
|
|
|
prevTime: 0,
|
|
|
isReady: false,
|
|
|
- ontakebtn: false,
|
|
|
- identifyFace: false,
|
|
|
- identifyFacePass: false,
|
|
|
identifyFaceDialog: false,
|
|
|
+ startPlay: false, // 开始认证
|
|
|
+ nextFaceTime: 0,
|
|
|
+ faceInterval: 10, // 打开人脸时间
|
|
|
+ closeDailogTime: 20, // 关闭dialog时间
|
|
|
+ onIdentify: false, // 同一时间一个认证
|
|
|
+ identifyDuration: 180*1000,
|
|
|
activeChapter: '',
|
|
|
activeName: '',
|
|
|
curTimes: 0,
|
|
|
errMsg: '',
|
|
|
- errCount: 0,
|
|
|
prevCollect: 0,
|
|
|
- onIdentify: false,
|
|
|
updateTime: 0,
|
|
|
imgbase64: '',
|
|
|
onPlay: false,
|
|
@@ -177,21 +165,6 @@
|
|
|
this.stopTick()
|
|
|
this.reportErr("play", 'destroy');
|
|
|
},
|
|
|
- directives: {
|
|
|
- drag(el, bindings) {
|
|
|
- el.onmousedown = function(e) {
|
|
|
- var disx = e.pageX - el.offsetLeft
|
|
|
- var disy = e.pageY - el.offsetTop
|
|
|
- document.onmousemove = function(e) {
|
|
|
- el.style.left = e.pageX - disx + 'px'
|
|
|
- el.style.top = e.pageY - disy + 'px'
|
|
|
- }
|
|
|
- document.onmouseup = function() {
|
|
|
- document.onmousemove = document.onmouseup = null
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- },
|
|
|
computed: {
|
|
|
player() {
|
|
|
return this.$refs.videoPlayer.player
|
|
@@ -199,10 +172,8 @@
|
|
|
},
|
|
|
beforeDestroy() {
|
|
|
this.destroyTimer()
|
|
|
- // this.closeCamera( "video" )
|
|
|
},
|
|
|
created() {
|
|
|
- this.startTick()
|
|
|
this.startMonitor();
|
|
|
this.activeChapter = this.media.chapterName;
|
|
|
this.activeName = this.media.name
|
|
@@ -213,7 +184,6 @@
|
|
|
this.activeName = this.media.name
|
|
|
this.tickNum = 0
|
|
|
this.errMsg = ''
|
|
|
- this.errCount = 0
|
|
|
this.prevCollect = 0;
|
|
|
this.startIdentify()
|
|
|
this.setposition( this.media.position )
|
|
@@ -223,33 +193,30 @@
|
|
|
getface( val){
|
|
|
this.imgbase64 = val;
|
|
|
let now = parseInt( Date.now()/2000 );
|
|
|
- if( !this.identifyFacePass && this.prevCollect != now ){
|
|
|
+ // 人脸认证期间, 一秒一次
|
|
|
+ if( !this.identifyFaceDialog && this.prevCollect != now ){
|
|
|
this.prevCollect = now
|
|
|
- this.photograph("video2")
|
|
|
+ this.photograph("video")
|
|
|
}
|
|
|
},
|
|
|
- handler_msg(pause, identify, msg ){
|
|
|
+ handler_msg(pause, msg ){
|
|
|
this.errMsg = msg || '';
|
|
|
- if (msg) {
|
|
|
- this.errCount++
|
|
|
- } else {
|
|
|
- if( identify ){
|
|
|
- this.identifyPassAndPlay()
|
|
|
- }
|
|
|
- this.errCount = 0;
|
|
|
- }
|
|
|
- if (!identify && this.errCount > this.maxErrorCount) {
|
|
|
- this.doPause();
|
|
|
+ if ( !msg ) {
|
|
|
+ this.identifyPassAndPlay()
|
|
|
}
|
|
|
},
|
|
|
photograph( ref ) {
|
|
|
- let identify = (ref=="video2");
|
|
|
- this.ontakebtn = true
|
|
|
- if( this.onIdentify ){
|
|
|
+ // 认证窗口关闭
|
|
|
+ if( !this.identifyFaceDialog ){
|
|
|
return;
|
|
|
}
|
|
|
+ // 取不到base64
|
|
|
if( !this.imgbase64 ){
|
|
|
- this.handler_msg(false, identify, "人脸不在视频上" );
|
|
|
+ this.handler_msg(false, "人脸定位中...." );
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 用户在认证中
|
|
|
+ if( this.onIdentify ){
|
|
|
return;
|
|
|
}
|
|
|
this.onIdentify = true;
|
|
@@ -265,7 +232,7 @@
|
|
|
pause
|
|
|
} = res.data
|
|
|
this.onIdentify = false;
|
|
|
- this.handler_msg(pause, identify, msg )
|
|
|
+ this.handler_msg(pause, msg )
|
|
|
})
|
|
|
},
|
|
|
destroyTimer() {
|
|
@@ -316,7 +283,6 @@
|
|
|
onPlayerTimeupdate(player) {
|
|
|
let curTimes = player.cache_.currentTime;
|
|
|
if (curTimes > 30 && curTimes > this.curTimes + 2) {
|
|
|
- console.log("return", curTimes, this.media.position)
|
|
|
player.currentTime(this.curTimes);
|
|
|
return;
|
|
|
}
|
|
@@ -326,8 +292,7 @@
|
|
|
if (position > this.media.duration) position = this.media.duration;
|
|
|
let player = this.$refs.videoPlayer.player;
|
|
|
let res = player.currentTime(position);
|
|
|
- console.log("setposition", position)
|
|
|
- // player.play()
|
|
|
+ // player.load();
|
|
|
this.curTimes = position;
|
|
|
if (this.media.isFinish) return;
|
|
|
if (this.media.position >= this.media.duration - 2*this.heartbeat && !this.media.isFinish) {
|
|
@@ -346,26 +311,29 @@
|
|
|
this.reportErr("play", 'close')
|
|
|
this.doPause()
|
|
|
this.$emit("close")
|
|
|
- // this.closeCamera( "video")
|
|
|
},
|
|
|
doPause() {
|
|
|
this.onPlay = false
|
|
|
- let myPlayer = this.$refs.videoPlayer.player;
|
|
|
- myPlayer && myPlayer.pause()
|
|
|
+ setTimeout( ()=>{
|
|
|
+ let myPlayer = this.$refs.videoPlayer.player;
|
|
|
+ myPlayer && myPlayer.pause()
|
|
|
+ }, 20);
|
|
|
+ // console.log( myPlayer )
|
|
|
+ // myPlayer&& myPlayer.controlBar.hide()
|
|
|
},
|
|
|
doPlay() {
|
|
|
this.onPlay = true
|
|
|
this.startTick();
|
|
|
if (!this.$refs.videoPlayer || !this.$refs.videoPlayer.player) return;
|
|
|
- // if (!this.dialog) return this.doPause();
|
|
|
let myPlayer = this.$refs.videoPlayer.player;
|
|
|
myPlayer && myPlayer.play()
|
|
|
this.tickNum = 0
|
|
|
},
|
|
|
onPlayerStart( player ) {
|
|
|
- console.log("onPlayerStart")
|
|
|
this.onPlay = true
|
|
|
- if( !this.identifyFacePass){
|
|
|
+ this.startPlay = true;
|
|
|
+ let now = Date.now()
|
|
|
+ if( now > this.nextFaceTime ){
|
|
|
this.startIdentify()
|
|
|
return
|
|
|
}
|
|
@@ -373,19 +341,32 @@
|
|
|
this.startTick();
|
|
|
},
|
|
|
startIdentify(){
|
|
|
+ // 清空上一次遗留
|
|
|
+ this.imgbase64 = '';
|
|
|
+ let isDebug = false
|
|
|
if( !this.closeFace){
|
|
|
- this.identifyFace = true
|
|
|
- this.identifyFacePass = false
|
|
|
this.identifyFaceDialog = true
|
|
|
this.updateTime = Date.now()
|
|
|
+ // 人脸采集间隔时间
|
|
|
+ this.faceInterval = this.heartbeat * this.collectBeat*1000;
|
|
|
+ // 关闭时间
|
|
|
+ this.closeDailogTime = this.updateTime + this.identifyDuration;
|
|
|
+ //
|
|
|
+ if( isDebug){
|
|
|
+ this.faceInterval = 30*1000;
|
|
|
+ this.closeDailogTime = this.updateTime + 30*1000;
|
|
|
+ }
|
|
|
}
|
|
|
this.startTick()
|
|
|
},
|
|
|
-
|
|
|
identifyPassAndPlay(){
|
|
|
- this.identifyFacePass = true
|
|
|
+ // 认证通过 关闭dialog
|
|
|
this.identifyFaceDialog = false
|
|
|
+ // 下一次人脸采集时间
|
|
|
+ this.nextFaceTime = Date.now() + this.faceInterval
|
|
|
+ // 通过 开始播放
|
|
|
this.$message.successMsg("人脸认证通过", 2)
|
|
|
+ this.errMsg = ''
|
|
|
this.doPlay()
|
|
|
},
|
|
|
reportErr(action, msg) {
|
|
@@ -407,56 +388,57 @@
|
|
|
}
|
|
|
});
|
|
|
},
|
|
|
+
|
|
|
tick(force = false) {
|
|
|
let media = this.media;
|
|
|
this.tickNum++
|
|
|
- // 人脸认证期间
|
|
|
- if( !this.closeFace && !this.identifyFacePass ) {
|
|
|
- if( this.onPlay ){
|
|
|
- this.doPause()
|
|
|
- }
|
|
|
- // 人脸认证
|
|
|
- // if (this.tickNum % 3 == 1) {
|
|
|
- // this.photograph( "video2" );
|
|
|
- // }
|
|
|
- return;
|
|
|
- };
|
|
|
+ let now = Date.now()
|
|
|
+ // 人脸认证期间 关闭播放
|
|
|
+ if( !this.closeFace ){
|
|
|
+ //
|
|
|
+ if( this.identifyFaceDialog ) {
|
|
|
+ // 在播放中,关闭播放
|
|
|
+ if( this.onPlay ){
|
|
|
+ this.doPause()
|
|
|
+ }
|
|
|
+ // 主动关闭人脸认证
|
|
|
+ if( now > this.closeDailogTime ){
|
|
|
+ this.$message.errorMsg("人脸检测失败,暂停播放", 5);
|
|
|
+ this.errMsg = "人脸检测失败,暂停播放";
|
|
|
+ // 关闭定时器
|
|
|
+ this.startPlay = false;
|
|
|
+ // 认真失败,下一次播发需要人脸
|
|
|
+ this.nextFaceTime = now
|
|
|
+ this.stopTick();
|
|
|
+ this.identifyFaceDialog = false;
|
|
|
+ }else{
|
|
|
+ // 人脸认证
|
|
|
+ this.photograph("video")
|
|
|
+ }
|
|
|
+ return;
|
|
|
+ }else{
|
|
|
+ console.log("next",(now - this.nextFaceTime)/1000 )
|
|
|
+ if( this.startPlay && now > this.nextFaceTime ){
|
|
|
+ this.startIdentify();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
// 未开始
|
|
|
if(!force && !this.onPlay ){
|
|
|
return;
|
|
|
}
|
|
|
-
|
|
|
// 已经完成
|
|
|
if (this.media.isFinish) {
|
|
|
console.log("finish")
|
|
|
return;
|
|
|
}
|
|
|
+
|
|
|
// 每5秒一次心跳
|
|
|
if (this.tickNum % this.heartbeat != 0) {
|
|
|
return;
|
|
|
}
|
|
|
- // if (!this.media.isFinish && this.onPlay && !this.closeFace) {
|
|
|
- // console.log(this.identifyFacePass , this.media.isFinish , this.onPlay, this.closeFace)
|
|
|
- // this.$message.errorMsg("需要安装摄像头才能学习", 2);
|
|
|
- // this.doPause()
|
|
|
- // return;
|
|
|
- // }
|
|
|
- if (this.errCount >= this.maxErrorCount) {
|
|
|
- this.$message.errorMsg("人脸不在摄像头上", 5);
|
|
|
- this.destroyTimer()
|
|
|
- this.$emit("close");
|
|
|
- return;
|
|
|
- }
|
|
|
|
|
|
- let heartBeat = parseInt(this.tickNum / this.heartbeat);
|
|
|
- // 异常 10秒检查
|
|
|
- if (!this.closeFace) {
|
|
|
- if (this.errCount > 0) {
|
|
|
- this.photograph("video")
|
|
|
- } else if (heartBeat % this.collectBeat == 1) {
|
|
|
- this.photograph("video")
|
|
|
- }
|
|
|
- }
|
|
|
// 主动暂停
|
|
|
let myPlayer = this.$refs.videoPlayer.player;
|
|
|
let curTimes = parseInt(myPlayer.currentTime());
|
|
@@ -489,6 +471,9 @@
|
|
|
} = res.data
|
|
|
if (pause || closed) {
|
|
|
this.doPause();
|
|
|
+ // 服务器关闭播放
|
|
|
+ this.startPlay = false;
|
|
|
+ this.stopTick()
|
|
|
this.$emit("close")
|
|
|
if (closed) {
|
|
|
this.$message.errorMsg("课程关闭学习", 5);
|