国标平台EasyGBS支持用户根据自己的需求自由进行二次开发,即便是试用版本也支持调用二次开发接口,接口丰富全面,可以满足大多数用户的需求。
本文我们要讲的是二次开发中的录像轴组件,由于有用户问到,所以讲一下这个组件是怎么使用的。
1.在项目导入PlayTimeAxis.vue组件
代码语言:javascript复制import PlayTimeAxis from "./PlayTimeAxis.vue";
export default {
components: {
PlayTimeAxis
}
}
2.在项目中引入PlayTimeAxis组件。组件中有两个属性videos是用来接收录像段,然后展示接收到对应的时间段录像。timeChange是返回点击某一点时间的回调。
videos需要传入一个数组对象,格式如下:
代码语言:javascript复制let videos = [{
currentVideoIndex: 0,
dayTime: "20210603",
duration: 9367,
endAt: "2021-06-03T02:37:29",
hmsTime: "0:1:22",
startAt: "2021-06-03T00:01:22",
}]
timeChange会返回一个对象,格式如下:
onTimeChange(data) {
//data 的数据格式
// {
// currentTime: 862,
// currentVideoIndex: 20,
// dayTime: "20210606",
// duration: 1127,
// endAt: "2021-06-06T11:42:25",
// hmsTime: "11:23:38",
// startAt: "2021-06-06T11:23:38",
// }
}
<PlayTimeAxis :videos="videos" @timeChange="onTimeChange">
</PlayTimeAxis>
PlayTimeAxis.vue组件完整代码:
代码语言:javascript复制<template>
<div class="time-rule">
<div class="time-day" ref="day" :style="{ left: timeDayX 'px'}">
<div :class="['time-minute', minuteActiveClass(n - 1)]" :title="minuteTitle(n - 1)" v-for="n in 1440"
:key="n"
@click.prevent="clickMinute(n - 1)"></div>
<div :class="[ n==1 ? 'time-text-first' : 'time-text']" v-for="n in 24" :key="n">{{hourText(n - 1)}}</div>
</div>
<div class="time-cursor" :style="{ left: timeCursorX 'px'}" ref="cursor">
<div class="time-cursor-text">{{timeCursorText}}</div>
</div>
</div>
</template>
<script>
import moment from 'moment'
export default {
data() {
return {
timeCursorX: 0,
timeDayX: 0,
bMoving: false,
}
},
props: {
videos: {
type: Array,
default: []
}
},
mounted() {
let cursor = this.$refs.cursor;
let day = this.$refs.day;
let rule = this.$el;
let _this = this;
function moveCursor(e) {
let originPageX = $(cursor).data("originPageX");
let dx = e.pageX - originPageX;
_this.timeCursorX = $(cursor).position().left dx;
$(cursor).data("originPageX", e.pageX);
}
function touchMoveCursor(e) {
let touch = e.originalEvent.targetTouches[0];
let originPageX = $(cursor).data("originPageX");
let dx = touch.pageX - originPageX;
_this.timeCursorX = $(cursor).position().left dx;
$(cursor).data("originPageX", touch.pageX);
}
function moveDay(e) {
let originPageX = $(day).data("originPageX");
let dx = e.pageX - originPageX;
_this.timeDayX = $(day).position().left dx;
$(day).data("originPageX", e.pageX);
}
function touchMoveDay(e) {
let touch = e.originalEvent.targetTouches[0];
let originPageX = $(day).data("originPageX");
let dx = touch.pageX - originPageX;
_this.timeDayX = $(day).position().left dx;
$(day).data("originPageX", touch.pageX);
}
$(cursor).on("mousedown", function (e) {
$(cursor).data("originPageX", e.pageX);
_this.bMoving = true;
$(document).on("mousemove", moveCursor).one("mouseup", function (e) {
$(document).off("mousemove", moveCursor);
$(cursor).removeData("originPageX");
_this.triggerTimeChange();
_this.bMoving = false;
})
}).on("touchstart", function (e) {
let touch = e.originalEvent.targetTouches[0];
$(cursor).data("originPageX", touch.pageX);
_this.bMoving = true;
$(document).on("touchmove", touchMoveCursor).one("touchend", function (e) {
$(document).off("touchmove", touchMoveCursor);
$(cursor).removeData("originPageX");
_this.triggerTimeChange();
_this.bMoving = false;
})
})
$(day).on("mousedown", function (e) {
$(day).data("originPageX", e.pageX);
_this.bMoving = true;
$(document).on("mousemove", moveDay).one("mouseup", function (e) {
$(document).off("mousemove", moveDay);
$(day).removeData("originPageX");
_this.triggerTimeChange(1);
_this.bMoving = false;
})
}).on("touchstart", function (e) {
let touch = e.originalEvent.targetTouches[0];
$(day).data("originPageX", touch.pageX);
_this.bMoving = true;
$(document).on("touchmove", touchMoveDay).one("touchend", function (e) {
$(document).off("touchmove", touchMoveDay);
$(day).removeData("originPageX");
_this.triggerTimeChange();
_this.bMoving = false;
})
})
},
watch: {
videos: function (val) {
this.triggerTimeChange();
}
},
methods: {
hourText(n) {
let h = moment().hour(n).minute(0).second(0);
return h.format("HH:mm");
},
minuteActiveClass(n) {
let m = moment().hour(0).minute(n);
let mtext = m.format("HH:mm");
return Object.keys(this.activeMinutes).indexOf(mtext) >= 0 ? "active" : "";
},
minuteTitle(n) {
let m = moment().hour(0).minute(n);
let mtext = m.format("HH:mm");
return Object.keys(this.activeMinutes).indexOf(mtext) >= 0 ? mtext : "";
},
clickMinute(n, bTrigger = true) {
if (this.bMoving) return;
this.timeCursorX = n this.timeDayX;
if (bTrigger) {
this.triggerTimeChange();
}
},
dataTime(value) { //'01:01:60' out:Number
let arr = value.split(':').map((i) => {
return i
});
return ((arr[0] * 60 * 60) (arr[1] * 60) (arr[2]));
},
triggerTimeChange(r) {
if (r === 1) return
this.$emit("timeChange", this.activeMinutes[this.timeCursorText]);
}
},
computed: {
timeCursorText() {
if (this.timeCursorX >= $(this.$el).innerWidth()) {
this.timeCursorX = $(this.$el).innerWidth() - 1;
}
if (this.timeCursorX < 0) {
this.timeCursorX = 0;
}
if (this.timeDayX < $(this.$el).innerWidth() - $(this.$refs.day).outerWidth()) {
this.timeDayX = $(this.$el).innerWidth() - $(this.$refs.day).outerWidth();
}
if (this.timeDayX > 0) {
this.timeDayX = 0;
}
if (this.timeCursorX - this.timeDayX >= 1440) {
this.timeDayX = $(this.$el).innerWidth() - $(this.$refs.day).outerWidth();
this.timeCursorX = $(this.$el).innerWidth() - 1;
}
if (this.timeCursorX === 0) {
let lenTx = this.videos.length
if (lenTx !== 0) {
lenTx = lenTx - 1
let strTx = this.videos[lenTx].endAt
strTx = strTx.substring(strTx.length - 8);
let entTx = this.dataTime(strTx)
this.timeCursorX = entTx * 100 / 6000 - 60000
}
}
var m = moment().hour(0).minute(this.timeCursorX - this.timeDayX);
return m.format("HH:mm");
},
activeMinutes() {
let minutes = {};
for (let video of this.videos) {
let m = moment(video.startAt, "YYYYMMDDHHmmss");
let s = parseInt(video.duration);
if (s > 8640000) {
this.$message({
type: 'error',
message: "录像" video.start_time "时间戳错误"
})
continue
}
let mtext = m.format("HH:mm");
minutes[mtext] = Object.assign({
currentTime: 0
}, video);
for (let i = 1; i <= s; i ) {
m.add(1, "seconds");
let _mtext = m.format("HH:mm");
if (_mtext != mtext) {
mtext = _mtext;
minutes[mtext] = Object.assign({
currentTime: i
}, video);
}
}
}
return minutes;
}
}
}
</script>
<style lang="less" scoped>
.time-rule {
overflow: hidden;
position: relative;
height: 50px;
margin: 0 auto;
width: 100%;
font-size: 12px;
max-width: 1440px;
background-color: #e5e5e5;
}
.time-day {
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 1440px;
cursor: pointer;
-ms-user-select: none;
user-select: none;
}
.time-minute {
float: left;
width: 1px;
height: 8px;
margin: 0;
cursor: default;
}
.time-minute.active {
background-color: red;
cursor: pointer;
}
.time-text {
float: left;
width: 60px;
border-left: 1px solid #999;
border-top: 1px solid #999;
box-sizing: border-box;
-ms-user-select: none;
user-select: none;
text-align: center;
height: 25px;
line-height: 25px;
}
.time-text-first {
.time-text;
border-left: 0;
}
.time-cursor {
position: absolute;
left: 0;
top: 0;
height: 30px;
width: 2px;
background-color: red;
text-align: center;
}
.time-cursor-text {
position: absolute;
padding: 0 5px;
width: 60px;
left: -30px;
top: 30px;
border: 1px solid red;
height: 15px;
line-height: 15px;
cursor: move;
background-color: white;
-ms-user-select: none;
user-select: none;
}
</style>