美文网首页
视频页面

视频页面

作者: Shiki_思清 | 来源:发表于2021-04-13 16:28 被阅读0次

    一、自定义视频操作按钮

    由于原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;
      }
    }
    

    相关文章

      网友评论

          本文标题:视频页面

          本文链接:https://www.haomeiwen.com/subject/vjkclltx.html