vue中使用flv.js以及DPlayer播放器播放flv格式视频

miaodi
发布于 2020-11-17 / 2899 阅读
0

vue中使用flv.js以及DPlayer播放器播放flv格式视频

1. 前言

自己的一个小项目:爬b站的视频保存到服务器(根据自定义的up主和指定的收藏夹),同时检查是否有删除和重新上传的。

想要加一个需求:可以在网页端直接播放保存在服务器的视频。

b站的视频有flv格式和dash格式。但是dash是音视频分离的,还是有一部分需求要在本地可以直接看的,所以脚本全部下载的flv格式的视频,最高能支持到4k分辨率。

FLV 是FLASH VIDEO的简称,flash漏洞太多,官方已经放弃维护了,flash播放器自然用不了。搜了下github,发现了b站开源的HTML5 flv播放器:flv.js,决定记录下代码。

2. flv.js

2.1 安装

安装flv.js :

npm install --save flv.js

2.2 最简单实现

最基础版本播放器:

修改下flv的地址即可,跨域的话需要提供flv视频的服务器设置下header:cors

play.vue: (高亮不支持vue,只能用js)

<template>
  <div class="home">
    <div class="example-title">flv.js 播放 flv 视频流</div>
    <video id="videoElement" controls width="80%"></video>
  </div>
</template>

<script>
import flvjs from 'flv.js/dist/flv.min.js'

export default {
  name: 'PlayVideo',
  props: {
    src: {
      type: String,
      default: '这里改为自己的视频地址'
    }
  },
  data() {
    return {
    }
  },
  created() {
  },
  mounted() {
    const flvSrc = this.src
    const videoElement = document.getElementById('videoElement')
    if (flvjs.isSupported()) {
      const flvPlayer = flvjs.createPlayer({
        type: 'flv',
        url: flvSrc
      })
      flvPlayer.attachMediaElement(videoElement)
      flvPlayer.load()
    } else {
      alert('不支持的浏览器类型')
    }
  },
  methods: {
  }
}
</script>

<style>
.home {
  text-align: center;
}

</style>


2.3 增加了传参

添加了地址参数,根据传参不同向后端请求不同的视频地址:

<template>
  <div class="home">
    <div class="example-title">flv.js 播放 flv 视频流</div>
    <video id="videoElement" controls width="80%"></video>
  </div>
</template>

<script>
import flvjs from 'flv.js/dist/flv.min.js'

export default {
  name: 'PlayVideo',
  props: {
    src: {
      type: String,
      default: '这里改为自己的视频地址'
    }
  },
  data() {
    return {
      cid: undefined
    }
  },
  created() {
    const cid = this.$route.params && this.$route.params.cid
    this.fetchData(cid)
    this.tempRoute = Object.assign({}, this.$route)
    this.cid = cid

    console.log('this.cid:' + this.cid)
  },
  mounted() {
    const flvSrc = this.src + this.cid
    console.log('flvSrc: ' + flvSrc)
    const videoElement = document.getElementById('videoElement')
    if (flvjs.isSupported()) {
      const flvPlayer = flvjs.createPlayer({
        type: 'flv',
        url: flvSrc
      })
      flvPlayer.attachMediaElement(videoElement)
      flvPlayer.load()
    } else {
      alert('不支持的浏览器类型')
    }
  },
  methods: {
    fetchData(cid) {
      console.log('cid:' + cid)
      // 向video模块请求数据,获取视频的标题,地址,是否有视频缓存在服务器上等信息
    }
  }
}
</script>

<style>
.home {
  text-align: center;
}

</style>


2.3. 效果

目前的效果:

image

默认的功能有 暂停/播放,调整声音,全屏播放。朴实无华,够用。

3. DPlayer

flv.js最后一次更新是3年前了,且仅支持flv/hls等几个格式播放。

最近发现diygod大神开源的DPlayer播放器,是一款HTML5的弹幕视频播放器。可以基于flv.js播放flv视频,还可以搭配其他播放器播放hls、dash等更多格式播放器。同时功能更多,支持弹幕,支持倍速播放等。

实际上,diygod也是b站员工,参与开发b站的播放器,所以播放器有很多功能跟b站的网页版很像。

3.1 安装

安装以及配置请参考官方文档:DOCS

DPlayer项目中有现成的vue播放器:MoePlayer/vue-dplayer ,可惜3年没更新了,各种代码自然不是最新的,这里直接在vue中使用DPlayer

npm install dplayer --save

3.2 最简单实现

同样是只实现了基础功能代码:

<template>
  <div class="home">
    <div class="example-title">DPlayer 播放 flv 视频流</div>
    <div id="dplayer" ></div>
  </div>
</template>

<script>
import flvjs from 'flv.js'
import DPlayer from 'dplayer'

export default {
  name: 'PlayVideo',
  props: {
    src: {
      type: String,
      default: '这里改为自己的视频地址'
    }
  },
  data() {
    return {
    }
  },
  created() {
  },
  mounted() {
    const flvSrc = this.src
    console.log('flvSrc: ' + flvSrc)
    const dp = new DPlayer({
      container: document.getElementById('dplayer'),
      video: {
        url: flvSrc,
        type: 'customFlv',
        customType: {
          customFlv: function(video, player) {
            const flvPlayer = flvjs.createPlayer({
              type: 'flv',
              url: video.src
            })
            flvPlayer.attachMediaElement(video)
            flvPlayer.load()
          }
        }
      }
    })
  },
  methods: {
  }
}
</script>

<style>
.home {
  text-align: center;
}

.example-title {
  font-size: 1.5em;
  font-weight: bold;
  margin-top: 2em;
  margin-bottom: 1.8em;
}

</style>

效果:image.png 默认的功能上,跟flv.js相比,自带调速功能,右键菜单做了改造,可以查看视频的大概信息等。


3.3 增加了部分配置

添加了地址参数,添加了播放器组件配置,弹幕功能暂未搭建,增加了播放器高度的限制。可以添加自定义右键信息等。

<template>
  <div class="home">
    <div class="example-title">DPlayer 播放 flv 视频流</div>
    <div id="dplayer" :style="autoHeight"></div>
  </div>
</template>

<script>
import flvjs from 'flv.js'
import DPlayer from 'dplayer'

const windowHeight = parseInt(window.innerHeight)
const windowWidth = parseInt(window.innerWidth)
export default {
  name: 'PlayVideo',
  props: {
    src: {
      type: String,
      default: '这里改为自己的视频地址'
    }
  },
  data() {
    return {
      cid: undefined,
      windowHeight: windowHeight,
      windowWidth: windowWidth,
      autoHeight: {
        height: '',
        width: ''
      }
    }
  },
  created() {
    window.addEventListener('resize', this.getHeight)
    this.getHeight()
    const cid = this.$route.params && this.$route.params.cid
    this.fetchData(cid)
    this.tempRoute = Object.assign({}, this.$route)
    this.cid = cid
    console.log('this.cid:' + this.cid)
  },
  destroyed() {
    window.removeEventListener('resize', this.getHeight)
  },
  mounted() {
    const flvSrc = this.src + this.cid
    console.log('flvSrc: ' + flvSrc)
    const dp = new DPlayer({
      container: document.getElementById('dplayer'),
      // 自动播放
      autoplay: false,
      theme: '#FADFA3',
      // 循环播放
      loop: false,
      lang: 'zh-cn',
      // 允许截图
      screenshot: true,
      hotkey: true,
      preload: 'auto',
      volume: 0.7,
      mutex: true,
      video: {
        url: flvSrc,
        type: 'customFlv',
        customType: {
          customFlv: function(video, player) {
            const flvPlayer = flvjs.createPlayer({
              type: 'flv',
              url: video.src
            })
            flvPlayer.attachMediaElement(video)
            flvPlayer.load()
          }
        }
      },
      // subtitle: {
      //   url: 'dplayer.vtt',
      //   type: 'webvtt',
      //   fontSize: '25px',
      //   bottom: '10%',
      //   color: '#b7daff'
      // },
      // danmaku: {
      //   id: '9E2E3368B56CDBB4',
      //   api: 'https://api.prprpr.me/dplayer/',
      //   token: 'tokendemo',
      //   maximum: 1000,
      //   addition: ['https://api.prprpr.me/dplayer/v3/bilibili?aid=4157142'],
      //   user: 'dong',
      //   bottom: '15%',
      //   unlimited: true
      // },
      contextmenu: [
        {
          text: '博客',
          link: 'https://www.bfmiaodi.cn'
        },
        {
          text: 'custom2',
          click: (player) => {
            console.log(player)
          }
        }
      ],
      highlight: [
        {
          time: 20,
          text: '这是第 20 秒'
        },
        {
          time: 120,
          text: '这是 2 分钟'
        }
      ]
    })
  },
  methods: {
    getHeight() {
      this.autoHeight.height = (windowHeight - windowHeight * 0.25) + 'px'
    },
    fetchData(cid) {
      console.log('cid:' + cid)
      // 向video模块请求数据,获取视频的标题,地址,是否有视频缓存在服务器上
    }
  }
}
</script>

<style>
.home {
  text-align: center;
}

.example-title {
  font-size: 1.5em;
  font-weight: bold;
  margin-top: 2em;
  margin-bottom: 1.8em;
}

</style>


目前效果:

image.png

4. 待优化:

  • 弹幕后台搭建(也是看教程)
  • 两段跳转,第一次根据用户的权限获取视频的播放链接,第二段去视频服务器请求播放。
  • 播放前获取视频信息,充实下播放页。