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. 效果
目前的效果:
默认的功能有 暂停/播放,调整声音,全屏播放。朴实无华,够用。
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>
效果:
默认的功能上,跟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>
目前效果:
4. 待优化:
- 弹幕后台搭建(也是看教程)
- 两段跳转,第一次根据用户的权限获取视频的播放链接,第二段去视频服务器请求播放。
- 播放前获取视频信息,充实下播放页。