<template>
  <view class="video-box" v-loading="loading">
    <video
      v-if="videoUrl"
      class="video-box-body"
      id="myVideo"
      @timeupdate="timeUpdate"
      :src="videoUrl"
      controls
      :initial-time="initial_time"
      object-fit="fill"
      play-btn-position="center"
      @ended="ended"
      @tap="videoClick"
      @loadedmetadata="loadedmetadata"
    >
      <cover-view class="video-control">
        <cover-view class="multi rate" @tap.stop="showSwitchRate">x {{ currentRate }}</cover-view>
      </cover-view>
      <cover-view class="multi-list rate" :class="{ active: rateShow }">
        <cover-view
          v-for="(item, index) in rateList"
          :key="index"
          class="multi-item rate"
          :data-rate="item"
          @tap="switchRate"
          :class="{ active: item == currentRate }"
        >
          {{ item }}
        </cover-view>
      </cover-view>
    </video>
    <view class="video-box-body" v-else>
      <u-empty text="视频地址为空" mode="page"></u-empty>
    </view>
  </view>
</template>

<script>
export default {
  name: 'VideoBox',
  props: {
    rateList: {
      type: Array,
      default: () => ['0.5', '1.0', '1.5', '2.0']
    },
    videoUrl: {
      type: String,
      default: ''
    }
  },
  data() {
    return {
      // 加载层
      loading: false,
      // 视频创建dom
      videoContext: uni.createVideoContext('myVideo', this),
      // 视频实时时间
      initial_time: 0,
      // 视频已经播放时间
      playedTime: 0,
      // 倍速浮层
      rateShow: false,
      // 默认倍速
      currentRate: 1.0,
      // 视频实际时间
      video_real_time: 0,
      // 视频总时长
      duration: 0,
      // 当前视频选中播放
      currentDuration: 0,
      // 视频信息
      videoInfo: {},
      // 选中课程下标
      videoIndex: 0
    };
  },
  methods: {
    /**
     * 加载视频
     * @date 2022-10-19
     * @returns {any}
     */
    loadVideo(data) {
      this.loading = true;
      this.videoInfo = data;
      this.initial_time = Number(data.currentDuration);
      this.video_real_time = Number(data.playDuration);
      this.playedTime = Number(data.playDuration);
    },
    /**
     * 记录时间
     * @date 2022-10-19
     * @param { Number } index
     * @returns {any}
     */
    recordDuration(index, refresh) {
      this.videoIndex = index;
      let playDuration = this.video_real_time;
      if (this.videoInfo.playDuration > this.video_real_time) {
        this.currentDuration = this.video_real_time;
        playDuration = this.videoInfo.playDuration;
      } else {
        this.currentDuration = this.video_real_time;
      }
      this.$emit('recordDuration', { playDuration, duration: this.duration, currentDuration: this.currentDuration }, index, refresh);
    },
    /**
     * 获取视频总时长
     * @param {Object} data
     */
    loadedmetadata(data) {
      this.duration = data.detail.duration;
      this.loading = false;
    },
    /**
     * 显示倍速浮层
     * @date 2022-10-19
     * @returns {any}
     */
    showSwitchRate() {
      this.rateShow = true;
    },
    /**
     * 切换倍速
     * @param {Object} e
     */
    switchRate(e) {
      let rate = Number(e.currentTarget.dataset.rate);
      this.currentRate = rate;
      this.rateShow = false;
      this.videoContext.playbackRate(rate);
    },
    /**
     * 视频点击
     * @param {Object} e
     */
    videoClick(e) {
      this.rateShow = false;
    },
    /**
     * 视频停止
     * @date 2022-10-19
     * @param {any} e
     * @returns {any}
     */
    pause(e) {
      console.log(e);
    },
    /**
     * 控制视频不能快进
     * @param {Object} e
     */
    timeUpdate(e) {
      //播放的总时长
      let duration = e.detail.duration;
      //实时播放进度 秒数
      let jumpTime = parseInt(e.detail.currentTime);
      //当前视频进度
      if (jumpTime - this.playedTime > 3) {
        // 差别过大，调用seek方法跳转到实际观看时间
        this.videoContext.seek(this.playedTime);
        wx.showToast({
          title: '未完整看完该视频，不能快进',
          icon: 'none',
          duration: 2000
        });
      } else {
        this.video_real_time = parseInt(e.detail.currentTime);
        this.currentDuration = e.detail.currentTime
        if (this.video_real_time > this.playedTime) {
          this.playedTime = this.video_real_time;
        }
      }
    },
    /**
     * 视频结束
     */
    ended() {
      // 用户把进度条拉到最后，但是实际观看时间不够，跳转回去会自动暂停。
      // 这里加个判断。
      if (this.playedTime < this.duration) {
        // this.videoContext.pause();
        this.$emit(
          'recordDuration',
          { playDuration: this.playedTime, duration: this.duration, currentDuration: this.currentDuration },
          this.videoIndex,
          false
        );
      }
    }
  }
};
</script>

<style lang="scss" scoped>
.video-box {
  &-body {
    width: 100%;
    height: 400rpx;
    .video-control {
      background-color: rgba(0, 0, 0, 0.1);
      height: 90rpx;
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      z-index: 997;
    }
    .video-wrap {
      position: relative;
    }
    .multi-list.full-screen.vertical {
      height: 100vh !important;
      padding: 8vh 0;
    }
    .multi-list.full-screen.horizontal {
      height: 100vw !important;
      padding: 8vw 0;
    }
    .multi {
      position: absolute;
      right: 30rpx;
      top: 50%;
      transform: translateY(-50%);
      z-index: 998;
      width: 100rpx;
      color: #fff;
      padding: 10rpx 0;
      text-align: center;
      transition: color ease 0.3s;
    }
    .multi.rate {
      right: 30rpx;
    }
    .multi-list {
      position: absolute;
      height: 100%;
      width: 0;
      background-color: rgba(0, 0, 0, 0.65);
      top: 0;
      right: 0;
      transition: width 0.3s ease;
      z-index: 999;
      box-sizing: border-box;
      padding: 20rpx 0;
    }
    .multi-list.rate {
      padding: 25rpx 0;
    }
    .multi-list.active {
      width: 200rpx;
    }
    .multi-item {
      text-align: center;
      color: #fff;
      line-height: 80rpx;
      transition: color ease 0.3s;
    }
    .multi-item.rate {
      line-height: 70rpx;
    }
    .multi-item:hover,
    .multi:hover {
      color: #00d8ff;
    }
    .multi-item.active {
      color: #00d8ff;
    }
  }
}
</style>
