<template>
  <div class="faceLoginWrap">
    <div style="height: 500px;">
      <div class="video-box">
        <video id="video" width="500" height="500" preload autoplay loop muted></video>
        <canvas id="canvas" width="500" height="500"></canvas>
      </div>
      <canvas id="screenshotCanvas" width="500" height="500"></canvas>
    </div>
  </div>
</template>
<script>
  import {clockRecord} from '@/api/hrm'
  import tracking from '@/assets/tracking/build/tracking-min.js';
  import '@/assets/tracking/build/data/face-min.js';

  export default {
    data() {
      return {
        video: null,
        screenshotCanvas: null,
        uploadLock: false // 上传锁
      }
    },
    mounted() {
      this.openTheCamera();
    },
    methods: {
      openTheCamera() {
        this.$nextTick(function () {
          let _this = this;
          this.video = document.getElementById('video');
          // 旧版本浏览器可能根本不支持mediaDevices，我们首先设置一个空对象
          if (navigator.mediaDevices === undefined) {
            navigator.mediaDevices = {}
          }
          // 一些浏览器实现了部分mediaDevices，我们不能只分配一个对象
          // 使用getUserMedia，因为它会覆盖现有的属性。
          // 这里，如果缺少getUserMedia属性，就添加它。
          if (navigator.mediaDevices.getUserMedia === undefined) {
            navigator.mediaDevices.getUserMedia = function (constraints) {
              // 首先获取现存的getUserMedia(如果存在)
              let getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.getUserMedia;
              // 有些浏览器不支持，会返回错误信息
              // 保持接口一致
              if (!getUserMedia) {
                return Promise.reject(new Error('getUserMedia is not implemented in this browser'))
              }
              // 否则，使用Promise将调用包装到旧的navigator.getUserMedia
              return new Promise(function (resolve, reject) {
                getUserMedia.call(navigator, constraints, resolve, reject)
              })
            }
          }
          let constraints = {
            audio: false,
            video: {width: this.videoWidth, height: this.videoHeight, transform: 'scaleX(-1)'}
          };
          navigator.mediaDevices.getUserMedia(constraints).then(function (stream) {
            // 旧的浏览器可能没有srcObject
            if ('srcObject' in _this.video) {
              _this.video.srcObject = stream
            } else {
              // 避免在新的浏览器中使用它，因为它正在被弃用。
              _this.video.src = window.URL.createObjectURL(stream)
            }
            _this.video.onloadedmetadata = function () {
              _this.video.play();
            };
            _this.init();
          }).catch(err => {
            console.log(err)
          })
        });
      },
      // 初始化设置
      init() {
        this.screenshotCanvas = document.getElementById('screenshotCanvas');
        let canvas = document.getElementById('canvas');
        let context = canvas.getContext('2d');

        // 实例化tracker对象
        let tracker = new window.tracking.ObjectTracker('face');
        tracker.setInitialScale(4);
        tracker.setStepSize(2);
        tracker.setEdgesDensity(0.1);
        //tracker对象和标签关联
        window.tracking.track('#video', tracker, {
          camera: true
        });
        let _this = this;
        //添加事件
        tracker.on('track', function (event) {
          // 检测出人脸 绘画人脸位置
          context.clearRect(0, 0, canvas.width, canvas.height);
          // 给每个人脸绘制对应的框
          event.data.forEach(function (rect) {
            context.strokeStyle = '#0764B7';
            context.strokeRect(rect.x, rect.y, rect.width, rect.height);
            // window.plot(rect.x, rect.y, rect.width, rect.height+20);
            // 避免重复发送请求
            if (!_this.uploadLock) {
              _this.uploadLock = true;
              // 上传图片
              _this.screenshotAndUpload();
            }
          });
        });
      },
      // 上传图片
      screenshotAndUpload() {
        let that = this;
        // 绘制当前帧图片转换为base64格式
        let canvas = this.screenshotCanvas;
        let video = this.video;
        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 img = base64Img.split(',')[1];
        let imgData = {base64: img};
        clockRecord(imgData).then((res) => {
          if (res.code === 200 && res.data.id) {
            this.$message.success(res.data.name + '签到成功！');
            setTimeout(() => {
              that.uploadLock = false;
            }, 3000)
          } else {
            // 打开锁
            that.uploadLock = false;
            this.$message.error(res.msg);
          }
        }).catch(() => {
          // 打开锁
          that.uploadLock = false;
          // this.$message.error('面部识别失败请重新验证');
        });
      },
      closeCamera() {
        this.video.srcObject.getTracks()[0].stop();
      },
    }
  }
</script>
<style scoped>
  .faceLoginWrap{
    /*padding: 50px;*/
    /*width: 600px;*/
    /*height: 600px;*/
    /*background: #000000;*/
    margin:50px auto 0 auto;
    /*box-sizing: border-box;*/
  }

  #screenshotCanvas {
    display: none;
  }

  .video-box {
    width: 500px;
    height: 500px;
    margin: auto;
    position: relative;
  }

  #video {
    object-fit: fill;
    -webkit-border-radius: 250px;
    -moz-border-radius: 250px;
    border-radius: 250px;
  }

  video, canvas {
    position: absolute;
    top: 0;
    left: 0;
  }
</style>

