Vue中使用DPlayer播放Hls(m3u8)视频
H5中有很多播放器可以使用,比如DPlayer、Video.js,这里不是去做播放器之间的对比,而是基于DPlayer,总结一下在Vue中如何使用,以及相关的一些关键点,比如播放Hls(m3u8)视频,以及播放成功和失败的事件监听。
为什么不用vue-dplayer
vue有一个现成的开源组件,vue-dplayer,来在vue中集成使用dplayer。但建议不用去研究和使用,vue-dplayer有几个问题:
-
本身不支持动态加载视频
很多功能的实现中,视频的src url是基于ajax请求获取,然后交给dplayer组件进行播放。直接使用dplayer会比较简单,但如果使用vue-dplayer组件,就不得不搞成这样。
<template> <dPlayer ref="player" :options="options"></dPlayer> </template> <script> import dPlayer from 'vue-dplayer' export default { name: 'example', components: { dPlayer }, data () { return { player: null, options: { video: { url: '' } } } }, mounted() { this.player = this.$refs.player.dp }, created() { // request video url, such as src this.playVideo(src) }, methods: { playVideo(src) { this.player.switchVideo({ url: src }) } } } </script>
必须使用vue-dplayer的switchVideo接口来切换src,因为options不是一个双向绑定的数据。如果request数据的时间偏长,尤其伴随请求和设置视频封面时,可能会出现一个黑色不可用的播放器,之后有一个刷新的过程,看到图片,然后等待视频加载,用户体验上受到影响。
-
不支持HLS视频
虽然按照vue-dplayer的说明中,可以设置options来播放Hls。但实际上行不通,因为vue-dplayer没有处理好hls.js一些需要配合播放Hls视频的操作。
options: { video: { url: 'http://xxxxx.xx.xxx/xx.m3u8', type: 'hls' } }
-
vue-player只是简单将dplayer进行vue组件化,使用起来没有太大必要性
使用dplayer非vue组件化的方式进行绑定和初始化,没有什么开发成本。
正确使用DPlayer播放Hls的方式
安装dplayer
npm install -S dplayer
安装hls.js,播放Hls必须使用
npm install -S hls.js
vue组件代码(**.vue)
<template>
<div>
<div id="dplayer" ref="player"></div>
</div>
</template>
<script>
import Hls from 'hls.js'
import Dplyaer from 'dplayer'
export default {
name: 'example1',
data () {
dp: null,
video: {}
},
methods: {
loadVideo (videoInfo) {
this.dp = new Dplayer({
element: this.$refs.player,
video: {
pic: videoInfo.img, // 封面
url: videoInfo.video,
type: 'customHls',
customType: {
customHls: function (video, player) {
const hls = new Hls()
hls.loadSource(video.src)
hls.attachMedia(video)
}
}
}
})
}
},
mounted () {
// getVideo: ajax request for getting videoInfo
getVideo().then(res => {
this.video = res.data.video
this.laodVideo(this.video)
})
}
}
</script>
视频播放事件监控
一般要监控的事件,是播放错误(往往是资源下载错误)、视频下载成功可以播放。
- Hls视频资源下载错误
this.dp = new Dplayer({
element: this.$refs.player,
video: {
pic: videoInfo.img,
url: videoInfo.video,
type: 'customHls',
customType: {
customHls: function (video, player) {
const hls = new Hls()
// 监听Hls.Events.ERROR事件,
// DNS解析、下载超时,都会触发manifestLoadError错误
hls.on(Hls.Events.ERROR, function (eventName, data) {
// 埋点上报,可以追踪data.details
// track()
})
hls.loadSource(video.src)
hls.attachMedia(video)
}
}
}
})
-
视频下载成功可以播放
播放器从开始下载到可以播放,dplayer延续H5 video的事件,依次会触发loadstart、durationchange、loadedmetadata、loadeddata、progress、canplay、canplaythrough。
虽然直觉上是监听canplay,但是canplay在iOS上行不通,只能使用loadedmetadata。
methods: {
loadVideo (videoInfo) {
this.dp = new Dplayer({
element: this.$refs.player,
video: {
pic: videoInfo.img, // 封面
url: videoInfo.video,
type: 'customHls',
customType: {
customHls: function (video, player) {
const hls = new Hls()
hls.loadSource(video.src)
hls.attachMedia(video)
}
}
}
})
// 监听loadedmetadata事件
this.dp.on('loadedmetadata', function () {
// 埋点上报
// track()
})
}
},