From 9b9a13ab36fe93153148a489436e04b12aabcdd6 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: 星期一, 09 一月 2023 16:31:51 +0800 Subject: [PATCH] 国标录像UI重构 --- web_src/static/css/iconfont.woff2 | 0 web_src/src/components/console.vue | 13 web_src/src/components/channelList.vue | 4 web_src/src/components/dialog/devicePlayer.vue | 291 ------------------- web_src/src/components/GBRecordDetail.vue | 495 +++++++++++++++++++++++++++++++++ src/main/java/com/genersoft/iot/vmp/conf/ApiAccessFilter.java | 4 web_src/src/components/console/ConsoleResource.vue | 12 web_src/src/router/index.js | 6 web_src/static/css/iconfont.css | 14 web_src/src/components/CloudRecordDetail.vue | 17 + 10 files changed, 551 insertions(+), 305 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/conf/ApiAccessFilter.java b/src/main/java/com/genersoft/iot/vmp/conf/ApiAccessFilter.java index 5f4ac22..d1e61c0 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/ApiAccessFilter.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/ApiAccessFilter.java @@ -10,6 +10,7 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; +import org.springframework.util.ObjectUtils; import org.springframework.web.filter.OncePerRequestFilter; import javax.servlet.*; @@ -51,6 +52,9 @@ LogDto logDto = new LogDto(); logDto.setName(uriName); + if (ObjectUtils.isEmpty(username)) { + username = ""; + } logDto.setUsername(username); logDto.setAddress(servletRequest.getRemoteAddr()); logDto.setResult(HttpStatus.valueOf(servletResponse.getStatus()).toString()); diff --git a/web_src/src/components/CloudRecordDetail.vue b/web_src/src/components/CloudRecordDetail.vue index 143448e..8d04eb0 100644 --- a/web_src/src/components/CloudRecordDetail.vue +++ b/web_src/src/components/CloudRecordDetail.vue @@ -30,7 +30,7 @@ </el-aside> <el-main style="padding: 22px"> <div class="playBox" :style="playerStyle"> - <player ref="recordVideoPlayer" :videoUrl="videoUrl" fluent autoplay :height="true" ></player> + <player ref="recordVideoPlayer" :videoUrl="videoUrl" :height="true" style="width: 100%" ></player> </div> <div class="player-option-box" > <el-slider @@ -310,7 +310,20 @@ let h = parseInt(val/3600); let m = parseInt((val - h*3600)/60); let s = parseInt(val - h*3600 - m*60); - return h + ":" + m + ":" + s + + let hStr = h; + let mStr = m; + let sStr = s; + if (h < 10) { + hStr = "0" + hStr; + } + if (m < 10) { + mStr = "0" + mStr;s + } + if (s < 10) { + sStr = "0" + sStr; + } + return hStr + ":" + mStr + ":" + sStr }, deleteRecord(){ // TODO diff --git a/web_src/src/components/GBRecordDetail.vue b/web_src/src/components/GBRecordDetail.vue new file mode 100644 index 0000000..feb2443 --- /dev/null +++ b/web_src/src/components/GBRecordDetail.vue @@ -0,0 +1,495 @@ +<template> + <div style="width: 100%"> + <div class="page-header" > + <div class="page-title"> + <el-page-header @back="goBack" content="鍥芥爣褰曞儚"></el-page-header> + </div> + </div> + <el-container> + <el-aside width="300px"> + <div class="record-list-box-box"> + <el-date-picker size="mini" v-model="chooseDate" type="date" value-format="yyyy-MM-dd" placeholder="鏃ユ湡" @change="dateChange()"></el-date-picker> + <div class="record-list-box" v-loading="recordsLoading" :style="recordListStyle"> + <ul v-if="detailFiles.length >0" class="infinite-list record-list" > + <li v-for="item in detailFiles" class="infinite-list-item record-list-item" > + + <el-tag v-if="chooseFile != item" @click="checkedFile(item)"> + <i class="el-icon-video-camera" ></i> + {{ moment(item.startTime).format('HH:mm:ss')}}-{{ moment(item.endTime).format('HH:mm:ss')}} + </el-tag> + <el-tag v-if="chooseFile == item" type="danger" > + <i class="el-icon-video-camera" ></i> + {{ moment(item.startTime).format('HH:mm:ss')}}-{{ moment(item.endTime).format('HH:mm:ss')}} + </el-tag> + <i style="color: #409EFF;margin-left: 5px;" class="el-icon-download" @click="downloadRecord(item)" ></i> + </li> + </ul> + </div> + <div size="mini" v-if="detailFiles.length ==0" class="record-list-no-val" >鏆傛棤鏁版嵁</div> + </div> + + </el-aside> + <el-main style="padding-bottom: 10px;"> + <div class="playBox" :style="playerStyle"> + <player ref="recordVideoPlayer" + :videoUrl="videoUrl" + :error="videoError" + :message="videoError" + :hasAudio="hasAudio" + style="max-height: 100%" + fluent autoplay live ></player> + </div> + <div class="player-option-box"> + <div> + <el-button-group > + <el-button size="mini" class="iconfont icon-zanting" title="寮�濮�" @click="gbPause()"></el-button> + <el-button size="mini" class="iconfont icon-kaishi" title="鏆傚仠" @click="gbPlay()"></el-button> + <el-dropdown size="mini" title="鎾斁鍊嶉��" style="margin-left: 1px;" @command="gbScale"> + <el-button size="mini"> + 鍊嶉�� <i class="el-icon-arrow-down el-icon--right"></i> + </el-button> + <el-dropdown-menu slot="dropdown"> + <el-dropdown-item command="0.25">0.25鍊嶉��</el-dropdown-item> + <el-dropdown-item command="0.5">0.5鍊嶉��</el-dropdown-item> + <el-dropdown-item command="1.0">1鍊嶉��</el-dropdown-item> + <el-dropdown-item command="2.0">2鍊嶉��</el-dropdown-item> + <el-dropdown-item command="4.0">4鍊嶉��</el-dropdown-item> + </el-dropdown-menu> + </el-dropdown> + <el-button size="mini" class="iconfont icon-xiazai1" title="涓嬭浇閫夊畾褰曞儚" @click="downloadRecord()"></el-button> + <el-button v-if="sliderMIn === 0 && sliderMax === 86400" size="mini" class="iconfont icon-slider" title="鏀惧ぇ婊戝潡" @click="setSliderFit()"></el-button> + <el-button v-if="sliderMIn !== 0 || sliderMax !== 86400" size="mini" class="iconfont icon-slider-right" title="鎭㈠婊戝潡" @click="setSliderFit()"></el-button> + </el-button-group> + </div> + <el-slider + class="playtime-slider" + v-model="playTime" + id="playtimeSlider" + :disabled="detailFiles.length === 0" + :min="sliderMIn" + :max="sliderMax" + :range="true" + :format-tooltip="playTimeFormat" + @change="playTimeChange" + :marks="playTimeSliderMarks"> + </el-slider> + <div class="slider-val-box"> + <div class="slider-val" v-for="item of detailFiles" :style="'width:' + getDataWidth(item) + '%; left:' + getDataLeft(item) + '%'"></div> + </div> + </div> + + </el-main> + </el-container> + <recordDownload ref="recordDownload"></recordDownload> + </div> +</template> + + +<script> + import uiHeader from '../layout/UiHeader.vue' + import player from './common/jessibuca.vue' + import moment from 'moment' + import recordDownload from './dialog/recordDownload.vue' + export default { + name: 'app', + components: { + uiHeader, player,recordDownload + }, + data() { + return { + deviceId: this.$route.params.deviceId, + channelId: this.$route.params.channelId, + recordsLoading: false, + sliderTime: 0, + seekTime: 0, + recordStartTime: 0, + streamId: "", + hasAudio: false, + detailFiles: [], + chooseDate: null, + videoUrl: null, + chooseFile: null, + streamInfo: null, + app: null, + mediaServerId: null, + ssrc: null, + + sliderMIn: 0, + sliderMax: 86400, + autoPlay: true, + taskUpdate: null, + tabVal: "running", + recordListStyle: { + height: this.winHeight + "px", + overflow: "auto", + margin: "10px auto 10px auto" + }, + playerStyle: { + "margin": "0 auto 20px auto", + "height": this.winHeight + "px", + }, + winHeight: window.innerHeight - 240, + playTime: 0, + playTimeSliderMarks: { + 0: "00:00", + 3600: "01:00", + 7200: "02:00", + 10800: "03:00", + 14400: "04:00", + 18000: "05:00", + 21600: "06:00", + 25200: "07:00", + 28800: "08:00", + 32400: "09:00", + 36000: "10:00", + 39600: "11:00", + 43200: "12:00", + 46800: "13:00", + 50400: "14:00", + 54000: "15:00", + 57600: "16:00", + 61200: "17:00", + 64800: "18:00", + 68400: "19:00", + 72000: "20:00", + 75600: "21:00", + 79200: "22:00", + 82800: "23:00", + 86400: "24:00", + }, + }; + }, + computed: { + + }, + mounted() { + this.recordListStyle.height = this.winHeight + "px"; + this.playerStyle["height"] = this.winHeight + "px"; + this.chooseDate = moment().format('YYYY-MM-DD') + this.dateChange(); + }, + destroyed() { + this.$destroy('recordVideoPlayer'); + }, + methods: { + dateChange(){ + if (!this.chooseDate) { + return; + } + this.recordsLoading = true; + this.detailFiles = []; + let startTime = this.chooseDate + " 00:00:00"; + let endTime = this.chooseDate + " 23:59:59"; + this.$axios({ + method: 'get', + url: '/api/gb_record/query/' + this.deviceId + '/' + this.channelId + '?startTime=' + startTime + '&endTime=' + endTime + }).then((res)=>{ + this.recordsLoading = false; + if(res.data.code === 0) { + // 澶勭悊鏃堕棿淇℃伅 + this.detailFiles = res.data.data.recordList; + + }else { + this.$message({ + showClose: true, + message: res.data.msg, + type: "error", + }); + } + + }).catch((e)=> { + this.recordsLoading = false; + // that.videoHistory.searchHistoryResult = falsificationData.recordData; + }); + }, + moment: function (v) { + return moment(v) + }, + videoError: function (e) { + console.log("鎾斁鍣ㄩ敊璇細" + JSON.stringify(e)); + }, + checkedFile(file){ + this.chooseFile = file; + // 寮�濮嬪洖鏀� + this.playRecord(file) + + }, + playRecord: function (row) { + + let startTime = row.startTime + this.recordStartTime = row.startTime + this.showTimeText = row.startTime.split(" ")[1] + let endTime = row.endTime + this.sliderTime = 0; + this.seekTime = new Date(endTime).getTime() - new Date(startTime).getTime(); + if (this.streamId !== "") { + this.stopPlayRecord(()=> { + this.streamId = ""; + this.playRecord(row); + }) + } else { + this.$axios({ + method: 'get', + url: '/api/playback/start/' + this.deviceId + '/' + this.channelId + '?startTime=' + startTime + '&endTime=' + + endTime + }).then((res)=> { + if (res.data.code === 0) { + this.streamInfo = res.data.data; + this.app = this.streamInfo.app; + this.streamId = this.streamInfo.stream; + this.mediaServerId = this.streamInfo.mediaServerId; + this.ssrc = this.streamInfo.ssrc; + this.videoUrl = this.getUrlByStreamInfo(); + }else { + this.$message({ + showClose: true, + message: res.data.msg, + type: "error", + }); + } + }); + } + }, + gbPlay(){ + console.log('鍓嶇鎺у埗锛氭挱鏀�'); + this.$axios({ + method: 'get', + url: '/api/playback/resume/' + this.streamId + }).then((res)=> { + this.$refs[this.activePlayer].play(this.videoUrl) + }); + }, + gbPause(){ + console.log('鍓嶇鎺у埗锛氭殏鍋�'); + this.$axios({ + method: 'get', + url: '/api/playback/pause/' + this.streamId + }).then(function (res) {}); + }, + gbScale(command){ + console.log('鍓嶇鎺у埗锛氬�嶉�� ' + command); + this.$axios({ + method: 'get', + url: `/api/playback/speed/${this.streamId }/${command}` + }).then(function (res) {}); + }, + downloadRecord: function (row) { + if (!row) { + let startTimeStr = moment(new Date(this.chooseDate + " 00:00:00").getTime() + this.playTime[0]*1000).format("YYYY-MM-DD HH:mm:ss"); + let endTimeStr = moment(new Date(this.chooseDate + " 00:00:00").getTime() + this.playTime[1]*1000).format("YYYY-MM-DD HH:mm:ss"); + console.log(startTimeStr); + console.log(endTimeStr); + row = { + startTime: startTimeStr, + endTime: endTimeStr + } + } + if (this.streamId !== "") { + this.stopPlayRecord(()=> { + this.streamId = ""; + this.downloadRecord(row); + }) + }else { + this.$axios({ + method: 'get', + url: '/api/gb_record/download/start/' + this.deviceId + '/' + this.channelId + '?startTime=' + row.startTime + '&endTime=' + + row.endTime + '&downloadSpeed=4' + }).then( (res)=> { + if (res.data.code === 0) { + let streamInfo = res.data.data; + this.$refs.recordDownload.openDialog(this.deviceId, this.channelId, streamInfo.app, streamInfo.stream, streamInfo.mediaServerId); + }else { + this.$message({ + showClose: true, + message: res.data.msg, + type: "error", + }); + } + }); + } + }, + stopDownloadRecord: function (callback) { + this.$refs["recordVideoPlayer"].pause(); + this.videoUrl = ''; + this.$axios({ + method: 'get', + url: '/api/gb_record/download/stop/' + this.deviceId + "/" + this.channelId+ "/" + this.streamId + }).then((res)=> { + if (callback) callback(res) + }); + }, + stopPlayRecord: function (callback) { + this.$refs["recordVideoPlayer"].pause(); + this.videoUrl = ''; + this.$axios({ + method: 'get', + url: '/api/playback/stop/' + this.deviceId + "/" + this.channelId + "/" + this.streamId + }).then(function (res) { + if (callback) callback() + }); + }, + getDataWidth(item){ + let timeForFile = this.getTimeForFile(item); + let result = (timeForFile[2])/((this.sliderMax - this.sliderMIn)*1000) + return result*100 + }, + getDataLeft(item){ + let timeForFile = this.getTimeForFile(item); + let differenceTime = timeForFile[0].getTime() - new Date(this.chooseDate + " 00:00:00").getTime() + return parseFloat((differenceTime - this.sliderMIn * 1000)/((this.sliderMax - this.sliderMIn)*1000))*100 ; + }, + getUrlByStreamInfo(){ + if (location.protocol === "https:") { + this.videoUrl = this.streamInfo["wss_flv"] + }else { + this.videoUrl = this.streamInfo["ws_flv"] + } + return this.videoUrl; + + }, + playTimeChange(val){ + console.log(val) + let maxTime = this.getTimeForFile(this.detailFiles[this.detailFiles.length - 1])[1]; + + let startTimeStr = moment(new Date(this.chooseDate + " 00:00:00").getTime() + val[0]*1000).format("YYYY-MM-DD HH:mm:ss"); + let endTimeStr = moment(new Date(this.chooseDate + " 00:00:00").getTime() + val[1]*1000).format("YYYY-MM-DD HH:mm:ss"); + console.log(startTimeStr); + console.log(endTimeStr); + + this.checkedFile({ + startTime: startTimeStr, + endTime: endTimeStr, + }); + }, + setSliderFit() { + if (this.sliderMIn === 0 && this.sliderMax === 86400) { + if (this.detailFiles.length > 0){ + let timeForFile = this.getTimeForFile(this.detailFiles[0]); + let lastTimeForFile = this.getTimeForFile(this.detailFiles[this.detailFiles.length - 1]); + let timeNum = timeForFile[0].getTime() - new Date(this.chooseDate + " " + "00:00:00").getTime() + let lastTimeNum = lastTimeForFile[1].getTime() - new Date(this.chooseDate + " " + "00:00:00").getTime() + + this.playTime = parseInt(timeNum/1000) + this.sliderMIn = parseInt(timeNum/1000 - timeNum/1000%(60*60)) + this.sliderMax = parseInt(lastTimeNum/1000 - lastTimeNum/1000%(60*60)) + 60*60 + + this.playTime = [this.sliderMIn, this.sliderMax]; + } + }else { + this.sliderMIn = 0; + this.sliderMax = 86400; + } + }, + getTimeForFile(file){ + let startTime = new Date(file.startTime); + let endTime = new Date(file.endTime); + return [startTime, endTime, endTime.getTime() - startTime.getTime()]; + }, + playTimeFormat(val){ + let h = parseInt(val/3600); + let m = parseInt((val - h*3600)/60); + let s = parseInt(val - h*3600 - m*60); + + let hStr = h; + let mStr = m; + let sStr = s; + if (h < 10) { + hStr = "0" + hStr; + } + if (m < 10) { + mStr = "0" + mStr;s + } + if (s < 10) { + sStr = "0" + sStr; + } + return hStr + ":" + mStr + ":" + sStr + }, + goBack(){ + window.history.go(-1); + } + } + }; +</script> + +<style> + .el-slider__runway { + background-color:rgba(206, 206, 206, 0.47) !important; + } + .el-slider__bar { + background-color: rgba(153, 153, 153, 0) !important; + } + .playtime-slider { + position: relative; + z-index: 100; + } + .data-picker-true{ + + } + .data-picker-true:after{ + content: ""; + position: absolute; + width: 4px; + height: 4px; + background-color: #606060; + border-radius: 4px; + left: 45%; + top: 74%; + + } + .data-picker-false{ + + } + .slider-val-box{ + height: 6px; + position: relative; + top: -22px; + } + .slider-val{ + height: 6px; + background-color: #007CFF; + position: absolute; + } + .record-list-box-box{ + width: 250px; + float: left; + } + .record-list-box{ + overflow: auto; + width: 220px; + list-style: none; + padding: 0; + margin: 0; + margin-top: 0px; + padding: 1rem 0; + background-color: #FFF; + margin-top: 10px; + } + .record-list{ + list-style: none; + padding: 0; + margin: 0; + background-color: #FFF; + + } + .record-list-no-val { + position: absolute; + color: #9f9f9f; + top: 50%; + left: 110px; + } + .record-list-item{ + padding: 0; + margin: 0; + margin: 0.5rem 0; + cursor: pointer; + } + .record-list-option { + width: 10px; + float: left; + margin-top: 39px; + + } + .player-option-box{ + padding: 0 20px; + } +</style> diff --git a/web_src/src/components/channelList.vue b/web_src/src/components/channelList.vue index 136ddfe..f020f34 100644 --- a/web_src/src/components/channelList.vue +++ b/web_src/src/components/channelList.vue @@ -269,10 +269,10 @@ }); }, queryRecords: function (itemData) { - var format = moment().format("yyyy-MM-DD"); let deviceId = this.deviceId; let channelId = itemData.channelId; - this.$refs.devicePlayer.openDialog("record", deviceId, channelId, {date: format}) + + this.$router.push(`/gbRecordDetail/${deviceId}/${channelId}`) }, stopDevicePush: function (itemData) { var that = this; diff --git a/web_src/src/components/console.vue b/web_src/src/components/console.vue index 6e2dd83..e192fb1 100644 --- a/web_src/src/components/console.vue +++ b/web_src/src/components/console.vue @@ -101,11 +101,14 @@ window.clearTimeout(this.timer); } this.timer = setTimeout(()=>{ - this.getSystemInfo(); - this.getLoad(); - this.timer = null; - this.loopForSystemInfo() - this.getResourceInfo() + if (this.$route.path === "/console") { + this.getSystemInfo(); + this.getLoad(); + this.timer = null; + this.loopForSystemInfo() + this.getResourceInfo() + } + }, 2000) }, getSystemInfo: function (){ diff --git a/web_src/src/components/console/ConsoleResource.vue b/web_src/src/components/console/ConsoleResource.vue index bc307b9..3aa7771 100644 --- a/web_src/src/components/console/ConsoleResource.vue +++ b/web_src/src/components/console/ConsoleResource.vue @@ -1,28 +1,32 @@ <template > <div id="consoleResource" style="width: 100%; height: 100%; background: #FFFFFF; text-align: center"> <div style="width: 50%;height: 50%; float:left; "> - <el-progress :width="100" :stroke-width="8" type="circle" :percentage="Math.floor(deviceInfo.online/deviceInfo.total*100)" style="margin-top: 20px; font-size: 18px"></el-progress> + <el-progress v-if="deviceInfo.total > 0" :width="100" :stroke-width="8" type="circle" :percentage="Math.floor(deviceInfo.online/deviceInfo.total*100)" style="margin-top: 20px; font-size: 18px"></el-progress> + <el-progress v-if="deviceInfo.total === 0" :width="100" :stroke-width="8" type="circle" :percentage="0" style="margin-top: 20px; font-size: 18px"></el-progress> <div class="resourceInfo"> 璁惧鎬绘暟:{{deviceInfo.total}}<br/> 鍦ㄧ嚎鏁�:{{deviceInfo.online}} </div> </div> <div style="width: 50%;height: 50%; float:left; "> - <el-progress :width="100" :stroke-width="10" type="circle" :percentage="Math.floor(channelInfo.online/channelInfo.total*100)" style="margin-top: 20px"></el-progress> + <el-progress v-if="channelInfo.total > 0" :width="100" :stroke-width="10" type="circle" :percentage="Math.floor(channelInfo.online/channelInfo.total*100)" style="margin-top: 20px"></el-progress> + <el-progress v-if="channelInfo.total === 0" :width="100" :stroke-width="10" type="circle" :percentage="0" style="margin-top: 20px"></el-progress> <div class="resourceInfo"> 閫氶亾鎬绘暟:{{channelInfo.total}}<br/> 鍦ㄧ嚎鏁�:{{channelInfo.online}} </div> </div> <div style="width: 50%;height: 50%; float:left; "> - <el-progress :width="100" :stroke-width="10" type="circle" :percentage="Math.floor(pushInfo.online/pushInfo.total*100)" style="margin-top: 20px"></el-progress> + <el-progress v-if="pushInfo.total > 0" :width="100" :stroke-width="10" type="circle" :percentage="Math.floor(pushInfo.online/pushInfo.total*100)" style="margin-top: 20px"></el-progress> + <el-progress v-if="pushInfo.total === 0" :width="100" :stroke-width="10" type="circle" :percentage="0" style="margin-top: 20px"></el-progress> <div class="resourceInfo"> 鎺ㄦ祦鎬绘暟:{{pushInfo.total}}<br/> 鍦ㄧ嚎鏁�:{{pushInfo.online}} </div> </div> <div style="width: 50%;height: 50%; float:left; "> - <el-progress :width="100" :stroke-width="10" type="circle" :percentage="Math.floor(proxyInfo.online/proxyInfo.total*100)" style="margin-top: 20px"></el-progress> + <el-progress v-if="proxyInfo.total > 0" :width="100" :stroke-width="10" type="circle" :percentage="Math.floor(proxyInfo.online/proxyInfo.total*100)" style="margin-top: 20px"></el-progress> + <el-progress v-if="proxyInfo.total === 0" :width="100" :stroke-width="10" type="circle" :percentage="0" style="margin-top: 20px"></el-progress> <div class="resourceInfo"> 鎷夋祦浠g悊鎬绘暟:{{proxyInfo.total}}<br/> 鍦ㄧ嚎鏁�:{{proxyInfo.online}} diff --git a/web_src/src/components/dialog/devicePlayer.vue b/web_src/src/components/dialog/devicePlayer.vue index 9ecbb9b..e83a29c 100644 --- a/web_src/src/components/dialog/devicePlayer.vue +++ b/web_src/src/components/dialog/devicePlayer.vue @@ -23,11 +23,6 @@ <div id="shared" style="text-align: right; margin-top: 1rem;"> <el-tabs v-model="tabActiveName" @tab-click="tabHandleClick" > <el-tab-pane label="瀹炴椂瑙嗛" name="media"> - <div style="margin-bottom: 0.5rem;"> - <!-- <el-button type="primary" size="small" @click="playRecord(true, '')">鎾斁</el-button>--> - <!-- <el-button type="primary" size="small" @click="startRecord()">褰曞埗</el-button>--> - <!-- <el-button type="primary" size="small" @click="stopRecord()">鍋滄褰曞埗</el-button>--> - </div> <div style="display: flex; margin-bottom: 0.5rem; height: 2.5rem;"> <span style="width: 5rem; line-height: 2.5rem; text-align: right;">鎾斁鍦板潃锛�</span> <el-input v-model="getPlayerShared.sharedUrl" :disabled="true" > @@ -148,51 +143,6 @@ </div> </el-tab-pane> <!--{"code":0,"data":{"paths":["22-29-30.mp4"],"rootPath":"/home/kkkkk/Documents/ZLMediaKit/release/linux/Debug/www/record/hls/kkkkk/2020-05-11/"}}--> - <el-tab-pane label="褰曞儚鏌ヨ" name="record" v-if="showRrecord"> - <div style="width: 100%;"> - <div style="width: 100%; text-align: left"> - <span>褰曞儚鎺у埗</span> - <el-button-group style="margin-left: 1rem;"> - <el-button size="mini" class="iconfont icon-zanting" title="寮�濮�" @click="gbPause()"></el-button> - <el-button size="mini" class="iconfont icon-kaishi" title="鏆傚仠" @click="gbPlay()"></el-button> - <el-dropdown size="mini" title="鎾斁鍊嶉��" style="margin-left: 1px;" @command="gbScale"> - <el-button size="mini"> - 鍊嶉�� <i class="el-icon-arrow-down el-icon--right"></i> - </el-button> - <el-dropdown-menu slot="dropdown"> - <el-dropdown-item command="0.25">0.25鍊嶉��</el-dropdown-item> - <el-dropdown-item command="0.5">0.5鍊嶉��</el-dropdown-item> - <el-dropdown-item command="1.0">1鍊嶉��</el-dropdown-item> - <el-dropdown-item command="2.0">2鍊嶉��</el-dropdown-item> - <el-dropdown-item command="4.0">4鍊嶉��</el-dropdown-item> - </el-dropdown-menu> - </el-dropdown> - </el-button-group> - <el-date-picker style="float: right;" size="mini" v-model="videoHistory.date" type="date" value-format="yyyy-MM-dd" placeholder="鏃ユ湡" @change="queryRecords()"></el-date-picker> - </div> - <div style="width: 100%; text-align: left"> - <span class="demonstration" style="padding: 12px 36px 12px 0;float: left;">{{showTimeText}}</span> - <el-slider style="width: 80%; float:left;" v-model="sliderTime" @change="gbSeek" :show-tooltip="false"></el-slider> - </div> - </div> - - - <el-table :data="videoHistory.searchHistoryResult" height="150" v-loading="recordsLoading"> - <el-table-column label="鍚嶇О" prop="name"></el-table-column> - <el-table-column label="鏂囦欢" prop="filePath"></el-table-column> - <el-table-column label="寮�濮嬫椂闂�" prop="startTime" :formatter="timeFormatter"></el-table-column> - <el-table-column label="缁撴潫鏃堕棿" prop="endTime" :formatter="timeFormatter"></el-table-column> - - <el-table-column label="鎿嶄綔"> - <template slot-scope="scope"> - <el-button-group> - <el-button icon="el-icon-video-play" size="mini" @click="playRecord(scope.row)">鎾斁</el-button> - <el-button icon="el-icon-download" size="mini" @click="downloadRecord(scope.row)">涓嬭浇</el-button> - </el-button-group> - </template> - </el-table-column> - </el-table> - </el-tab-pane> <!--閬ユ帶鐣岄潰--> <el-tab-pane label="浜戝彴鎺у埗" name="control" v-if="showPtz"> <div style="display: flex; justify-content: left;"> @@ -286,21 +236,18 @@ </el-tabs> </div> </el-dialog> - <recordDownload ref="recordDownload"></recordDownload> </div> </template> <script> import rtcPlayer from '../dialog/rtcPlayer.vue' import LivePlayer from '@liveqing/liveplayer' -// import player from '../dialog/easyPlayer.vue' import jessibucaPlayer from '../common/jessibuca.vue' -import recordDownload from '../dialog/recordDownload.vue' export default { name: 'devicePlayer', props: {}, components: { - LivePlayer, jessibucaPlayer, rtcPlayer, recordDownload, + LivePlayer, jessibucaPlayer, rtcPlayer, }, computed: { getPlayerShared: function () { @@ -328,10 +275,6 @@ livePlayer : ["ws_flv", "wss_flv"], webRTC: ["rtc", "rtcs"], }, - videoHistory: { - date: '', - searchHistoryResult: [] //濯掍綋娴佸巻鍙茶褰曟悳绱㈢粨鏋� - }, showVideoDialog: false, streamId: '', app : '', @@ -357,7 +300,6 @@ tracks: [], coverPlaying:false, tracksLoading: false, - recordPlay: "", showPtz: true, showRrecord: true, tracksNotLoaded: false, @@ -418,11 +360,6 @@ case "media": this.play(param.streamInfo, param.hasAudio) break; - case "record": - this.showVideoDialog = true; - this.videoHistory.date = param.date; - this.queryRecords() - break; case "streamPlay": this.tabActiveName = "media"; this.showRrecord = false; @@ -432,9 +369,6 @@ case "control": break; } - }, - timeAxisSelTime: function (val) { - console.log(val) }, play: function (streamInfo, hasAudio) { this.streamInfo = streamInfo; @@ -531,10 +465,6 @@ this.convertStop(); } this.convertKey = '' - if (this.recordPlay != '') { - this.stopPlayRecord(); - } - this.recordPlay = '' }, copySharedInfo: function (data) { @@ -558,137 +488,6 @@ }); } ); - }, - - queryRecords: function () { - if (!this.videoHistory.date) { - return; - } - this.recordsLoading = true; - this.videoHistory.searchHistoryResult = []; - let that = this; - var startTime = this.videoHistory.date + " 00:00:00"; - var endTime = this.videoHistory.date + " 23:59:59"; - this.$axios({ - method: 'get', - url: '/api/gb_record/query/' + this.deviceId + '/' + this.channelId + '?startTime=' + startTime + '&endTime=' + endTime - }).then(function (res) { - console.log(res) - that.recordsLoading = false; - if(res.data.code === 0) { - // 澶勭悊鏃堕棿淇℃伅 - that.videoHistory.searchHistoryResult = res.data.data.recordList; - }else { - this.$message({ - showClose: true, - message: res.data.msg, - type: "error", - }); - } - - }).catch(function (e) { - console.log(e.message); - // that.videoHistory.searchHistoryResult = falsificationData.recordData; - }); - - }, - onTimeChange: function (video) { - // this.queryRecords() - }, - playRecord: function (row) { - let that = this; - - let startTime = row.startTime - this.recordStartTime = row.startTime - this.showTimeText = row.startTime.split(" ")[1] - let endtime = row.endTime - this.sliderTime = 0; - this.seekTime = new Date(endtime).getTime() - new Date(startTime).getTime(); - console.log(this.seekTime) - if (that.streamId != "") { - that.stopPlayRecord(function () { - that.streamId = ""; - that.playRecord(row); - }) - } else { - this.$axios({ - method: 'get', - url: '/api/playback/start/' + this.deviceId + '/' + this.channelId + '?startTime=' + row.startTime + '&endTime=' + - row.endTime - }).then(function (res) { - if (res.data.code === 0) { - that.streamInfo = res.data.data; - that.app = that.streamInfo.app; - that.streamId = that.streamInfo.stream; - that.mediaServerId = that.streamInfo.mediaServerId; - that.ssrc = that.streamInfo.ssrc; - that.videoUrl = that.getUrlByStreamInfo(); - }else { - that.$message({ - showClose: true, - message: res.data.msg, - type: "error", - }); - } - that.recordPlay = true; - }); - } - }, - stopPlayRecord: function (callback) { - this.$refs[this.activePlayer].pause(); - this.videoUrl = ''; - this.$axios({ - method: 'get', - url: '/api/playback/stop/' + this.deviceId + "/" + this.channelId + "/" + this.streamId - }).then(function (res) { - if (callback) callback() - }); - }, - downloadRecord: function (row) { - let that = this; - if (that.streamId != "") { - that.stopDownloadRecord(function (res) { - if (res.code == 0) { - that.streamId = ""; - that.downloadRecord(row); - }else { - this.$message({ - showClose: true, - message: res.data.msg, - type: "error", - }); - } - - }) - } else { - this.$axios({ - method: 'get', - url: '/api/gb_record/download/start/' + this.deviceId + '/' + this.channelId + '?startTime=' + row.startTime + '&endTime=' + - row.endTime + '&downloadSpeed=4' - }).then(function (res) { - if (res.data.code == 0) { - let streamInfo = res.data.data; - that.recordPlay = false; - that.$refs.recordDownload.openDialog(that.deviceId, that.channelId, streamInfo.app, streamInfo.stream, streamInfo.mediaServerId); - }else { - that.$message({ - showClose: true, - message: res.data.msg, - type: "error", - }); - } - }); - } - }, - stopDownloadRecord: function (callback) { - this.$refs[this.activePlayer].pause(); - this.videoUrl = ''; - this.$axios({ - method: 'get', - url: '/api/gb_record/download/stop/' + this.deviceId + "/" + this.channelId+ "/" + this.streamId - }).then((res)=> { - if (callback) callback(res) - }); }, ptzCamera: function (command) { console.log('浜戝彴鎺у埗锛�' + command); @@ -728,52 +527,6 @@ url: '/api/ptz/front_end_command/' + this.deviceId + '/' + this.channelId + '?cmdCode=' + cmdCode + '¶meter1=' + groupNum + '¶meter2=' + parameter + '&combindCode2=0' }).then(function (res) {}); }, - formatTooltip: function (val) { - var h = parseInt(val / 60); - var hStr = h < 10 ? ("0" + h) : h; - var s = val % 60; - var sStr = s < 10 ? ("0" + s) : s; - return h + ":" + sStr; - }, - timeFormatter: function (row, column, cellValue, index) { - return cellValue.split(" ")[1]; - }, - mergeTime: function (timeArray) { - var resultArray = []; - for (let i = 0; i < timeArray.length; i++) { - var startTime = new Date(timeArray[i].startTime); - var endTime = new Date(timeArray[i].endTime); - if (i == 0) { - resultArray[0] = { - startTime: startTime, - endTime: endTime - } - } - for (let j = 0; j < resultArray.length; j++) { - if (startTime > resultArray[j].endTime) { // 鍚堝苟 - if (startTime - resultArray[j].endTime <= 1000) { - resultArray[j].endTime = endTime; - } else { - resultArray[resultArray.length] = { - startTime: startTime, - endTime: endTime - } - } - } else if (resultArray[j].startTime > endTime) { // 鍚堝苟 - if (resultArray[j].startTime - endTime <= 1000) { - resultArray[j].startTime = startTime; - } else { - resultArray[resultArray.length] = { - startTime: startTime, - endTime: endTime - } - } - } - } - } - console.log(resultArray) - return resultArray; - }, copyUrl: function (dropdownItem){ console.log(dropdownItem) this.$copyText(dropdownItem).then((e)=> { @@ -782,47 +535,7 @@ }) }, - gbPlay(){ - console.log('鍓嶇鎺у埗锛氭挱鏀�'); - this.$axios({ - method: 'get', - url: '/api/playback/resume/' + this.streamId - }).then((res)=> { - this.$refs[this.activePlayer].play(this.videoUrl) - }); - }, - gbPause(){ - console.log('鍓嶇鎺у埗锛氭殏鍋�'); - this.$axios({ - method: 'get', - url: '/api/playback/pause/' + this.streamId - }).then(function (res) {}); - }, - gbScale(command){ - console.log('鍓嶇鎺у埗锛氬�嶉�� ' + command); - this.$axios({ - method: 'get', - url: `/api/playback/speed/${this.streamId }/${command}` - }).then(function (res) {}); - }, - gbSeek(val){ - console.log('鍓嶇鎺у埗锛歴eek '); - console.log(this.seekTime); - console.log(this.sliderTime); - let showTime = new Date(new Date(this.recordStartTime).getTime() + this.seekTime * val / 100) - let hour = showTime.getHours(); - let minutes = showTime.getMinutes(); - let seconds = showTime.getSeconds(); - this.showTimeText = (hour < 10?("0" + hour):hour) + ":" + (minutes<10?("0" + minutes):minutes) + ":" + (seconds<10?("0" + seconds):seconds) - this.$axios({ - method: 'get', - url: `/api/playback/seek/${this.streamId }/` + Math.floor(this.seekTime * val / 100000) - }).then( (res)=> { - setTimeout(()=>{ - this.$refs[this.activePlayer].play(this.videoUrl) - }, 600) - }); - }, + } diff --git a/web_src/src/router/index.js b/web_src/src/router/index.js index 4844d64..23c0a82 100644 --- a/web_src/src/router/index.js +++ b/web_src/src/router/index.js @@ -5,6 +5,7 @@ import console from '../components/console.vue' import deviceList from '../components/DeviceList.vue' import channelList from '../components/channelList.vue' +import gbRecordDetail from '../components/GBRecordDetail.vue' import pushVideoList from '../components/PushVideoList.vue' import streamProxyList from '../components/StreamProxyList.vue' import map from '../components/map.vue' @@ -65,6 +66,11 @@ component: channelList, }, { + path: '/gbRecordDetail/:deviceId/:channelId/', + name: 'gbRecordDetail', + component: gbRecordDetail, + }, + { path: '/parentPlatformList/:count/:page', name: 'parentPlatformList', component: parentPlatformList, diff --git a/web_src/static/css/iconfont.css b/web_src/static/css/iconfont.css index a09b98e..4636a73 100644 --- a/web_src/static/css/iconfont.css +++ b/web_src/static/css/iconfont.css @@ -1,8 +1,8 @@ @font-face { font-family: "iconfont"; /* Project id 1291092 */ - src: url('iconfont.woff2?t=1655453611360') format('woff2'), - url('iconfont.woff?t=1655453611360') format('woff'), - url('iconfont.ttf?t=1655453611360') format('truetype'); + src: url('iconfont.woff2?t=1673251105600') format('woff2'), + url('iconfont.woff?t=1673251105600') format('woff'), + url('iconfont.ttf?t=1673251105600') format('truetype'); } .iconfont { @@ -13,6 +13,14 @@ -moz-osx-font-smoothing: grayscale; } +.icon-slider:before { + content: "\e7e0"; +} + +.icon-slider-right:before { + content: "\ea19"; +} + .icon-list:before { content: "\e7de"; } diff --git a/web_src/static/css/iconfont.woff2 b/web_src/static/css/iconfont.woff2 index c2fdf69..f1cb24c 100644 --- a/web_src/static/css/iconfont.woff2 +++ b/web_src/static/css/iconfont.woff2 Binary files differ -- Gitblit v1.8.0