目录
videojs官网
踩的坑
1. 解决ios系统视频会默认全屏播放
// video标签中增加该属性
webkit-playsinline="true"
playsinline="true"
2. 视频播放结束后展示黑屏(想展示封面和播放按钮,进度条退回零)
this.on('ended', () => {
console.log('视频结束')
// 5.0及以后版本
this.hasStarted(false)
// this.posterImage.show() // 展示封面 -- 适用于5.0一下版本
// this.bigPlayButton.show() // 展示播放按钮 -- 适用于5.0一下版本
this.currentTime(0) // 进度条退回0
})
3. 播放的按钮样式
默认是左上一个小按钮,要设置居中的大按钮就给<video>
增加一个类名vjs-big-play-centered
4. 视频格式
<source :src="videoData.videoUrl" :type="sourceType">
m3u8 设置sourceType为'application/x-mpegURL'
mp4 设置sourceType为'video/mp4'
5. 路由跳转可能会id报错
组件销毁时调用自带的销毁方法:
myVideo.dispose()
6. vue3中通过npm加载,然后打包的js代码过大,导致加载速度慢
通过是用cdn引入videojs,减小资源包
// index.html
<script src="//vjs.zencdn.net/7.10.2/video.min.js"></script>
<link href="//vjs.zencdn.net/7.10.2/video-js.min.css" rel="stylesheet">
// vue.config.js
configureWebpack: config => {
config.externals = {
'moment': 'moment',
'echarts': 'echarts',
'videojs': 'videojs'
}
},
基础使用(仅供参考,并非完整代码)
$ npm install --save video.js
<template>
<video :id="'video_' + videoData.videoBaseInfoId"
class="video-js vjs-default-skin vjs-big-play-centered"
controls
preload="none"
width="640" height="264"
:poster="videoData.content"
webkit-playsinline="true"
playsinline="true">
<source :src="videoData.videoUrl" :type="sourceType">
</video>
</template>
<script>
import videojs from 'video.js'
import videoZhCN from 'video.js/dist/lang/zh-CN.json'
videojs.addLanguage('zh-CN', videoZhCN)
export default {
props: ['videoData'],
emits: ['pause', 'playing'],
setup (props, { emit }) {
const state = reactive({
sourceType: computed(() => {
switch (props.videoData.videoSuffix) {
case 'm3u8': return 'application/x-mpegURL'
case 'mp4': return 'video/mp4'
}
}),
myVideo: null,
videoTotalTime: 0,
playBeginTime: null,
playEndTime: null,
actionType: VIDEO_TYPE.VIDEO_PAUSE,
videoDefaultConfig: {
controls: true, // 是否显示播放器控件
autoplay: false, // 是否自动播放
fluid: true, // 自适应宽高
language: 'zh-CN', // 设置语言
// width: 864, // 视频的宽度
// height: 486, // 视频的高度
aspectRatio: '16:9', // 视频的宽高比
poster: props.videoData.content, // 视频的封面
muted: false, // 非静音
// loop: true, // 循环播放
controlBar: { // 底部的控制栏组件
currentTimeDisplay: true, // 当前播放时间
timeDivider: true, // 当前播放时间与总时间的斜杆分隔符
durationDisplay: true, // 是否显示总时间
remainingTimeDisplay: false, // 是否显示剩下的时间,该选项与是否显示总时间二选一
children: [ // children数组这是controlbar的子元素顺序 // 好像不起作用
{ name: 'playToggle' }, // 播放按钮
// { name: 'volumePanel', inline: true }, // 音量控制, 不使用水平方式
{ name: 'currentTimeDisplay' },
{ name: 'progressControl' },
{ name: 'durationDisplay' },
// { name: 'playbackRateMenuButton', playbackRates: [0.5, 1, 1.5, 2] }, // 倍速播放
{ name: 'FullscreenToggle' } // 全屏按钮
]
}
}
})
watch(() => props.videoData.isPause, (val) => {
if (val && state.myVideo) {
state.myVideo.pause()
}
})
pageCloser(() => {
if (state.actionType === VIDEO_TYPE.VIDEO_PLAYING && state.myVideo) {
emit('pause', state.myVideo.currentTime(), props.videoData, VIDEO_TYPE.VIDEO_PAUSE)
state.myVideo.dispose()
}
})
onMounted(() => {
initVideo()
})
onUnmounted(() => { // 页面销毁前,将视频组件销毁
state.myVideo.dispose()
})
const initVideo = () => {
state.myVideo = videojs('video_' + props.videoData.videoBaseInfoId, state.videoDefaultConfig, function () {
this.on('error', () => {
// 视频错误监听事件
console.log('视频错误监听事件')
})
this.on('loadstart', () => {
// 视频开始加载数据监听事件
console.log('视频开始加载数据监听事件')
})
this.on('loadedmetadata', () => {
// 视频加载数据
console.log('加载视频数据')
state.videoTotalTime = this.duration()
console.log(state.videoTotalTime)
})
this.on('playing', () => {
// 视频正在播放监听事件
console.log('视频播放')
state.actionType = VIDEO_TYPE.VIDEO_PLAYING
state.playBeginTime = new Date()
emit('playing', props.videoData.videoBaseInfoId)
})
this.on('canplaythrough', () => {
// 视频可以播放监听事件
console.log('视频可以播放监听事件')
})
this.on('stalled', () => {
console.log('网络异常')
})
this.on('waiting', () => {
// 视频正在加载事件
console.log('视频正在加载事件')
})
this.on('pause', () => {
console.log('视频暂停')
state.actionType = VIDEO_TYPE.VIDEO_PAUSE
emit('pause', props.videoData.videoBaseInfoId, this.currentTime(), state.playBeginTime)
})
this.on('ended', () => {
console.log('视频结束')
this.hasStarted(false)
// this.posterImage.show() // 展示封面
// this.bigPlayButton.show() // 展示播放按钮
this.currentTime(0) // 进度条退回0
})
})
}
return {
...toRefs(state)
}
}
}
</script>