<template>
<el-row :gutter="20">
<el-col :span="0">
<!-- 视频区域 -->
<video
ref="trailer"
class="trailer_box"
preload
:src="$imgUrl + videoPath"
id="videoSmall"
v-show="isShowVideo"
>
您的浏览器不支持视频播放
</video>
</el-col>
<el-col :span="24">
<!--刻度尺-->
<div class="rule-box d-flex a-start j-start">
<div class="rule-area" v-if="isShow">
<div v-for="(item, index) in actionList" :key="index">
<el-popover
placement="top-start"
width="150"
trigger="click"
:content="item.hitTimeView"
@show="showPopover(index)"
>
<div
slot="reference"
class="rule-item"
:style="{ height: item.ruleHeight, left: item.left }"
></div>
</el-popover>
</div>
</div>
<div class="rule-area" v-else v-loading="loading"></div>
</div>
<!--只是获取滑块的宽度 -->
<div class="trailer_progress_bar d-flex flex-column" v-show="isShowBar">
<div class="proress_content_box" id="proressBox"></div>
</div>
<!-- 自定义视频进度条 -->
<div v-if="isShow">
<el-slider
v-model="time"
:min="0"
:max="max"
@change="sliderChange"
@input="sliderInput"
@mousedown.native="openVideo"
:show-tooltip="false"
></el-slider>
<div class="d-flex a-center j-sb">
<div class="text-black font-14 font-weight">
{{ sliderTime }}
</div>
<div class="text-black font-14 font-weight">{{ duration }}</div>
</div>
</div>
</el-col>
</el-row>
</template>
<script>
import { timeToSec, timeFomat } from "@/util/util";
export default {
props: {
list: {
type: Array,
default: () => []
},
videoPath: {
type: String
},
msec: {
type: Number
},
hitTimeView: {
type: String
},
isRestore: {
type: Boolean
}
},
data() {
return {
isShow: false,
actionList: [],
currentTime: "00:00", //当前时间
duration: "00:00", //总时长
duration1: 0,
radiusLeft: false,
//视频容器
pvideo: null,
//视频总毫秒叔
videoMs: 0,
//进度条宽度
widthProgress: 0,
//刻度轴加载中
loading: true,
//滑块绑定的值
time: 0,
//time1: 0,
//当时滑块拖动展示的时间
sliderTime: "00:00:000",
//为了获取进度宽度
isShowBar: true,
//虽然不显示视频,但是需要获取视频的一些值,需加载
isShowVideo: false,
vcIsPlay: false,
//是否使用键盘控制
isKeyboard: false,
//进度条最大值
max: 100
};
},
mounted() {
this.keyboardListen();
},
watch: {
list: {
immediate: true,
handler(value) {
this.processData(value);
}
},
msec: {
immediate: true,
handler(value) {
this.msec = value;
let second = this.msec / 1000; //毫秒换算成秒
if (this.pvideo != null) {
let percent = second / this.pvideo.duration; //得出比例
//计算slider滑动的当前时间
let currertTime = 0;
second === 3
? (currertTime = 3)
: (currertTime = this.pvideo.duration * percent);
this.sliderTime = timeFomat(currertTime);
this.time = percent * 100;
}
}
},
hitTimeView: {
immediate: true,
handler(value) {
this.currentTime = value;
}
}
},
methods: {
//显示时触发
showPopover(index) {
//索引传值给父组件
this.$emit("setCurrent", index);
},
//监听键盘
keyboardListen() {
//监听键盘
let that = this;
//键盘按下
document.onkeydown = function(e) {
// 兼容FF和IE和Opera
var theEvent = window.event || e;
var code = theEvent.keyCode || theEvent.which || theEvent.charCode;
//右箭头 39 左箭头 37
if (code == 39) {
if (!that.time) {
that.time = 0;
}
//that.time++;
that.time = that.time + 0.01;
that.isKeyboard = true;
that.sliderChange(that.time);
}
if (code == 37) {
if (!that.time) {
that.time = 0;
}
//that.time--;
that.time = that.time - 0.01;
that.isKeyboard = true;
that.sliderChange(that.time);
}
};
},
//处理数据
async processData(value) {
await this.init();
this.isShow = false;
this.loading = true;
this.actionList = value;
this.actionList.map((item, index) => {
//根据子节点个数计算刻度线的长度
item.children.length <= 5
? (item.ruleHeight = item.children.length * 20 + "px")
: (item.ruleHeight = "100px");
item.msec = timeToSec(item.time);
setTimeout(() => {
item.percent = item.msec / this.videoMs; //得出比例
item.left = item.percent * this.widthProgress + 3 + "px"; //计算距离
}, 2000);
setTimeout(() => {
this.isShow = true;
this.loading = false;
this.$emit("changeRestore", false);
}, 3000);
});
},
//初始化
init() {
this.$nextTick(() => {
let video = document.getElementById("videoSmall");
this.pvideo = video;
let that = this;
video.addEventListener("loadedmetadata", function(e2) {
//加载数据
that.duration = timeFomat(video.duration); //总时长,格式化时间格式后展示
that.videoMs = Math.round(video.duration * 1000); //视频总毫秒数
let progress = document.getElementById("proressBox"); //获取变化进度条的元素
that.widthProgress = progress.offsetWidth; //获取进度条的宽度
});
});
},
//监听滑块值
sliderChange(value) {
if (value) {
this.vcIsPlay = false;
}
//键盘控制使用
if (this.isKeyboard) {
let percent = value / 100;
let currertTime = this.pvideo.duration * percent;
this.sliderTime = timeFomat(currertTime);
this.pvideo.currentTime = percent * this.pvideo.duration;
this.$emit("getCurrentTime", this.pvideo.currentTime);
}
},
sliderInput(value) {
if (this.vcIsPlay) {
let percent = value / 100;
let currertTime = this.pvideo.duration * percent;
this.sliderTime = timeFomat(currertTime);
this.pvideo.currentTime = percent * this.pvideo.duration;
this.$emit("getCurrentTime", this.pvideo.currentTime);
this.time = value; // 进度
if (value == 0) {
this.vcIsPlay = false;
}
}
},
//鼠标按下的时候
openVideo(value) {
if (value) {
this.vcIsPlay = true;
}
}
}
};
</script>
<style lang="scss">
.rule-area {
.el-popover {
background: #303133 !important;
color: #fff !important;
text-align: center !important;
}
}
</style>
<style lang="scss" scoped>
.rule-box {
width: 100%;
height: 120px;
.rule-area {
width: 100%;
height: 120px;
border: 1px solid #ebeef5;
position: relative;
.rule-item {
display: inline-block;
vertical-align: top;
border-right: 3px solid #666;
position: absolute;
cursor: pointer;
}
.item-active {
border-right: 2px solid #1890ff;
}
}
}
.trailer_box {
// width: 100%;
width: 400px;
height: 200px;
padding: 0;
object-fit: cover;
}
.trailer_progress_bar {
width: 100%;
overflow: hidden;
position: relative;
.proress_content_box {
width: 100%;
overflow: hidden;
display: flex;
justify-content: center;
}
}
</style>
使用el-slider滑块 自定义视频进度条
最新推荐文章于 2024-06-23 17:09:38 发布