1.安装依赖(亲测5.0.1版本可用,最新版本会找不到'vue-video-player/src/custom-theme.css'这个样式)
npm install vue-video-player@5.0.1 --save
2.在main.js中添加
import VideoPlayer from 'vue-video-player/src';
require('vue-video-player/src/custom-theme.css')
import 'video.js/dist/video-js.css'
Vue.use(VideoPlayer)
3.新建一个video.vue文件
<template>
<div class="box">
<div class="course_node_video">
<video-player
class="video-player vjs-custom-skin"
ref="videoPlayer"
:playsinline="true"
:options="playerOptions"
@ready="playerReadied"
@pause="onPlayerPause($event)"
@timeupdate="onPlayerTimeupdate($event)"
customEventName="customstatechangedeventname"
@play="onPlayerPlay"
@ended="onPlayerEnded"
@waiting="onPlayerWaiting"
@playing="onPlayerPlaying"
@loadeddata="onPlayerLoadeddata"
@canplay="onPlayerCanplay"
@canplaythrough="onPlayerCanplaythrough"
@statechanged="playerStateChanged"
>
</video-player>
<!-- <div class="footer">
<div class="list" @click="videoPlay">播放</div>
<div class="list" @click="videoPause">停止</div>
<div class="list" @click="videoPosition">播放位置</div>
<div class="list" @click="videoDoubleSpeed">倍速</div>
<div class="list" @click="videoMute">静音</div>
</div> -->
</div>
</div>
</template>
<script>
export default {
data() {
return {
playerOptions: {
playbackRates: [0, 0.5, 1.0, 1.5, 2.0], // 可选的播放速度
autoplay: false, // 如果为true,浏览器准备好时开始回放。
muted: false, // 默认情况下将会消除任何音频。
loop: false, // 是否视频一结束就重新开始。
preload: 'auto', // 建议浏览器在<video>加载元素后是否应该开始下载视频数据。auto浏览器选择最佳行为,立即开始加载视频(如果浏览器支持)
language: 'zh-CN', // zh-CN 需要main.js全局引入才可以生效
aspectRatio: '16:9', // 将播放器置于流畅模式,并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字(例如"16:9"或"4:3")
fluid: true, // 当true时,Video.js player将拥有流体大小。换句话说,它将按比例缩放以适应其容器。
sources: [
{
type: 'video/mp4', // 类型
src: 'https://qkodo.playlistmusic.com.cn/transcode_1080/video/2dd0dd6bb83b71d16c6313d0411d26aa.mp4' // url地址https://qkodo.playlistmusic.com.cn/transcode_1080/video/2dd0dd6bb83b71d16c6313d0411d26aa.mp4
}
],
poster: '', // 封面地址
notSupportedMessage: '此视频暂无法播放,请稍后再试', // 允许覆盖Video.js无法播放媒体源时显示的默认信息。
controlBar: {
// 当前时间和持续时间的分隔符
timeDivider: true,
// 显示持续时间
durationDisplay: true,
// 是否显示剩余时间功能
remainingTimeDisplay: false,
// 是否显示全屏按钮
fullscreenToggle: true,
//播放暂停按钮
playToggle: true,
//音量控制
volumeMenuButton: false,
//当前播放时间
currentTimeDisplay: true,
//点播流时,播放进度条,seek控制
progressControl: true,
//直播流时,显示LIVE
liveDisplay: true,
//播放速率,当前只有html5模式下才支持设置播放速率
playbackRateMenuButton: true
}
},
currentTime: 0, // 秒数设置 单位默认s 进度条位置设置 , 进入页面直接开始位置一一一一一一
playtimes: 7 // 通过点击videoPosition事件改变视频位置二二二二二
};
},
methods: {
// 视频播放
videoPlay() {
// this.player.play();
// this.playerOptions.controlBar.playToggle = false;
this.$refs.videoPlayer.player.play();
},
// 视频暂停
videoPause() {
this.$refs.videoPlayer.player.pause();
},
// 视频位置
videoPosition() {
// 通过点击videoPosition事件改变视频位置二二二二二
this.$refs.videoPlayer.player.currentTime(this.playtimes);
console.log('当前位置', this.$refs.videoPlayer.player.currentTime(this.playtimes));
},
// 视频倍速
videoDoubleSpeed() {
//https://www.zhangxinxu.com/study/201807/video-playbackrate.html
// https://blog.csdn.net/qq_35153373/article/details/112183508
this.$refs.videoPlayer.player.playbackRate(2); // 这个能设置固定倍速
// var button = document.getElementsByTagName('vjs-playback-rate')
// button.addEventListener('change', function () {
// this.$refs.videoPlayer.player.playbackRate = this.playerOptions.playbackRates;
// });
// this.$refs.videoPlayer.player.ready(function () {
// const num = Math.round(Math.random()*5+5);
// // 定义一个随机常数倍数
// var _this = this
// //速率
// setTimeout(function () {
// // _this.playbackRate(parseFloat(10));// 能设定固定值
// _this.playbackRate(parseFloat(num)); // 随机的
// }, 20);
// });
},
// 视频静音
videoMute() {
this.$refs.videoPlayer.player.muted(true);
},
//获取视频播放进度 进度更新(当前播放位置发生变化时触发)(视频接收到新内容会一直调用)(高频调用)
onPlayerTimeupdate(player) {
// this.currentTime = player.cache_.currentTime 进度条位置设置 , 进入页面直接开始位置一一一一一一
// console.log(player.cache_.currentTime, '监听位置');
this.$emit('handleCurrentTime',player.cache_.currentTime)
},
/* 设置视频开始的进度 准备就绪(预加载前会调用)(初始化调用) */
playerReadied(player) {
player.currentTime(this.currentTime);
},
// 暂停回调 将视频播放的时间保存 暂停回调(暂停时调用)(用户操作调用)
onPlayerPause(player) {
console.log('player pause currentTime!', player.cache_.currentTime);
// let that = this;
this.$emit('onPlayerPause', player.cache_.currentTime);
// 存储player.currentTime 是当前暂停时间 用于下次断续播放
},
// 播放回调(播放时会调用)(用户操作调用)
onPlayerPlay(player) {
this.$emit('onPlayerPlay', player);
},
// 播放状态改变回调
playerStateChanged(playerCurrentState) {
console.log('数据变化', playerCurrentState);
this.$emit('playerStateChanged', playerCurrentState);
},
//视频播完回调 (结束)(视频播放完毕调用)
onPlayerEnded(player) {
console.log('结束', player);
this.$emit('onPlayerEnded', player);
},
// 等待(视频中出现loading就会调用,加载时调用)(高频调用)
onPlayerWaiting(player) {
console.log('等待', player);
this.$emit('onPlayerWaiting', player);
},
// 播放中(进入播放状态会调用)(等待onPlayerWaiting和播放onPlayerPlay执行后会调用)(高频调用)
onPlayerPlaying(player) {
console.log('播放中', player);
this.$emit('onPlayerPlaying', player);
// this.$refs.videoPlayer.player.currentTime(this.playtimes)
},
// 当播放器在当前播放位置下载数据时触发
onPlayerLoadeddata(player) {
console.log('预加载', player);
this.$emit('onPlayerLoadeddata', player);
},
// 媒体的readyState为HAVE_FUTURE_DATA或更高(预加载onPlayerLoadeddata调用后会调用)(初始化调用)
onPlayerCanplay(player) {
console.log('是否播放', player);
this.$emit('onPlayerCanplay', player);
},
// 能够从头到尾播放(是否播放onPlayerCanplay调用后会调用)(初始化调用)这意味着可以在不缓冲的情况下播放整个媒体文件
onPlayerCanplaythrough(player) {
console.log('能够从头到尾播放', player);
this.$emit('onPlayerCanplaythrough', player);
}
},
beforeMount() {
// let id = this.$route.query.id;
// if (id != undefined && id != null) {
// //编辑
// localStorage.setItem("videoId", id);
// // this.loadCourseNodeVideo(id);
// } else {
// id = localStorage.getItem("videoId");
// if (id != undefined && id != null) {
// // this.loadCourseNodeVideo(id);
// } else {
// localStorage.removeItem("videoId");
// }
// }
}
};
</script>
<style>
.box {
width: 94%;
margin: 0 auto;
margin-bottom: 40px;
}
/* 重置样式也需要全局挂载 */
* {
margin: 0;
padding: 0;
}
.course_node_video {
width: 100%;
height: auto;
margin: 0 auto;
text-align: center;
/* object-fit:fill; */
}
/* 是否禁止拖动进度条 */
/* .course_node_video >>> .vjs-progress-control {
pointer-events: none;
} */
/* 这里深度选择器这种生效,需要去掉style标签里面的scoped才可以生效使用,才可以铺满屏幕 */
::v-deep video {
width: 100% !important;
/* 我的容器高度设置的是100vh-95px,你们根据你们容器高度设置视频高度即可 */
height: calc(100vh - 95px) !important;
/* 消除两边留白 */
object-fit: fill;
}
.footer {
width: 100%;
height: 50px;
/* border: 1px solid red; */
/* background-color: rgb(67,77,71); */
flex-direction: row;
display: flex;
justify-content: space-between;
}
.footer .list {
width: 15%;
height: 100%;
/* background-color: rgba(255, 255, 255, 0.1); */
background-color: rgb(67, 77, 71);
border: 1px solid rgb(224, 208, 208);
color: #fff;
line-height: 2.8;
}
</style>
4.在页面中使用
<video-box
@onPlayerEnded="onPlayerEnded"
@handleCurrentTime="handleCurrentTime"
@onPlayerPlay="onPlayerPlay"
@onPlayerPause="onPlayerPause"
></video-box>
import VideoBox from '@/components/page/course/components/video.vue';
export default {
components: {
VideoBox
},
methods: {
toGoBack() {
this.$router.go(-1);
// console.log(this.course, 'asdasdas');
},
toChoseCourse(item) {
console.log(item,'当前位置')
this.smallId = item.id;
this.courseInfo = item;
},
//视频结束
onPlayerEnded() {
console.log('下一节课');
},
//监听视频位置滑动
handleCurrentTime(e) {
console.log('当前位置', e);
},
//视频播放
onPlayerPlay(player){
console.log('播放', player);
},
//视频暂停
onPlayerPause(e){
console.log('暂停,位置', e);
}
},
}