视频页面

2021-04-13  本文已影响0人  Shiki_思清

一、自定义视频操作按钮

由于原video组件不方便操作,所以果断放弃
使用自定义页面组件配合js操作video,同时使用 requestFullscreen和exitFullscreen配合放大缩小。

1. 重写最大化 最大化父节点

<div class="video-player" id="myvideo">
  <video></video>
  <div>
    // 播放/暂停
    // 进度条
    // 最大化最小化
  </div>
</div>

const myvideo = document.getElementById("myvideo");
    // 判断是否最大化
    if (isFullScreen) {
      if (document.exitFullscreen) {
          document.exitFullscreen();
        } else if (document.msExitFullscreen) {
          document.msExitFullscreen();
        } else if (document.mozCancelFullScreen) {
          document.mozCancelFullScreen();
        } else if (document.webkitCancelFullScreen) {
          document.webkitCancelFullScreen();
        }
      } else {
        if (myvideo.requestFullscreen) {
          myvideo.requestFullscreen();
        } else if (myvideo.mozRequestFullScreen) {
          myvideo.mozRequestFullScreen();
        } else if (myvideo.webkitRequestFullscreen) {
          myvideo.webkitRequestFullscreen();
        } else if (myvideo.msRequestFullscreen) {
          myvideo.msRequestFullscreen();
        }
      }
    }

2. 重写播放和滚动条

<div class="video-player-container">
  <video
    ref="videoPlayer"
    class="video-player"
    width="100%"
    :src="videoObj.video_info && videoObj.video_info.play_url_fd"
    @pause="() => handPlay('pause')"
    @play="() => handPlay('play')"
    @loadedmetadata="getAudioLength"
    @timeupdate="videoTimeUpdate"
    @click="playVideo"
  />

  <div class="video_control">
    <div class="controler">
      <img
        @click="playVideo"
        class="play-btn"
        :src="
          `https://sc2.hexiaoxiang.com/write-artifact/hx_dxb_website/video-player/${
            initVideo.play ? 'pause1.png' : 'play1.png'
          }`
        "
        alt=""
      />
      <div class="time">
        <!-- //videoLength 总时间,currentTime 当前时间,videoTime 自定义过滤器 -->
        <span>{{ getFormatVideoTime(initVideo.currentTime) }}</span>
        /
        <span>{{ getFormatVideoTime(initVideo.videoLength) }}</span>
      </div>
      <img
        @click="setWidth"
        class="screen-btn"
        :src="
          `https://sc2.hexiaoxiang.com/write-artifact/hx_dxb_website/video-player/${
            isFullScreen ? 'exitFullScreen.png' : 'fullScreen.png'
          }`
        "
        alt=""
      />
    </div>
    <!-- //进度条 -->
    <a-slider
      class="commonSlider"
      :tooltip-visible="false"
      v-model="initVideo.currentTime"
      :max="initVideo.videoLength"
      @change="changeVideoTime"
    >
    </a-slider>
  </div>
  <div class="auto-play">
    <a-switch @change="handleAutoplay" v-model="isAutoPlay" />
    <a-tooltip
      placement="bottomRight"
      :arrowPointAtCenter="true"
      overlayClassName="overrideClass"
    >
      <template slot="title">
        <span>开启后自动播放下一个视频,播放完本课自动播放下一课</span>
      </template>
      <div>{{ isAutoPlay ? "关闭自动播放" : "打开自动播放" }}</div>
    </a-tooltip>
  </div>
</div>
data() {
  return {
    player: {},
    isAutoPlay: false,
    initVideo: {
      play: false, //播放还是暂停 true播放中
      videoLength: 0, //时长
      url: "", //视频课件Url
      currentTime: 0, //当前播放时间
      lastTime: null, //标记时间戳
      name: ""
    },
    isFullScreen: false
  };
},
watch: {
  videoObj() {
    this.handPlay("pause");
    this.initVideo = {
      play: false, //播放还是暂停 true播放中
      videoLength: 0, //时长
      url: "", //视频课件Url
      currentTime: 0, //当前播放时间
      lastTime: null, //标记时间戳
      name: ""
    };
  },
  isAutoPlay(newV, oldV) {
    if (newV != oldV) {
      this.$emit("is-auto-play", newV);
    }
  }
},
mounted() {
  this.$nextTick(function() {
    this.player = this.$refs.videoPlayer;
    this.player.onended = this.onended;
    this.player.onerror = this.onerror;
  });
},
methods: {
  setWidth() {
    this.$emit("set-width", this.isFullScreen);
    setTimeout(() => {
      this.isFullScreen = !this.isFullScreen;
    }, 100);
  },
  playVideo() {
    //播放视频
    if (this.initVideo.play) {
      this.player.pause();
    } else {
      Math.abs(this.initVideo.currentTime - this.player.currentTime) > 2
        ? (this.player.currentTime = this.initVideo.currentTime)
        : "";
      this.player.play();
      this.player.muted = false;
    }
  },
  videoTimeUpdate() {
    //更新视频时间。节流,每秒触发一次
    let nowTime = Date.now();
    let gapTime = 1000;
    if (
      !this.initVideo.lastTime ||
      nowTime - this.initVideo.lastTime > gapTime
    ) {
      if (this.player) {
        let time = this.player.currentTime;
        this.initVideo.currentTime = time;
      }
      this.initVideo.lastTime = nowTime;
    }
  },
  changeVideoTime(val) {
    //改变视频时间
    if (this.player) {
      this.player.currentTime = val;
    }
  },
  getAudioLength() {
    //获取音视频时长
    this.initVideo.videoLength = this.player.duration;
  },
  handPlay(type) {
    this.initVideo.play = type == "play";
  },
  //格式化时间
  getFormatVideoTime(time) {
    let curtime = time;
    let h = parseInt(curtime / 3600);
    let m = parseInt((curtime % 3600) / 60);
    let s = parseInt(curtime % 60);

    h = h < 10 ? "0" + h : h;
    m = m < 10 ? "0" + m : m;
    s = s < 10 ? "0" + s : s;

    if (h == "00") {
      return m + ":" + s;
    }

    return h + ":" + m + ":" + s;
  },
  // 播放错误
  onerror() {
    console.log("error");
    this.$message.error("视频资源无法播放~");
  },
  onended() {
    this.$emit("file-ended");
    // this.handPlay("pause");
    // this.player.load();
    // this.playVideo();
  },
  handleAutoplay() {
    this.player.autoplay = !this.player.autoplay;
    // this.player.load();
  }
}

3. 动态调整视频大小

<template>
  <div class="carousel"><video></video></div>
</template>
<style lang="scss" scoped>
.carousel {
  @media screen and (max-width: 1239px) {
    max-width: 824px;
  }
  @media screen and (min-width: 1240px) and (max-width: 1329px) {
    max-width: 854px;
  }
  @media screen and (min-width: 1330px) and (max-width: 1592px) {
    max-width: 924px;
  }
  @media screen and (min-width: 1593px) and (max-width: 1789px) {
    max-width: 1046px;
  }
  @media screen and (min-width: 1790px) {
    max-width: 1128px;
  }
}
</style>
image.png

二、拖拽滚动

image.png

1.通过点击滚动
2.鼠标滚球滚动
3.鼠标点击拖动

<div class="carousel">
  <div class="carousel-left">
    <div @click="carouselLeftEnd ? null : offset('left')">
      <img
        :src="
          `https://sc2.hexiaoxiang.com/write-artifact/hx_dxb_website/video-player/${
            carouselLeftEnd ? 'arrow-left.png' : 'arrow-left-active.png'
          }`
        "
        alt=""
      />
    </div>
  </div>
  <div class="carousel-content" ref="ref" draggable="true">
    <div
      v-for="(item, index) in fontList"
      :key="index"
      @click="() => $emit('change', { ...item, index })"
    >
      <RectFont
        :fontText="item.module_title"
        :active="currentIndex == index"
      />
    </div>
  </div>
  <div class="carousel-right">
    <div @click="carouselRightEnd ? null : offset('right')">
      <img
        :src="
          `https://sc2.hexiaoxiang.com/write-artifact/hx_dxb_website/video-player/${
            carouselRightEnd ? 'arrow-right.png' : 'arrow-right-active.png'
          }`
        "
        alt=""
      />
    </div>
  </div>
</div>
props: {
  fontList: {
    type: Array,
    default: () => []
  },
  currentIndex: {
    type: Number,
    default: 0
  }
},
data() {
  return {
    currentPosition: 0,
    carouselLeftEnd: true,
    carouselRightEnd: false
  };
},
watch: {
  fontList: {
    handler: function(newValue, oldValue) {
      if (!newValue) {
        return;
      }
      if (JSON.stringify(newValue) != JSON.stringify(oldValue)) {
        this.$refs.ref && this.$refs.ref.scrollTo(0, 0);
      }
    },
    immediate: true
  }
},
mounted() {
  if (this.$refs.ref) {
    const el = this.$refs.ref;
    const that = this;
    // 2.鼠标滚球滚动
    el.onscroll = function() {
      that.currentPosition = el.scrollLeft;
      that.changeBtnStatus(el.scrollWidth - el.offsetWidth);
    };
    // 3.鼠标点击拖动
    el.onmousedown = function(ev) {
      const disX = ev.clientX;
      const originalScrollLeft = el.scrollLeft;
      const originalScrollBehavior = el.style.scrollBehavior;
      const originalPointerEvents = el.style.pointerEvents;
      el.style.scrollBehavior = "auto";
      document.onmousemove = function(ev) {
        ev.preventDefault();
        const distanceX = ev.clientX - disX;
        el.scrollTo(originalScrollLeft - distanceX, 0);
        el.style.pointerEvents = "none";
        that.currentPosition = el.scrollLeft;
        that.changeBtnStatus(el.scrollWidth - el.offsetWidth);
      };
      document.onmouseup = function() {
        document.onmousemove = null;
        document.onmouseup = null;
        el.style.scrollBehavior = originalScrollBehavior;
        el.style.pointerEvents = originalPointerEvents;
      };
    };
  }
},
methods: {
  getScrollPosition(el = window) {
    const x = el.pageXOffset !== undefined ? el.pageXOffset : el.scrollLeft;
    const y = el.pageYOffset !== undefined ? el.pageYOffset : el.scrollTop;
    return { x, y };
  },
  // 1.通过点击滚动
  offset(direction) {
    const typemap = {
      left: -360,
      right: 360
    };
    const currentScrollWidth =
      this.$refs.ref.scrollWidth - this.$refs.ref.offsetWidth;
    this.currentPosition =
      this.currentPosition + typemap[direction] >= 0
        ? this.currentPosition + typemap[direction] >= currentScrollWidth
          ? currentScrollWidth
          : this.currentPosition + typemap[direction]
        : 0;
    this.$refs.ref.scrollTo(this.currentPosition, 0);
    this.changeBtnStatus(currentScrollWidth);
  },
  changeBtnStatus(currentScrollWidth) {
    const cuurenScrollPos = this.getScrollPosition(this.$refs.ref);
    this.carouselLeftEnd = cuurenScrollPos.x == 0;
    this.carouselRightEnd = cuurenScrollPos.x == currentScrollWidth;
  }
}
上一篇下一篇

猜你喜欢

热点阅读