基于LivePlayer的录像回放页面

在视频播放中,少不了录像回放功能。其回放功能进行接口调用暂且不谈,主要记录下包含回放条的录像回放页面。

html



	
		
		录像回放窗口
		
		
		
	
	
		
{{cameraData.address}} {{cameraData.name}}( {{cameraData.main_channel}} )
时间:

js

/**
 * 录像回放窗口
 * @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

/**
 * 录像回放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 */
}

效果

基于LivePlayer的录像回放页面_第1张图片

你可能感兴趣的:(javascript,html,vue)