src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/record/GBRecordController.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
web_src/src/components/dialog/devicePlayer.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
web_src/static/css/iconfont.css | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
web_src/static/css/iconfont.woff2 | 补丁 | 查看 | 原始文档 | blame | 历史 |
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/record/GBRecordController.java
@@ -56,17 +56,21 @@ } Device device = storager.queryVideoDevice(deviceId); cmder.recordInfoQuery(device, channelId, startTime, endTime); // 指定超时时间 1分钟30秒 DeferredResult<ResponseEntity<RecordInfo>> result = new DeferredResult<>(90*1000L); String uuid = UUID.randomUUID().toString(); String key = DeferredResultHolder.CALLBACK_CMD_RECORDINFO + deviceId + channelId; RequestMessage msg = new RequestMessage(); msg.setId(uuid); msg.setKey(key); cmder.recordInfoQuery(device, channelId, startTime, endTime, (eventResult -> { msg.setData("查询录像失败, status: " + eventResult.statusCode + ", message: " + eventResult.msg ); resultHolder.invokeResult(msg); })); // 录像查询以channelId作为deviceId查询 resultHolder.put(key, uuid, result); result.onTimeout(()->{ RequestMessage msg = new RequestMessage(); msg.setId(uuid); msg.setKey(key); msg.setData("timeout"); resultHolder.invokeResult(msg); }); web_src/src/components/dialog/devicePlayer.vue
@@ -39,7 +39,30 @@ </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"> <el-date-picker size="mini" v-model="videoHistory.date" type="date" value-format="yyyy-MM-dd" placeholder="日期" @change="queryRecords()"></el-date-picker> <div style="float: 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="播放倍速" @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> </div> <el-date-picker size="mini" v-model="videoHistory.date" type="date" value-format="yyyy-MM-dd" placeholder="日期" @change="queryRecords()"></el-date-picker> <div class="block" > <span class="demonstration" style="padding: 12px 36px 12px 0;float: left;">{{Math.floor(seekTime * sliderTime / 100000)}}秒</span> <el-slider style="width: 80%; float:left;" v-model="sliderTime" @change="gbSeek" :show-tooltip="false"></el-slider> </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> @@ -210,6 +233,8 @@ showPtz: true, showRrecord: true, tracksNotLoaded: false, sliderTime: 0, seekTime: 0, }; }, methods: { @@ -433,6 +458,11 @@ }, playRecord: function (row) { let that = this; let startTime = row.startTime let endtime = row.endTime this.seekTime = new Date(endtime).getTime() - new Date(startTime).getTime(); console.log(this.seekTime) if (that.streamId != "") { that.stopPlayRecord(function () { that.streamId = "", @@ -580,7 +610,40 @@ } console.log(resultArray) return resultArray; }, gbPlay(){ console.log('前端控制:播放'); this.$axios({ method: 'get', url: '/api/playback/resume/' + this.streamId }).then((res)=> { this.$refs.videoPlayer.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('前端控制:seek '); console.log(this.seekTime); console.log(this.sliderTime); this.$axios({ method: 'get', url: `/api/playback/seek/${this.streamId }/` + Math.floor(this.seekTime * val / 100000) }).then(function (res) {}); } } }; </script> web_src/static/css/iconfont.css
@@ -1,8 +1,8 @@ @font-face { font-family: "iconfont"; /* Project id 1291092 */ src: url('iconfont.woff2?t=1631767887536') format('woff2'), url('iconfont.woff?t=1631767887536') format('woff'), url('iconfont.ttf?t=1631767887536') format('truetype'); src: url('iconfont.woff2?t=1637741914969') format('woff2'), url('iconfont.woff?t=1637741914969') format('woff'), url('iconfont.ttf?t=1637741914969') format('truetype'); } .iconfont { @@ -13,6 +13,226 @@ -moz-osx-font-smoothing: grayscale; } .icon-suoxiao:before { content: "\e79a"; } .icon-shanchu3:before { content: "\e79b"; } .icon-chehui:before { content: "\e79c"; } .icon-wenben:before { content: "\e79d"; } .icon-zhongzuo:before { content: "\e79e"; } .icon-jianqie:before { content: "\e79f"; } .icon-fangda:before { content: "\e7a0"; } .icon-fangdazhanshi:before { content: "\e7a1"; } .icon-qianjin:before { content: "\e7a2"; } .icon-kuaijin:before { content: "\e7a3"; } .icon-diyigeshipin:before { content: "\e7a4"; } .icon-kuaitui:before { content: "\e7a5"; } .icon-kaishi:before { content: "\e7a7"; } .icon-zuihouyigeshipin:before { content: "\e7a8"; } .icon-zanting:before { content: "\e7a9"; } .icon-zhankai:before { content: "\e7aa"; } .icon-bendisucai:before { content: "\e7ab"; } .icon-luzhi:before { content: "\e7ac"; } .icon-ossziyuan:before { content: "\e7ad"; } .icon-chuangjianzhinengfenxirenwu:before { content: "\e7ae"; } .icon-sousuo3:before { content: "\e7af"; } .icon-gengduo:before { content: "\e7b0"; } .icon-tianjia:before { content: "\e7b1"; } .icon-xiazai:before { content: "\e7b2"; } .icon-biaojibeifen:before { content: "\e7b3"; } .icon-bendisucaibeifen:before { content: "\e7b4"; } .icon-luzhibeifen:before { content: "\e7b5"; } .icon-ossziyuanbeifen:before { content: "\e7b6"; } .icon-bianji3:before { content: "\e7b7"; } .icon-cuti:before { content: "\e7b8"; } .icon-xieti:before { content: "\e7b9"; } .icon-xiahuaxian:before { content: "\e7ba"; } .icon-wuxiaoguo:before { content: "\e7bb"; } .icon-sousuo4:before { content: "\e7bc"; } .icon-gouwuche:before { content: "\e7bd"; } .icon-shuaxin2:before { content: "\e7be"; } .icon-xiaoxi:before { content: "\e7bf"; } .icon-wushouquan:before { content: "\e7c0"; } .icon-tishi2:before { content: "\e7c1"; } .icon-tishi1:before { content: "\e7c2"; } .icon-shouquanchenggong:before { content: "\e7c3"; } .icon-sousuo5:before { content: "\e7c4"; } .icon-shuaxin3:before { content: "\e7c5"; } .icon-xiazai1:before { content: "\e7c6"; } .icon-shangchuan:before { content: "\e7c7"; } .icon-guanbi:before { content: "\e7c8"; } .icon-wangye-loading:before { content: "\e7c9"; } .icon-bianzubeifen3:before { content: "\e7ca"; } .icon-xingzhuangbeifen:before { content: "\e7cb"; } .icon-bianzubeifen:before { content: "\e7cc"; } .icon-zhuanchang:before { content: "\e7cd"; } .icon-meizi:before { content: "\e7ce"; } .icon-daimabeifen:before { content: "\e7cf"; } .icon-suoxiao1:before { content: "\e7d0"; } .icon-ai19:before { content: "\e799"; } .icon-online:before { content: "\e600"; } web_src/static/css/iconfont.woff2Binary files differ