在视频播放中,少不了录像回放功能。其回放功能进行接口调用暂且不谈,主要记录下包含回放条的录像回放页面。
录像回放窗口
{{cameraData.address}} {{cameraData.name}}( {{cameraData.main_channel}} )
时间:
/**
* 录像回放窗口
* @author chenbin
*
*/
var cameraData = url.getUrlParms("record");
cameraData = JSON.parse(cameraData);
var startDate = new Date(); //开始时间
startDate.setHours(0);
startDate.setMinutes(0);
startDate.setSeconds(0);
var endDate = new Date(); //结束时间
var vm = new Vue({
el: "#videoTape",
data: {
cameraData: cameraData,
timerange: [
startDate,
endDate
],
videos: [],
video: null,
videoUrl: "",
streamID: "",
day:Format.dateFormat(new Date(),"YYYY/MM/DD"),
timeCursorX: 0,
timeDayX: 0,
bMoving: false,
minutesArr:[],
minutesPerUnit: 5
},
watch: {
videos: function(val) {
this.triggerTimeChange();
},
video: function(newVal, oldVal) {
if (newVal && newVal != oldVal) {
this.startPlayback();
} else {
this.stopPlayback();
}
},
day:function(newVal, oldVal){
if(newVal != oldVal){
var start = new Date(newVal);
start.setHours(0);
start.setMinutes(0);
start.setSeconds(0);
var end = new Date(newVal);
end.setHours(23);
end.setMinutes(59);
end.setSeconds(59);
this.timerange = [
start,
end
]
this.getRecords(true);
}
},
minutesArr:function(val){
var today = new Date();
var day = new Date(this.day);
if(day.getDate() != today.getDate()){
var time = 0;
if(this.minutesArr.length>0){
time = Math.min.apply(null, this.minutesArr) + 5;
}
this.timeCursorText = time;
}else{
var h = today.getHours();
var m = today.getMinutes();
this.timeCursorText = h * 60 + m - 10;
}
this.triggerTimeChange();
}
},
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) {
if ($(e.target).hasClass("time-minute")) {
return false;
}
$(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();
_this.bMoving = false;
})
}).on("touchstart", function(e) {
if ($(e.target).hasClass("time-minute")) {
return false;
}
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;
})
})
let mmt = moment();
let n = mmt.diff(mmt.clone().startOf('day'), 'minutes');
n -= 10;
if (n < 0) n = 0;
this.clickMinute(n);
this.getRecords(true);
},
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();
}
},
triggerTimeChange() {
this.onTimeChange(this.activeMinutes[this.timeCursorText]);
},
onTimeChange(video) {
this.video = video;
},
getRecords(refresh) {
if (refresh) {
this.videos = [];
}
var p = {
serial: this.cameraData.main_channel,
starttime: moment(this.timerange[0]).format("YYYY-MM-DDTHH:mm:ss"),
endtime: moment(this.timerange[1]).format("YYYY-MM-DDTHH:mm:ss")
}
Live.videotape.list(cameraData.nvr_id, p, function(e) {
var items = e.RecordList || [];
vm.videos = vm.videos.concat(items.filter(item => {
if (!item || !item.StartTime || !item.EndTime) {
return false;
}
return true;
}));
})
},
stopPlayback() {
if(comm.isEmpty(this.streamID)){
return;
}
Live.videotape.stopPlay(this.cameraData.nvr_id, {
streamid: this.streamID
}, function(e) {
vm.streamID = "";
vm.videoUrl = "";
});
},
startPlayback() {
var p = {
serial: this.video.DeviceID,
starttime: this.video.StartTime,
endtime: this.video.EndTime
}
if(!comm.isEmpty(this.streamID)){
Live.videotape.stopPlay(this.cameraData.nvr_id, {
streamid: this.streamID
}, function(e) {
vm.streamID = "";
vm.videoUrl = "";
Live.videotape.startPlay(this.cameraData.nvr_id, p, function(e) {
vm.streamID = e.StreamID;
vm.videoUrl = e.WS_FLV;
})
});
}else{
Live.videotape.startPlay(this.cameraData.nvr_id, p, function(e) {
vm.streamID = e.StreamID;
vm.videoUrl = e.WS_FLV;
})
}
},
countTime(str){
var times = str.split(":");
var t = parseInt(times[0]) * 60 + parseInt(times[1]);
return t;
},
countPosition(){
let this_ = this;
setTimeout(function(){
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;
}
},100)
}
},
computed: {
timeCursorText: {
get:function(){
this.countPosition();
var mx = parseInt((this.timeCursorX - this.timeDayX) / this.minutesPerUnit) * this.minutesPerUnit;
var m = moment().hour(0).minute(mx);
return m.format("HH:mm");
},
set:function(time){
this.timeCursorX = time;
}
},
activeMinutes() {
var minutes = {};
var minArr = [];
var idx = 0;
for (var video of this.videos) {
var start = moment(video.StartTime, "YYYY-MM-DDTHH:mm:ss");
var end = moment(video.EndTime, "YYYY-MM-DDTHH:mm:ss");
if (!start.isSame(end, "day")) { // 跨天
if (idx == 0) {
start = moment(end).startOf("day");
} else {
end = moment(start).endOf("day");
}
}
var _start = moment(start).startOf("hour");
for (var i = 0;; i += 5) {
var c = moment(_start).add(i, "minute");
if (c.isBefore(start, "minute")) {
continue;
}
if (c.isAfter(end, "minute")) {
break;
}
var mtext = c.format("HH:mm");
minArr.push(this.countTime(mtext));
minutes[mtext] = Object.assign({}, video, {
StartTime: c.format("YYYY-MM-DDTHH:mm:ss")
});
}
idx++;
}
this.minutesArr = minArr;
return minutes;
}
}
})
layui.use('laydate', function() {
var laydate = layui.laydate;
var nowDate = Format.dateFormat(new Date(), "YYYY-MM-DD");
//常规用法
laydate.render({
elem: '#dateTime',
value: nowDate,
showBottom: false,
max: nowDate,
done: function(value, date, endDate) {
vm.day = value.replace(/-/g,"/");
}
});
})
/**
* 录像回放css
*/
.time-rule {
overflow: hidden;
position: relative;
height: 50px;
margin: 0 auto;
width: 100%;
font-size: 12px;
max-width: 1440px;
background-color: #CCC;
}
.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;
height: 8px;
margin: 0;
cursor: default;
}
.time-minute.active {
background-color: #556677;
cursor: pointer;
}
.time-text {
float: left;
width: 60px;
border-left: 1px solid #999;
border-top: 1px solid #999;
-ms-user-select: none;
user-select: none;
text-align: center;
height: 25px;
line-height: 25px;
}
.time-text-first {
border-left: 0;
float: left;
width: 60px;
border-top: 1px solid #999;
-ms-user-select: none;
user-select: none;
text-align: center;
height: 25px;
line-height: 25px;
}
.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;
}
.box-div{
box-sizing:border-box;
-moz-box-sizing:border-box; /* Firefox */
-webkit-box-sizing:border-box; /* Safari */
}