y595705120 1 год назад
Родитель
Сommit
54a19040df
3 измененных файлов с 105 добавлено и 80 удалено
  1. 35 14
      src/components/face/icollect.vue
  2. 69 65
      src/containers/center/play/components/iMedia.vue
  3. 1 1
      src/settings.js

+ 35 - 14
src/components/face/icollect.vue

@@ -1,14 +1,21 @@
 <template>
   <div>
     <div class="video-box">
-      <video id="video" width="320" height="240" preload autoplay loop muted></video>
-      <canvas id="canvas" width="320" height="240"></canvas>
+      <video id="video" width="240" height="180" preload autoplay loop muted></video>
+      <canvas id="canvas" width="240" height="180"></canvas>
     </div>
-    <canvas id="screenshotCanvas" width="320" height="240"></canvas>
-    <div class="switch-button">
+    <canvas id="screenshotCanvas" width="240" height="180" @click="init"></canvas>
+   <div class="switch-button">
       <el-row>
-        <el-button type="primary" @click="destroyed">关闭摄像头</el-button>
-        <el-button type="primary" @click="init">开始识别</el-button>
+        <el-col :span="12">
+          <el-button type="text" style="color: red;" size="mini" @click="destroyed">关闭摄像头</el-button>
+        </el-col>
+
+        <el-col :span="12">
+          <el-button type="text" style="color: red;" size="mini" @click="init">开始识别</el-button>
+        </el-col>
+
+
       </el-row>
     </div>
   </div>
@@ -28,8 +35,18 @@
         uploadLock: true // 上传锁
       }
     },
+    props:['updateTime'],
     mounted() {
-      this.init();
+      setTimeout( this.init, 2000 )
+      // this.init();
+    },
+    beforeDestroy(){
+      this.destroyed()
+    },
+    watch:{
+      updateTime(){
+        this.init();
+      }
     },
     methods: {
       // 初始化设置
@@ -77,10 +94,11 @@
         let ctx = canvas.getContext('2d');
         ctx.clearRect(0, 0, canvas.width, canvas.height);
         ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
-        let base64Img = canvas.toDataURL('image/jpeg');
+        let base64Img = canvas.toDataURL('image/jpeg', 1);
 
+        this.$emit("getface", base64Img.replace("data:image/jpeg;base64,", "") )
         // 打印出 base64Img
-        console.log('base64Img', base64Img.length)
+        // console.log('base64Img', base64Img.replace("data:image/jpeg;base64,", ""))
 
         // 请求接口成功以后打开锁
         this.uploadLock = true;
@@ -105,19 +123,22 @@
 
   .video-box{
     position: relative;
-    margin-left: 30px;
-    width: 320px;
-    height: 240px;
+    margin-left: 5px;
+    width: 240px;
+    height: 180px;
   }
 
   .switch-button{
-    margin-top: 30px;
+    /* margin-top: -50px; */
+    margin: -28px auto;
     margin-left: 30px;
+    /* text-align: center; */
+    /* margin-left: 30px; */
   }
   video,canvas{
     position: absolute;
     top: 0;
     left: 0;
-	border: #000000 5px solid;
+    border: #000000 5px solid;
   }
 </style>

+ 69 - 65
src/containers/center/play/components/iMedia.vue

@@ -21,7 +21,7 @@
         </div>
 
         <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>
 
       </el-col>
@@ -91,19 +91,25 @@
       </el-col>
 
     </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>
       <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="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;">
         <video ref="video2"  width="240" height="180" autoplay></video>
         <p  style="margin-top: 20px;">当前照片:</p>
         <canvas ref="canvas" width="240" height="180"></canvas>
         <p v-if="errMsg" style="font-size: 30px;color: red;"> {{errMsg}}</p>
       </div>
-    </el-dialog>
+    </el-dialog> -->
   </div>
 </template>
 
@@ -118,6 +124,7 @@
     videoPlayer
   } from 'vue-video-player';
   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 {
@@ -140,12 +147,17 @@
         curTimes: 0,
         errMsg: '',
         errCount: 0,
+        prevCollect: 0,
+        onIdentify: false,
+        updateTime: 0,
+        imgbase64: '',
         onPlay: false
       }
     },
     components: {
       videoPlayer,
-      IMessage
+      IMessage,
+      ICollect
     },
     props: ['media', 'options', 'heartbeat', 'maxErrorCount', 'collectBeat', 'closeFace', 'chapter', 'list'],
     filters: {
@@ -186,7 +198,7 @@
     },
     beforeDestroy() {
       this.destroyTimer()
-      this.closeCamera( "video" )
+      // this.closeCamera( "video" )
     },
     created() {
       this.startTick()
@@ -201,43 +213,58 @@
         this.tickNum = 0
         this.errMsg = ''
         this.errCount = 0
+        this.prevCollect = 0;
         this.startIdentify()
         this.setposition( this.media.position )
       }
     },
     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 ) {
         let identify = (ref=="video2");
-        let ctx = this.$refs["canvas"].getContext("2d");
-        // 把当前视频帧内容渲染到canvas上
         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 = {
           id: this.media.id,
           ref,
-          image: str
+          image: this.imgbase64
         }
+        this.imgbase64 = '';
         httpServer("course.collect", param).then(res => {
           let {
             msg,
             pause
           } = 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() {
@@ -253,39 +280,6 @@
       goSubState(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() {
         let tick = this.tryTick;
         this.destroyTimer();
@@ -351,7 +345,7 @@
         this.reportErr("play", 'close')
         this.doPause()
         this.$emit("close")
-        this.closeCamera( "video")
+        // this.closeCamera( "video")
       },
       doPause() {
         this.onPlay = false
@@ -372,6 +366,7 @@
         this.onPlay = true
         if( !this.identifyFacePass){
           this.startIdentify()
+          return
         }
         this.reportErr("play", 'start');
         this.startTick();
@@ -380,16 +375,12 @@
         if( !this.closeFace){
           this.identifyFace = true
           this.identifyFacePass = false
-          this.closeCamera("video")
-          this.callCamera("video2")
+          this.updateTime = Date.now()
         }
         this.startTick()
       },
       identifyPassAndPlay(){
         this.identifyFacePass = true
-        this.identifyFace = false;
-        this.closeCamera("video2")
-        this.callCamera("video")
         this.$message.successMsg("人脸认证通过", 2)
         this.doPlay()
       },
@@ -548,6 +539,19 @@
     text-align: center;
     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 {
     width: 100%;

+ 1 - 1
src/settings.js

@@ -1,5 +1,5 @@
 module.exports = {
-  title: '宁德聚仁教育服务有限公司'
+  title: '宁德聚仁教育网络培训学院'
   ,beian:'闽ICP备2021006867号'
   ,exam:{
     username:'福建省爱数信息技术有限公司'