Vue2.0+Dplayer实现视频多格式播放(历史播放)

2,196 阅读1分钟

准备

  • Vue2.0
  • Dplayer
  • hls.js

开始

Dplayer & hls.js

  • 安装 dplayer npm i dplayer --save
  • 安装 hls.js npm i hls.js --save

video-player.vue文件

  • 首先考虑代码复用,所有我们需要将其抽取成组件

  • html代码:

<template>
  <div ref="dplayer"></div>
</template>
  • 代码如下
  1. 历史记录和视频的获取,通过接口
import { getDatasPost, getDatasGet } from '@/api/http' // 接口服务
import { videoHistoryTime, getVideoHistoryTime } from '@/api/config' // 接口服务

2.引入我们需要的文件

// hls.js需要在dplayer前引入
const Hls = require('hls.js')
import DPlayer from 'dplayer'

3.作为子组件需要接受的值

// vue的代码
// props里可以简化为一个对象,由于是迭代,作者太赖没有做
export default {
  name: 'VideoDplayer',
  props: {
    // 播放地址
    dpSrc: {
      type: String,
      default() {
        return ''
      }
    },
    // 视频id
    videoId: {
      typeof: Number,
      default() {
        return 0
      }
    },
    // 视频格式
    videoType: {
      type: String,
      default() {
        return ''
      }
    }
  },

4.我们需要的data

  data() {
    return {
      dplayerSrc: '',
      startTime: 0, // 开始时间
      endTime: 0 // 结束时间
    }
  },

5.这里做了个无用功

  computed: {
    /**
     * 本地缓存props中的dpSrc
     */
    dpSrcComputed() {
      return this.$props.dpSrc // 本地计算属性存值
    }
  },

6.mounted钩子中去获取到播放的时间

 mounted() {
   // 获取历史播放记录
   this.getInterfaceDatas()
 },

7.由于业务逻辑,这里只涉及到离开当前页面时保存记录。具体需求同理

  • 这一步将完成,把播放的时间通过接口储存到数据库中
beforeDestroy() {
// 接口请求参数
  const obj = {
  }
  // 发送储存播放时间的请求
  getDatasPost(videoHistoryTime, obj)
    .then()
    .catch((res) => {
      console.log(res)
    })
},

8.methods方法

methods: {
  /**
   * 构建dplayer
   * @param { String }url 视频播放地址
   * @param { Number }num 视频的播放记录
   */
  setDplayer(url, num) {
    let options
    // 当视频的格式 为 m3u8 时
    if (this.$props.videoType === '.m3u8') {
      // dplayer配置
      options = {
        // 获取dom
        container: this.$refs.dplayer,
        video: {
          url: url, // 视频播放地址
          // MSE支持
          type: 'customHls',
          customType: {
            customHls: function (video, player) {
              const hls = new Hls()
              hls.loadSource(video.src)
              hls.attachMedia(video)
            }
          }
        }
      }
    } else {
      // dplayer配置
      options = {
        // 获取dom
        container: this.$refs.dplayer,
        video: {
          url: url, // 视频播放地址
          type: 'auto'
        }
      }
    }
    const dp = new DPlayer(options) // 创建一个DPlayer
    // 视频跳转到播放记录
    dp.seek(num) // <----------------------------------------------------这里将跳转到对应的历史记录时间
    // 绑定播放事件
    dp.on('timeupdate', () => {
      // 将当前的时间赋值给结束时间
      this.endTime = dp.video.currentTime
    })
  },
}
}

父组件使用

    <main class="video-management__main">
      <div
        v-for="(item, index) in videoSrc"
        :key="index"
        class="video-management__content"
      >
        <video-dplayer
          :dp-src="item.src"
          :video-id="item.id"
          :video-type="item.type"
          class="main__content--component"
        ></video-dplayer>
        <span>{{ item.name }}</span>
      </div>
    </main>

遇到的问题

  • 历史记录一直为子组件中的初始值

思考

  • 和Echarts一样,dom的建立和数据的渲染之间有一定的前后管理,应该先获取到历史播放的数据,之后再通过创建dom对象,才能完成历史播放记录

解决

  • 将建立dplayer对象的函数,放在获取历史播放记录的接口成功回调中

总结

  • 设计到数据变化的dom对象建立,都应该将对应的函数放入数据请求的成功回调中