vue-video-player implements breakpoint resume playback, and the currentTime does not take effect.

vue-video-player implements breakpoint resume playback, and the currentTime does not take effect.

The video setting currentTime does not take effect, and Google Chrome does not take effect.

1. How does vue-video-player implement video playback

About this part, there are many detailed explanations on the Internet, please see (or other articles) for details: How to implement vue-video-player component playback

2. After realizing the playback of the video, the demand is to realize the breakpoint playback.

  1. That is, the start playback time is no longer starting from 0 seconds, but according to our own settings (usually passed from the backend), the last time you log in to the learning website in the usage scenario , watch a learning video, and watch it for 20 minutes (after watching it) , assuming that the total duration is 50 minutes, then the next time we log in to the learning website again and click on this video to play, we still need to start playing from 20 minutes instead of starting from 0.
    At this time, it is necessary to implement breakpoint resume.

Paste the source code of my component here:

<template>
  <div class="an-video" :style="{ width: width, height: height }">
    <video-player
      class="video-player vjs-custom-skin"
      ref="videoPlayer"
      :playsinline="true"
      :options="playerOptions"
      :readiedTime="readiedTime"
      @play="onPlayerPlay($event)"
      @pause="onPlayerPause($event)"
      @ended="onPlayerEnded($event)"
      @ready="playerReadied($event)"// 实现断点续播的关键
      @timeupdate="onPlayerTimeupdate($event)"
    ></video-player>
  </div>
</template>

<script>
import {
    
     videoPlayer } from "vue-video-player";
import "video.js/dist/video-js.css";
import "vue-video-player/src/custom-theme.css";

export default {
    
    
  name: "AnVideo",
  components: {
    
    
    videoPlayer,
  },
  props: {
    
    
    //必传:url
    width: {
    
    
      //宽度
      type: String,
      default: "400px",
    },
    height: {
    
    
      //高度
      type: String,
      default: "240px",
    },
    url: {
    
    
      type: String, //必选参数,上传的地址
      require,
    },
    playbackRates: {
    
    
      type: Array,
      default: function () {
    
    
        return [0.7, 1.0, 1.5, 2.0]; //播放速度
      },
    },
    autoplay: {
    
    
      type: Boolean,
      default: false, //如果true,浏览器准备好时 自动播放。
    },
    muted: {
    
    
      type: Boolean,
      default: false, //默认情况下将会消除任何音频。
    },
    loop: {
    
    
      type: Boolean,
      default: false, //视频一结束就重新开始,循环播放。
    },
    aspectRatio: {
    
    
      type: String,
      default: "16:9", //播放器的动态大小,代表一个比例 - 用冒号分隔的两个数字(例如"16:9"或"4:3")
    },
    poster: {
    
    
      type: String,
      default: "/课程学习.jpg", //视频封面地址,使用了本地一个图片
    },
    showPoster: {
    
    
      type: Boolean,
      default: false, //是否展示 ,视频封面地址
    },
    readiedTime: {
    
    
      type: String,
      default: "", //设置 开始播放视频的位置,已经看完的时间
    },
  },
  data() {
    
    
    return {
    
    
      playerOptions: {
    
    }, // 播放信息
      player: null,
      duration: 0, // 视频总长
    };
  },
  created() {
    
    
    this.initData();
  },
  methods: {
    
    
    initData() {
    
    
      this.playerOptions = {
    
    
        playbackRates: this.playbackRates, //播放速度
        autoplay: this.autoplay, //如果true,浏览器准备好时开始回放。
        muted: this.muted, // 默认情况下将会消除任何音频。
        loop: this.loop, // 导致视频一结束就重新开始。
        preload: "auto", //规定是否预加载视频 ,auto - 当页面加载后载入整个视频 meta - 当页面加载后只载入元数据,none - 当页面加载后不载入视频
        language: "zh-CN",
        aspectRatio: this.aspectRatio, // 将播放器置于流畅模式,并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字(例如"16:9"或"4:3")
        fluid: true, // 当true时,Video.js player将拥有流体大小。换句话说,它将按比例缩放以适应其容器。
        poster: this.poster, //你的封面地址
        width: document.documentElement.clientWidth,
        notSupportedMessage: "此视频暂无法播放,请稍后再试", //允许覆盖Video.js无法播放媒体源时显示的默认信息。
        controlBar: {
    
    
          timeDivider: true,
          durationDisplay: true,
          remainingTimeDisplay: false,
          fullscreenToggle: true, //全屏按钮
        },
      };
      // 不设置封面地址
      if (!this.showPoster) {
    
    
        this.playerOptions.poster = "";
      }
      // 设置 播放地址和视频类型
      if (this.url) {
    
    
        let sources = [];
        let typeStr = this.url.split(".");
        let videoType = typeStr[typeStr.length - 1];
        sources.push({
    
    
          src: this.url,
          type: "video/" + videoType, // 类型
        });
        this.playerOptions.sources = sources;
      }
    },
    // 播放回调
    onPlayerPlay(player) {
    
    
      this.$emit("play", player);
      console.log("onPlayerPlay");
    },

    // 播放暂停回调
    onPlayerPause(player) {
    
    
      console.log("onPlayerPause暂停", player);
      this.$emit("pause");
    },
    // 播放结束
    onPlayerEnded() {
    
    
      console.log("onPlayerEnded 播放结束", player);
      this.$emit("ended");
    },
    //获取当前播放进度 , 当前播放位置发生变化时触发。
    onPlayerTimeupdate(player) {
    
    
      console.log(
        "onPlayerTimeupdate播放位置发生变",
        player.cache_.currentTime
      );
      // let currentTime = player.cache_.duration; //总时长
      let currentTime = player.cache_.currentTime; //当前时间
      this.$emit("timeupdate", currentTime);
    },
    // 设置播放进度,实现断点续播。
    playerReadied: function (player) {
    
    
      console.log("playerReadied", player);

      if (this.readiedTime) {
    
    //后端传值来的时间
      // 我的项目中,后端传值为 字符串格式  “00:00:00” 时:分:秒 (所以我做了处理,将其转化为秒)
        let time = this.readiedTime.split(":");
        let newTime =
          Number(time[0]) * 3600 + Number(time[1]) * 60 + Number(time[2]);
        console.log("处理后的时间", newTime);

        player.currentTime(newTime);// 此处,设置了开始播放时间。
      }
    },
  },
};
</script>

<style scoped>
.an-video {
    
    
  /* width: 400px; */
  margin-left: 2%;
}
.an-video >>> .video-js .vjs-big-play-button {
    
    
  top: 40%;
  left: 40%;
}

.an-video >>> .vjs-progress-control {
    
    
// 不允许自己在界面中,通过点击,调节进度。(设置后,进度条会不可手动调节)
  pointer-events: none !important;
}
</style>

3. There is a problem:

  1. Situation 1: The referenced local video can be resumed from breakpoints in both Firefox and Google
  2. Situation 2: The video referenced by the http address can take effect in Firefox, but not in Google.

4. Solutions

Change the settings response headers Content-Length and Accept-Ranges.
There will also be corresponding problems in ie, and the specific changes can be made according to the prompts in the figure below. Firefox is no problem.
insert image description here

5. Pay attention

The same problem does not only exist in the vue-video-player component, but in the native Dom of video, and the modification method is the same.

Guess you like

Origin blog.csdn.net/qq_41117240/article/details/123786389