<template>
  <div
    class="o-video"
    :class="{ offline: !online }"
    @mouseenter.stop="mouseOver"
    @mouseleave.stop="mouseLeave"
  >
    <video
      v-if="online"
      ref="player"
      class="o-video__player o-simple-video"
      muted
      autoplay
      :poster="poster"
    />
    <div
      v-else
      class="o-video__offline"
      :style="{ zoom: zoomnum }"
    >
      当前设备离线了
    </div>
    <div
      class="o-video__tip"
      :class="{ online }"
    />
    <div class="c-footer u-ellipsis">{{ device.name }}</div>
    <div
      v-show="maskShow"
      class="o-video__mask"
    >
      <div
        class="o-video__btn u-pointer"
        :style="{ zoom: zoomnum }"
        @click="onPlay"
      >
        <i
          class="o-video__icon has-bg"
          :class="iconClass"
        />
      </div>
    </div>
  </div>
</template>

<script>
import flvjs from 'flv.js'
import { authCode } from '@/api/camera'
import videoPoster from '@/assets/video-poster.png'

const CAMERA_URL = `${location.protocol}//${process.env.VUE_APP_GATEWAY || location.host}`

export default {
  name: 'DeviceCard',
  props: {
    device: {
      type: Object,
      required: true
    },
    zoomnum: {
      type: String,
      default: null
    }
  },
  data () {
    return {
      poster: videoPoster,
      maskShow: false,
      refreshShow: false,
      first: false
    }
  },
  computed: {
    iconClass () {
      if (this.refreshShow) {
        return 'refresh'
      }
      return this.device.paused ? 'paused' : 'playing'
    },
    online () {
      return this.device.onlineStatus === 1
    }
  },
  created () {
    if (this.online) {
      this.$timer = -1
      this.getAuthCode()
    }
  },
  beforeDestroy () {
    if (this.$player) {
      clearTimeout(this.$timer)
      this.destroyPlay()
    }
  },
  methods: {
    mouseOver () {
      if (this.online) {
        this.maskShow = true
      }
      if (this.$player && !this.$refs.player.paused) {
        this.device.paused = false
      } else {
        this.device.paused = true
      }
    },
    mouseLeave () {
      this.maskShow = false
    },
    onPlay () {
      this.first = true
      if (this.$refs.player.paused) {
        this.maskShow = false
      }
      this.refreshShow = false
      if (this.$player && !this.$refs.player.paused) {
        this.device.paused = true
        this.$player.pause()
      } else {
        if (this.$player) {
          this.destroyPlay()
        }
        this.device.paused = false
        this.getAuthCode()
      }
    },
    getAuthCode () {
      authCode({ deviceId: this.device.id }).then(({ data }) => {
        this.createPlayer(data)
      })
    },
    createPlayer ({ timestamp, token, expire }) {
      if (flvjs.isSupported()) {
        // 创建一个flvjs实例
        const url = `${CAMERA_URL}/live/${this.device.id}.flv?authorization=${token}&timestamp=${timestamp}&expire=${expire}`
        this.$player = flvjs.createPlayer({
          type: 'flv',
          isLive: true,
          hasAudio: false,
          url
        })
        this.$player.on('error', () => {
          this.refreshShow = true
          this.destroyPlay()
          this.$message({
            type: 'warning',
            message: '设备视频流出错'
          })
        })
        let decodedFrames = -1
        this.$player.on('statistics_info', res => {
          decodedFrames = res.decodedFrames
        })
        this.$timer = setTimeout(() => {
          if (decodedFrames === 0) {
            this.destroyPlay()
            this.$message({
              type: 'warning',
              message: `${this.device.name}设备没有视频流`
            })
            this.refreshShow = true
          }
        }, 10000)
        // 将实例挂载到video元素上面
        this.$player.attachMediaElement(this.$refs.player)

        try {
          // 开始运行加载 只要流地址正常 就可以在h5页面中播放出画面了
          this.$player.load()
          this.$player.play()
          if (!this.first) {
            this.$player.pause()
          }
        } catch (error) {
          console.log('连接websocker异常', error)
        }
      }
    },
    destroyPlay () {
      this.$player.pause()
      this.$player.unload()
      this.$player.detachMediaElement()
      this.$player.destroy()
      this.$player = null
    }
  }
}
</script>

<style lang="scss" scoped>
.o-video {
  position: relative;
  padding-top: 56.25%;
  border-radius: $radius--mini;
  overflow: hidden;

  &.offline {
    background: url("~@/assets/image_offline.svg") 0 0 / 100% 100% no-repeat;
  }

  &__player {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
  }

  &__offline {
    position: absolute;
    top: 73%;
    left: 50%;
    color: $info;
    font-size: 24px;
    transform: translateX(-50%);
  }

  &__tip {
    position: absolute;
    top: 0;
    right: 0;
    width: 48px;
    height: 24px;
    color: #fff;
    font-size: 14px;
    line-height: 24px;
    text-align: center;
    border-radius: 0 0 0 $radius--mini;
    background-color: $error--dark;
    z-index: 9;

    &::after {
      content: "离线";
    }

    &.online {
      background-color: $success--dark;

      &::after {
        content: "在线";
      }
    }
  }

  &__mask {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.3);
    z-index: 2;
  }

  &__btn {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 128px;
    padding-top: 128px;
    border-radius: 50%;
    background-color: rgba(#f4f7fb, 0.5);
    transform: translate(-50%, -50%);
  }

  &__icon {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);

    &.playing {
      border-top: 22px solid transparent;
      border-left: 37px solid #fff;
      border-bottom: 22px solid transparent;
      transform: translate(-15px, -50%);
    }

    &.paused {
      width: 40%;
      height: 60%;
      border-left: 10px solid #fff;
      border-right: 10px solid #fff;
    }

    &.refresh {
      width: 60%;
      height: 60%;
      background-image: url("~@/assets/icon_refresh.png");
    }
  }
}
</style>
