video-play

236 阅读1分钟
<template>
  <view v-if="videoShow" class="video-contain">
    <u-popup
      v-model="value"
      mode="center"
      :mask="true"
      width="100%"
      height="100%"
      class="popups"
    >
      <view class="body-video">
        <view
          :class="{ 'video-js': isFullscreen, 'video-small': !isFullscreen }"
          ref="video"
        >
        </view>
        <!-- 重新播放 -->
        <!-- <button
          class="vjs-play-control vjs-control vjs-button vjs-paused vjs-ended auto-speed"
          type="button"
          aria-live="polite"
          title="Replay"
          v-if="isEnd"
          @click="replay"
          aria-disabled="false"
        >
          
        </button> -->
        <view class="pause" v-if="isEnd" @click="replay">
          <image
            src="/static/base-module/common/replay.png"
            class="pause-icon"
            mode=""
          />
        </view>
        <!-- 全屏 -->
        <view class="video-mask" @click="showBtn"></view>
        <!-- 关闭视频 -->
        <view class="close-video" @click="close">
          <image
            src="/static/base-module/common/close-video.png"
            class="close-icon"
          />
        </view>
        <view class="pause" v-if="isPlay && isShowBtn" @click="pause">
          <image
            src="/static/base-module/common/pause.png"
            class="pause-icon"
          />
        </view>
        <view class="pause" v-if="!isPlay && isShowBtn" @click="play">
          <image src="/static/base-module/common/play.png" class="pause-icon" />
        </view>
        <!-- 音量 -->
        <view class="volume-control">
          <view class="volume" v-if="muted">
            <u-slider
              v-model="slideVolume"
              :use-slot="true"
              @slideClick="slideClick"
              class="video-slider"
              inactive-color="#6E6E6E"
              active-color="#FFFFFF"
              height="2.2"
              @end="volumeStart"
            >
              <template>
                <!-- vue实例外创建 -->
                <view class="volume-cicle"> </view>
              </template>
            </u-slider>
          </view>
          <view class="icon">
            <image
              src="/static/base-module/common/volum.png"
              class="volum"
              v-if="muted"
              @click="volum"
            />
            <image
              src="/static/base-module/common/close-volum.png"
              class="volum"
              v-if="!muted"
              @click="volum"
            />
          </view>
        </view>
        <!-- 底部控制 -->
        <view class="bottom">
          <view class="time">
            <view class="currentTime">{{ currentTime }}</view>
            <view class="spet">/</view>
            <view class="duration">{{ duration }}</view>
          </view>
          <!-- 时间进度 -->
          <!-- <view id="progressWrap">
            <view id="playProgress" :style="{ width: playWidth }"> </view>
            <view class="cicle"> </view>
          </view> -->
          <view class="progressWrap">
            <u-slider
              v-model="slide"
              class="video-slider"
              :use-slot="true"
              inactive-color="#6E6E6E"
              active-color="#FFFFFF"
              height="2.2"
              @slideClick="slideVideo"
              @end="sliderStart"
            >
              <template>
                <!-- vue实例外创建 -->
                <view class="cicle"> </view>
              </template>
            </u-slider>
          </view>
          <!-- 全屏 -->
          <view class="full">
            <image
              src="/static/base-module/common/scale1.png"
              v-if="!isFullscreen"
              class="scale"
              @click="fullscreen"
            />
            <image
              src="/static/base-module/common/scale.png"
              v-if="isFullscreen"
              class="scale"
              @click="fullscreen"
            />
          </view>
        </view>
      </view>
    </u-popup>
  </view>
</template>
<script>
export default {
  props: {
    videoShow: {
      type: Boolean,
      default: false,
    },
    source: {
      type: String,
      default: "",
    },
    poster: {
      type: String,
      default: "",
    },
    type: {
      type: String,
      default: "video/mp4",
    },
    title: {
      type: String,
      default: "",
    },
  },
  data() {
    return {
      player: null,
      value: false,
      isEnd: false,
      isFullscreen: false,
      isPlay: false,
      isShowBtn: false,
      duration: 0,
      currentTime: 0,
      muted: false,
      playWidth: 0,
      volume: 100,
      slide: 0,
      slideVolume: 100,
    };
  },
  mounted() {},
  watch: {
    // 如果是异步关闭时,外部修改v-model的值为false时,重置内部的loading状态
    // 避免下次打开的时候,状态混乱
    videoShow(n) {
      this.value = n;
      console.log(n);
    },
    value(n) {
      if (!n) {
        this.$emit("close");
        this.destroyVideo();
      }
    },
  },
  methods: {
    // 全屏的方法
    fullscreen() {
      this.isFullscreen = !this.isFullscreen;
    },
    showBtn() {
      this.isShowBtn = true;
      setTimeout(() => {
        if (this.isPlay) {
          this.isShowBtn = false;
        }
      }, 3000);
    },
    volum() {
      var video = document.getElementById("video").children[0];
      this.muted = !this.muted;
      if (this.muted) {
        video.volume = 1;
        this.slideVolume = 100
      } else {
        video.volume = 0;
        this.slideVolume = 0
      }
    },
    volumeStart() {
       var video = document.getElementById("video").children[0];
       var num = this.slideVolume/100;
           video.volume = num;
           if(video.volume===0){
             this.muted = false
           }
    },
    getInit() {
      var progressFlag;
      let video = document.createElement("video");
      video.id = "video";
      video.style =
        "width: 100%; height: 100%;background: #000000;padding-top:0";
      video.controls = true;
      video.setAttribute("class", "vjs-big-play-centered"); //IOS微信浏览器支持小窗内播放
      video.setAttribute("playsinline", true); //IOS微信浏览器支持小窗内播放
      video.setAttribute("webkit-playsinline", true); //这个bai属性是ios 10中设置可以让视频在小du窗内播放,也就是不是全zhi屏播放的video标签的一个属性
      video.setAttribute("x5-video-player-type", "h5"); //安卓 声明启用同层H5播放器 可以在video上面加东西
      let source = document.createElement("source");
      source.src = this.source;
      source.type = this.type;
      video.appendChild(source);
      this.$refs.video.$el.appendChild(video);
      let that = this;
      that.player = videojs(
        "video",
        {
          poster: that.poster, // 视频封面图地址
          title: that.title,
          autoDisable: true,
          preload: "none", //auto - 当页面加载后载入整个视频 meta - 当页面加载后只载入元数据 none - 当页面加载后不载入视频
          language: "zh-CN",
          fluid: true, // 自适应宽高
          muted: true, //  是否静音
          aspectRatio: "16:9", // 将播放器置于流畅模式,并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字(例如"16:9"或"4:3")
          controls: false, //是否拥有控制条 【默认true】,如果设为false ,那么只能通过api进行控制了。也就是说界面上不会出现任何控制按钮
          autoplay: true, //如果true,浏览器准备好时开始回放。 autoplay: "muted", // //自动播放属性,muted:静音播放
          loop: false, // 导致视频一结束就重新开始。 视频播放结束后,是否循环播放
          // techOrder: ["html5", "flash"], //播放顺序
          screenshot: true,
          controlBar: false,
          currentTime: 0,
          duration: 0,
        },
        function () {
          this.on("error", function () {
            //请求数据时遇到错误
            that.$emit("error");
          });
          this.on("stalled", function () {
            //网速失速
            console.log("网速失速");
            that.$emit("stalled");
          });
          this.on("play", function () {
            //开始播放
            that.isPlay = true;
            that.isEnd = false;
            that.$emit("play");
          });
          this.on("pause", function () {
            //暂停
            console.log("暂停");
            that.isPlay = false;
            that.$emit("pause");
          });
          this.on("timeupdate", function () {
            that.duration = that.formateSeconds(this.duration());
            that.currentTime = that.formateSeconds(this.currentTime());
            var percent = (this.currentTime() / this.duration()) * 100;
            that.slide = percent;
            that.$emit("timeupdate");
          });
          this.on("ended", function () {
            that.isEnd = true;
            that.isPlay = false;
            that.isFullscreen = false; //播放我退出全屏
            that.$emit("ended");
          });
        }
      );
    },
    sliderStart() {
      var time = this.slide / 100;
      var video = document.getElementById("video").children[0];
      var total = video.duration;
      video.currentTime = time * total;
    },
    slideVideo(){
      var time = this.slide / 100;
      var video = document.getElementById("video").children[0];
      var total = video.duration;
      video.currentTime = time * total;
    },
    slideClick(){
       var video = document.getElementById("video").children[0];
       var num = this.slideVolume/100;
           video.volume = num;
           if(video.volume===0){
             this.muted = false
           }
    },
    destroyVideo() {
      if (this.player != null) {
        this.player.dispose();
        this.player = null;
      }
    },
    close() {
      if (this.player != null) {
        this.player.dispose();
        this.player = null;
      }
      this.$emit("close");
    },
    replay() {
      this.play();
    },
    play() {
      let that = this;
      this.player.ready(function () {
        that.player.play();
        if (that.isShowBtn) {
          setTimeout(() => {
            that.isShowBtn = false;
          }, 3000);
        }
      });
    },
    pause() {
      let that = this;
      this.player.ready(function () {
        that.player.pause();
      });
    },
    //将秒转化为时分秒
    formateSeconds(endTime) {
      let secondTime = parseInt(endTime); //将传入的秒的值转化为Number
      let min = 0; // 初始化分
      let h = 0; // 初始化小时
      let result = "";
      if (secondTime > 60) {
        //如果秒数大于60,将秒数转换成整数
        min = parseInt(secondTime / 60); //获取分钟,除以60取整数,得到整数分钟
        secondTime = parseInt(secondTime % 60); //获取秒数,秒数取佘,得到整数秒数
        if (min > 60) {
          //如果分钟大于60,将分钟转换成小时
          h = parseInt(min / 60); //获取小时,获取分钟除以60,得到整数小时
          min = parseInt(min % 60); //获取小时后取佘的分,获取分钟除以60取佘的分
        }
      }
      result = `${min
        .toString()
        .padStart(2, "0")}:${secondTime.toString().padStart(2, "0")}`;
      return result;
    },
  },
};
</script>
<style lang="scss" scoped>
.body-video {
  width: 100%;
  height: 100%;
  background: #000000;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
}
.video-js {
  width: 100%;
  height: calc(100% - 106rpx);
  background: #000000;
}
.video-small {
  width: calc(100% - 204rpx);
  height: calc(100% - 219rpx);
  background: #000000;
}
.video-mask {
  width: 100%;
  height: calc(100% - 106rpx);
  position: absolute;
  top: 53rpx;
  z-index: 99;
}
.auto-speed {
  position: absolute;
  width: rpx(172);
  height: rpx(172);
  left: 50%;
  top: 50%;
  margin-left: rpx(-86);
  margin-top: rpx(-86);
  z-index: 999999999;
}
.close-video {
  width: rpx(90);
  height: rpx(90);
  background: rgba(51, 51, 51, 0.8);
  border-radius: rpx(20);
  position: absolute;
  left: rpx(60);
  top: rpx(55);
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  .close-icon {
    width: rpx(60);
    height: rpx(60);
  }
}
.pause {
  width: rpx(172);
  height: rpx(172);
  left: 50%;
  top: 50%;
  position: absolute;
  margin-left: rpx(-86);
  margin-top: rpx(-86);
  z-index: 999;
  .pause-icon {
    width: rpx(172);
    height: rpx(172);
  }
}
.bottom {
  width: 100%;
  position: absolute;
  height: rpx(192);
  bottom: 0;
  z-index: 9999;
  left: 0;
  right: 0;
  display: flex;
  align-items: center;
  .time {
    display: flex;
    align-items: center;
    font-size: rpx(32);
    font-family: HelveticaNeue;
    color: rgba(255, 255, 255, 1);
    margin-left: rpx(60);
    .currentTime {
      color: rgba(255, 255, 255, 1);
    }
    .spet {
      color: rgba(136, 136, 136, 1);
      margin-left: 4px;
    }
    .duration {
      color: rgba(136, 136, 136, 1);
      margin-left: 4px;
    }
  }
}
.progressWrap {
  border-radius: rpx(6);
  height: rpx(8);
  cursor: pointer;
  margin-left: rpx(30);
  display: flex;
  align-items: center;
  flex: 1;
}
.cicle {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 1);
}
#playProgress {
  background: rgba(217, 217, 217, 1);
  width: 0px;
  height: rpx(8);
}
.full {
  width: rpx(60);
  height: rpx(60);
  display: flex;
  align-items: center;
  margin-right: rpx(61);
  margin-left: rpx(60);
  .scale {
    width: rpx(60);
    height: rpx(60);
  }
}
.volume-control {
  position: absolute;
  top: rpx(55);
  right: rpx(75);
  height: rpx(90);
  background: rgba(51, 51, 51, 0.8);
  border-radius: rpx(20);
  display: flex;
  align-items: center;
  .volume {
    width: rpx(358);
    height: rpx(8);
    background: rgba(110, 110, 110, 1);
    border-radius: rpx(4);
    display: flex;
    align-items: center;
    margin-left: rpx(50);
    margin-right: rpx(50);
    display: flex;
    align-items: center;
    .volume-muted {
      height: rpx(8);
      background: rgba(217, 217, 217, 1);
      border-radius: rpx(4);
    }
    .volume-cicle {
      width: 10px;
      height: 10px;
      border-radius: 50%;
      background: rgba(255, 255, 255, 1);
    }
  }
}
.volum {
  width: rpx(60);
  display: flex;
  margin-left: rpx(15);
  align-items: center;
  margin-right: rpx(15);
  height: rpx(60);
  .volum-icon {
    width: rpx(60);
    height: rpx(60);
  }
}
.video-slider {
  width: 100%;
  height: rpx(8);
}
</style>