Vue2中使用vue-video-player实现断点续传功能详解

737 阅读2分钟

Vue2中使用vue-video-player实现断点续传功能详解

实现原理

断点续传的核心在于:

  1. 监听视频播放进度并定期保存
  2. 重新加载页面或切换回视频时恢复上次播放位置

具体实现步骤

1. 安装依赖

npm install vue-video-player --save
# 或使用yarn
yarn add vue-video-player

2. 组件实现

<template>
  <div class="video-container">
    <video-player
      ref="videoPlayer"
      class="video-player"
      :options="playerOptions"
      @timeupdate="onTimeUpdate"
      @play="onPlay"
      @pause="onPause"
      @ended="onEnded"
    ></video-player>
  </div>
</template>

<script>
import 'video.js/dist/video-js.css'
import { videoPlayer } from 'vue-video-player'

export default {
  components: {
    videoPlayer
  },
  data() {
    return {
      playerOptions: {
        autoplay: false,
        controls: true,
        sources: [{
          type: 'video/mp4',
          src: 'https://example.com/video.mp4'
        }],
        // 其他配置...
      },
      saveProgressInterval: null,
      lastSaveTime: 0
    }
  },
  computed: {
    videoSrc() {
      return this.playerOptions.sources[0].src
    }
  },
  mounted() {
    // 初始化播放器后加载保存的进度
    this.$nextTick(() => {
      this.loadSavedProgress()
      
      // 设置进度保存定时器(每5秒保存一次)
      this.saveProgressInterval = setInterval(() => {
        this.saveCurrentProgress()
      }, 5000)
    })
  },
  beforeDestroy() {
    // 组件销毁前清除定时器
    if (this.saveProgressInterval) {
      clearInterval(this.saveProgressInterval)
    }
  },
  watch: {
    // 监听视频源变化,加载新视频的进度
    videoSrc(newSrc) {
      this.$nextTick(() => {
        this.loadSavedProgress()
      })
    }
  },
  methods: {
    onTimeUpdate() {
      // 可选:实时更新进度,但频繁触发可能影响性能
      // 实际应用中可能不需要每次timeupdate都保存
    },
    onPlay() {
      // 视频开始播放时开始保存进度
      this.startSaveProgress()
    },
    onPause() {
      // 视频暂停时保存当前进度
      this.saveCurrentProgress()
    },
    onEnded() {
      // 视频播放结束时清除保存的进度
      this.clearSavedProgress()
    },
    startSaveProgress() {
      // 开始播放时启动定时保存
      if (!this.saveProgressInterval) {
        this.saveProgressInterval = setInterval(() => {
          this.saveCurrentProgress()
        }, 5000)
      }
    },
    saveCurrentProgress() {
      const currentTime = this.$refs.videoPlayer.player.currentTime()
      // 避免过于频繁保存(小于1秒的播放不保存)
      if (currentTime - this.lastSaveTime >= 1) {
        localStorage.setItem(`video-progress-${this.videoSrc}`, currentTime.toString())
        this.lastSaveTime = currentTime
      }
    },
    loadSavedProgress() {
      const savedTime = localStorage.getItem(`video-progress-${this.videoSrc}`)
      if (savedTime) {
        this.$nextTick(() => {
          this.$refs.videoPlayer.player.currentTime(parseFloat(savedTime))
        })
      }
    },
    clearSavedProgress() {
      localStorage.removeItem(`video-progress-${this.videoSrc}`)
    }
  }
}
</script>

<style scoped>
.video-container {
  width: 100%;
  max-width: 800px;
  margin: 0 auto;
}
.video-player {
  width: 100%;
  height: 0;
  padding-top: 56.25%; /* 16:9比例 */
  position: relative;
}
</style>

注意事项

  1. ​存储介质选择​​:

    • 使用localStorage适合单机应用
    • 如需跨设备同步,应考虑服务器端存储
  2. ​进度保存频率​​:

    • 不要过于频繁保存(如每秒多次),以免影响性能
    • 建议至少间隔1秒保存一次
  3. ​不同视频源处理​​:

    • 切换视频源时要清除旧视频的进度记录
    • 使用唯一的键名标识不同视频的进度(如video-progress-${src})
  4. ​页面关闭前保存​​:

    • 可以监听beforeunload事件确保进度保存
    mounted() {
      window.addEventListener('beforeunload', this.handleBeforeUnload)
    },
    beforeDestroy() {
      window.removeEventListener('beforeunload', this.handleBeforeUnload)
    },
    methods: {
      handleBeforeUnload() {
        this.saveCurrentProgress()
      }
    }
    
  5. ​大视频文件处理​​:

    • 对于非常大的视频,可以考虑只保存关键点位置
    • 或增加保存间隔以减少存储和处理压力
  6. ​错误处理​​:

    • 添加try-catch处理localStorage可能的异常
    • 考虑localStorage容量限制(通常5MB左右)

这种实现方式简单有效,适用于大多数需要断点续传功能的视频播放场景。