国标GB28181协议视频平台EasyGBS二次开发过程中如何使用录像轴组件?
国标平台EasyGBS支持用户根据自己的需求自由进行二次开发,即便是试用版本也支持调用二次开发接口,接口丰富全面,可以满足大多数用户的需求。
本文我们要讲的是二次开发中的录像轴组件,由于有用户问到,所以讲一下这个组件是怎么使用的。
1.在项目导入PlayTimeAxis.vue组件
import PlayTimeAxis from "./PlayTimeAxis.vue"; export default { components: { PlayTimeAxis } }
2.在项目中引入PlayTimeAxis组件。组件中有两个属性videos是用来接收录像段,然后展示接收到对应的时间段录像。timeChange是返回点击某一点时间的回调。
videos需要传入一个数组对象,格式如下:
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组件完整代码:
<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>