监控视频回放
This commit is contained in:
		| @@ -3,7 +3,7 @@ | ||||
|     <device-slider :permissions="permissions" :show.sync="slider" :ins="instance" :dict="dict" | ||||
|                    @treeCommand="handleSliderOption" @select="handleSelectMonitor" | ||||
|                    :render-item="renderTreeItem" ref="DeviceSlider"/> | ||||
|     <div class="monitorPane"> | ||||
|     <div class="monitorPane" v-loading="isLoading" element-loading-background="rgba(0, 0, 0, 0.6)"> | ||||
|       <div class="headerBar"> | ||||
|         <el-select default-first-option size="small" v-model="splitScreen" @change="onChange"> | ||||
|           <!-- <i slot="prefix" class="iconfont iconjdq_led_Led1"/> --> | ||||
| @@ -21,10 +21,27 @@ | ||||
|           v-for="(m, i) in monitors" | ||||
|           :key="m.id" | ||||
|           :style="currentSplitStyle"> | ||||
|           <AiMonitor :instance="instance" :deviceId="m.deviceId" :isShowBar="isShowBar" :id="m.id" type="slw" :name="m.name" @close="removeMonitor(i)" ref="AiMonitor"></AiMonitor> | ||||
|           <AiMonitor | ||||
|             :instance="instance" | ||||
|             :deviceId="m.deviceId" | ||||
|             :isShowBar="isShowBar" | ||||
|             :id="m.id" | ||||
|             :playbackUrls="playbackUrls" | ||||
|             :name="m.name" | ||||
|             @close="removeMonitor(i)" | ||||
|             ref="AiMonitor"> | ||||
|           </AiMonitor> | ||||
|         </div> | ||||
|       </div> | ||||
|       <Synergy ref="Synergy" v-if="!isShowBar && monitors.length" style="width: 100%; height: 68px;"></Synergy> | ||||
|       <Synergy | ||||
|         ref="Synergy" | ||||
|         :ids="ids" | ||||
|         :instance="instance" | ||||
|         @replay="onReplay" | ||||
|         @backLiveing="playbackUrls = []" | ||||
|         v-if="!isShowBar && monitors.length" | ||||
|         style="width: 100%; height: 68px;"> | ||||
|       </Synergy> | ||||
|     </div> | ||||
|     <ai-dialog title="修改名称" :visible.sync="dialog" width="500px" @onConfirm="handleSubmit(selected)" | ||||
|                @closed="selected={}"> | ||||
| @@ -69,7 +86,13 @@ | ||||
|         let per = this.splitOps.find(e => e.value == this.splitScreen)?.per || "100%" | ||||
|         return {width: per, height: per} | ||||
|       }, | ||||
|       ...mapState(['user']) | ||||
|       ...mapState(['user']), | ||||
|  | ||||
|       ids () { | ||||
|         if (!this.monitors.length) return '' | ||||
|  | ||||
|         return this.monitors.map(v => v.id).join(',') | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     data() { | ||||
| @@ -80,11 +103,13 @@ | ||||
|         monitors: [], | ||||
|         dialog: false, | ||||
|         locate: false, | ||||
|         isLoading: false, | ||||
|         isShowBar: true, | ||||
|         selected: { | ||||
|           areaId: '' | ||||
|         }, | ||||
|         videoUrl: '', | ||||
|         playbackUrls: [], | ||||
|         latlng: null, | ||||
|         disabledLevel: 0, | ||||
|         rules: { | ||||
| @@ -137,6 +162,27 @@ | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       onReplay (e) { | ||||
|         this.isLoading = true | ||||
|         this.instance.post(`/app/appzyvideoequipment/getSlwPlaybackUrl`, null, { | ||||
|           params: { | ||||
|             ids: this.ids, | ||||
|             startTime: e.startTime, | ||||
|             endTime: e.endTime, | ||||
|             nvrCodes: this.ids | ||||
|           } | ||||
|         }).then(res => { | ||||
|           if (res.code == 0) { | ||||
|             if (res.data && res.data.length) { | ||||
|               this.playbackUrls = res.data | ||||
|               this.isLoading = false | ||||
|             } | ||||
|           } | ||||
|         }).catch(() => { | ||||
|           this.isLoading = false | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       removeMonitor(i) { | ||||
|         this.monitors.splice(i, 1) | ||||
|       }, | ||||
|   | ||||
| @@ -12,7 +12,7 @@ | ||||
|       :id="iframeId" | ||||
|       allow="autoplay *; microphone *; fullscreen *" allowfullscreen allowtransparency key="" allowusermedia frameBorder="no" | ||||
|       style="width: 100%; height: 100%;" | ||||
|       :src="`https://cdn.cunwuyun.cn/slw2.0/index.html?url=${isLiveing ? src : replayUrl}`"> | ||||
|       :src="`https://cdn.cunwuyun.cn/slw2.0/index.html?url=${src}`"> | ||||
|     </iframe> | ||||
|     <div class="slw-bottom" v-if="isShowBar"> | ||||
|       <Timeline class="Timeline" v-if="times.length" :times="times" @replay="onReplay" :isLiveing="isLiveing" :width="width" ref="timeline" :style="{width: width}"></Timeline> | ||||
| @@ -45,9 +45,9 @@ | ||||
|             <div class="live" v-if="isLiveing"> | ||||
|               <span class="label"></span> | ||||
|               <i>直播中</i> | ||||
|               <em>{{ form.date }}</em> | ||||
|               <em>{{ date }}</em> | ||||
|             </div> | ||||
|             <div v-else class="back-btn" @click="backLiving">回到直播</div> | ||||
|             <div v-else class="back-btn" @click="backLiveing">回到直播</div> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div class="right"> | ||||
| @@ -86,7 +86,7 @@ | ||||
|   import Timeline from './Timeline' | ||||
|  | ||||
|   export default { | ||||
|     props: ['name', 'isShowBar', 'instance', 'id', 'deviceId'], | ||||
|     props: ['name', 'isShowBar', 'instance', 'id', 'playbackUrls'], | ||||
|  | ||||
|     name: 'slwVideo', | ||||
|  | ||||
| @@ -105,7 +105,6 @@ | ||||
|         form: { | ||||
|           date: '' | ||||
|         }, | ||||
|         src: '', | ||||
|         isLoading: false, | ||||
|         times: [], | ||||
|         date: '', | ||||
| @@ -115,7 +114,22 @@ | ||||
|         videoId: `slwvideo-${new Date().getTime()}`, | ||||
|         iframeId: `video-${new Date().getTime()}`, | ||||
|         isFullscreen: false, | ||||
|         replayUrl: '' | ||||
|         replayUrl: '', | ||||
|         liveingUrl: '' | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     computed: { | ||||
|       src () { | ||||
|         if (this.playbackUrls.length) { | ||||
|           return this.playbackUrls.filter(v => v.id === this.id)[0].playbackUrl | ||||
|         } | ||||
|  | ||||
|         if (this.isLiveing) { | ||||
|           return this.liveingUrl | ||||
|         } | ||||
|  | ||||
|         return this.replayUrl | ||||
|       } | ||||
|     }, | ||||
|  | ||||
| @@ -129,9 +143,7 @@ | ||||
|               this.isShow = true | ||||
|             }) | ||||
|           } | ||||
|         }, | ||||
|         immediate: true, | ||||
|         deep: true | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|  | ||||
| @@ -155,7 +167,7 @@ | ||||
|         document.removeEventListener('fullscreenchange', this.fullScreenChange) | ||||
|       }, | ||||
|  | ||||
|       backLiving () { | ||||
|       backLiveing () { | ||||
|         this.getLiveingUrl() | ||||
|       }, | ||||
|  | ||||
| @@ -163,7 +175,7 @@ | ||||
|         this.isLoading = true | ||||
|         this.instance.post(`/app/appzyvideoequipment/getWebSdkUrl?deviceId=${this.id}`).then(res => { | ||||
|           if (res.data) { | ||||
|             this.src = res.data | ||||
|             this.liveingUrl = res.data | ||||
|             this.isLiveing = true | ||||
|           } | ||||
|  | ||||
| @@ -179,7 +191,7 @@ | ||||
|           params: { | ||||
|             ids: this.id, | ||||
|             startTime: `${this.form.date} ${e}`, | ||||
|             endTime: this.form.date + ` ${Number(e.substr(0, 2)) + 6 > 9 ? Number(e.substr(0, 2)) + 6 : '0' + (Number(e.substr(0, 2)) + 6)}:59:59`, | ||||
|             endTime: this.form.date + ` ${Number(e.substr(0, 2)) + 6 > 9 ? Number(e.substr(0, 2)) + 6 : '0' + (Number(e.substr(0, 2)) + 6)}:00:00`, | ||||
|             nvrCodes: '' | ||||
|           } | ||||
|         }).then(res => { | ||||
| @@ -259,6 +271,7 @@ | ||||
|       onConfirm () { | ||||
|         this.$refs.form.validate((valid) => { | ||||
|           if (valid) { | ||||
|             this.date = this.form.date | ||||
|             this.isShowDate = false | ||||
|             this.getSlwPlaybackTime() | ||||
|           } | ||||
|   | ||||
							
								
								
									
										134
									
								
								packages/IntelligentSecurity/components/PlaybackTime.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								packages/IntelligentSecurity/components/PlaybackTime.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,134 @@ | ||||
| <template> | ||||
|   <div :class="wrapper" class="canvas" v-if="isInit"> | ||||
|     <canvas | ||||
|       :id="id" | ||||
|       :style="{height: '10px'}" | ||||
|       v-if="canvasWidth" | ||||
|       :width="canvasWidth" | ||||
|       height="10"> | ||||
|     </canvas> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|   export default { | ||||
|     props: ['times'], | ||||
|  | ||||
|     data () { | ||||
|       return { | ||||
|         ctx: null, | ||||
|         canvasWidth: '', | ||||
|         canvasHeight: '', | ||||
|         isInit: false, | ||||
|         wrapper: `canvas-${new Date().getTime()}`, | ||||
|         id: `timeline-${new Date().getTime()}`, | ||||
|         timer: null | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     watch: { | ||||
|       times: { | ||||
|         deep: true, | ||||
|         handler (v) { | ||||
|           if (v.length && this.ctx) { | ||||
|             this.init() | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     mounted () { | ||||
|       this.$nextTick(() => { | ||||
|         this.init() | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     destroyed () { | ||||
|       clearInterval(this.timer) | ||||
|     }, | ||||
|  | ||||
|     methods: { | ||||
|       init () { | ||||
|         this.$nextTick(() => { | ||||
|           this.isInit = true | ||||
|           this.$nextTick(() => { | ||||
|             this.canvasWidth = document.querySelector(`.${this.wrapper}`).offsetWidth | ||||
|             this.canvasHeight = document.querySelector(`.${this.wrapper}`).offsetHeight | ||||
|  | ||||
|             this.$nextTick(() => { | ||||
|               const el = document.querySelector(`#${this.id}`) | ||||
|               this.ctx = el.getContext('2d') | ||||
|               this.ctx.width  = document.querySelector('.canvas').offsetWidth | ||||
|               this.ctx.height  = document.querySelector('.canvas').offsetHeight | ||||
|  | ||||
|               if (this.x > 0) { | ||||
|                 // this.x = this.canvasWidth * this.ratioW | ||||
|               } else { | ||||
|                 // this.initNowTime() | ||||
|               } | ||||
|  | ||||
|               this.renderPlayback() | ||||
|  | ||||
|               // this.countdown() | ||||
|             }) | ||||
|           }) | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       countdown () { | ||||
|         this.timer = setInterval(() => { | ||||
|           if (this.isLiveing) { | ||||
|             this.initNowTime() | ||||
|           } else { | ||||
|             this.x = this.x + this.canvasWidth / (24 * 60 * 60) | ||||
|           } | ||||
|         }, 1000) | ||||
|       }, | ||||
|  | ||||
|       initNowTime () { | ||||
|         const date = new Date() | ||||
|         const seconds = date.getHours() * 3600 + date.getMinutes() * 60 + date.getSeconds() | ||||
|  | ||||
|         this.x = this.canvasWidth / (24 * 60 * 60) * seconds | ||||
|       }, | ||||
|  | ||||
|       drawLine(ctx, options) { | ||||
|         const { beginX, beginY, endX, endY, lineColor, lineWidth } = options | ||||
|         ctx.beginPath() | ||||
|         ctx.lineWidth = lineWidth | ||||
|         ctx.moveTo(beginX, beginY) | ||||
|         ctx.lineTo(endX, endY) | ||||
|         ctx.strokeStyle = lineColor | ||||
|         ctx.stroke() | ||||
|       }, | ||||
|  | ||||
|       renderPlayback () { | ||||
|         const ctx = this.ctx | ||||
|         const unit = this.canvasWidth / (24 * 60 * 60) | ||||
|         this.times.forEach(item => { | ||||
|           this.drawLine(ctx, { | ||||
|             beginX: item.startTime * unit, | ||||
|             beginY: 28, | ||||
|             endX: item.startTime * unit, | ||||
|             endY: 0, | ||||
|             lineColor: 'rgba(0, 156, 255, 1)', | ||||
|             lineWidth: item.endTime * unit - item.startTime * unit | ||||
|           }) | ||||
|         }) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
|   .canvas { | ||||
|     position: relative; | ||||
|     width: 100%; | ||||
|     height: 10px; | ||||
|  | ||||
|     canvas { | ||||
|       width: 100%; | ||||
|       height: 10px; | ||||
|     } | ||||
|   } | ||||
| </style> | ||||
| @@ -1,9 +1,13 @@ | ||||
| <template> | ||||
|   <div class="synergr" :id="videoId" @mousemove.stop="onMousemove" @mouseup="onMouseUp" @mouseleave="isHide = true" v-if="isInit"> | ||||
|   <div class="synergr" :id="videoId" v-if="isInit"> | ||||
|     <canvas | ||||
|       id="canvas" | ||||
|       id="synergr-canvas" | ||||
|       :style="{height: '28px'}" | ||||
|       v-if="canvasWidth" | ||||
|       @click="onClick" | ||||
|       @mousemove.stop="onMousemove" | ||||
|       @mouseup="onMouseUp" | ||||
|       @mouseleave="isHide = true" | ||||
|       :width="canvasWidth" | ||||
|       height="28"> | ||||
|     </canvas> | ||||
| @@ -36,9 +40,9 @@ | ||||
|             <div class="live" v-if="isLiveing"> | ||||
|               <span class="label"></span> | ||||
|               <i>直播中</i> | ||||
|               <em>{{ form.date }}</em> | ||||
|               <em>{{ date }}</em> | ||||
|             </div> | ||||
|             <div v-else class="back-btn" @click="isLiveing = true">回到直播</div> | ||||
|             <div v-else class="back-btn" @click="backLiveing">回到直播</div> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div class="right"> | ||||
| @@ -53,10 +57,10 @@ | ||||
|         <img title="展开" src="https://cdn.cunwuyun.cn/slw2.0/images/arrow.png" /> | ||||
|       </div> | ||||
|       <div class="playback-list" v-if="isShowTimeline"> | ||||
|         <div class="playback-item" v-for="(item, index) in 4" :key="index"> | ||||
|         <div class="playback-item" v-for="(item, index) in times" :key="index"> | ||||
|           <el-checkbox></el-checkbox> | ||||
|           <span>通道{{ index }}</span> | ||||
|           <div class="playback-item__timeline"></div> | ||||
|           <PlaybackTime class="playback-item__timeline" :key="'PlaybackTime' + index" :times="item"></PlaybackTime> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
| @@ -80,15 +84,15 @@ | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|   import Timeline from './Timeline' | ||||
|   import PlaybackTime from './PlaybackTime' | ||||
|  | ||||
|   export default { | ||||
|     props: ['src', 'name', 'isShowBar'], | ||||
|     props: ['ids', 'instance'], | ||||
|  | ||||
|     name: 'slwVideo', | ||||
|     name: 'Synergy', | ||||
|  | ||||
|     components: { | ||||
|       Timeline | ||||
|       PlaybackTime | ||||
|     }, | ||||
|  | ||||
|     data () { | ||||
| @@ -102,6 +106,7 @@ | ||||
|         form: { | ||||
|           date: '' | ||||
|         }, | ||||
|         times: [], | ||||
|         isShowTimeline: false, | ||||
|         checkList: [], | ||||
|         isInit: false, | ||||
| @@ -136,6 +141,8 @@ | ||||
|  | ||||
|     mounted () { | ||||
|       this.form.date = this.$moment(new Date()).format('YYYY-MM-DD') | ||||
|       this.date = this.$moment(new Date()).format('YYYY-MM-DD') | ||||
|       this.getSlwPlaybackTime() | ||||
|       this.$nextTick(() => { | ||||
|         this.init() | ||||
|       }) | ||||
| @@ -143,33 +150,42 @@ | ||||
|  | ||||
|     methods: { | ||||
|       onMousemove (e) { | ||||
|         const canvasInfo = document.querySelector(`#canvas`).getBoundingClientRect() | ||||
|         const canvasInfo = document.querySelector(`#synergr-canvas`).getBoundingClientRect() | ||||
|         const seconds = 24 * 60 * 60 | ||||
|         const x = e.clientX - canvasInfo.left | ||||
|         const unit = seconds / this.canvasWidth * x | ||||
|         this.left = x | ||||
|         this.time = this.secTotime(unit) | ||||
|         this.isHide = false | ||||
|  | ||||
|         if (e.clientY - canvasInfo.top < 29) { | ||||
|           const x = e.clientX - canvasInfo.left | ||||
|           const unit = seconds / this.canvasWidth * x | ||||
|           this.left = x | ||||
|           this.time = this.secTotime(unit) | ||||
|           this.isHide = false | ||||
|  | ||||
|           if (!this.isChoose) return | ||||
|           this.x = e.clientX - canvasInfo.left - 4 | ||||
|           this.ratioW = this.x / this.canvasWidth | ||||
|         } else { | ||||
|           this.isHide = true | ||||
|         } | ||||
|         if (!this.isChoose) return | ||||
|         this.x = e.clientX - canvasInfo.left - 4 | ||||
|         this.ratioW = this.x / this.canvasWidth | ||||
|       }, | ||||
|  | ||||
|       onDragDown () { | ||||
|         this.$emit('pause') | ||||
|         clearInterval(this.timer) | ||||
|         this.timer = null | ||||
|         this.isChoose = true | ||||
|       }, | ||||
|  | ||||
|       backLiveing () { | ||||
|         this.$emit('backLiveing') | ||||
|         this.isLiveing = true | ||||
|         this.initNowTime() | ||||
|       }, | ||||
|  | ||||
|       onMouseUp () { | ||||
|         if (!this.isChoose) return | ||||
|  | ||||
|         clearInterval(this.timer) | ||||
|         this.timer = null | ||||
|         this.isChoose = false | ||||
|         const time = this.secTotime((24 * 60 * 60) / this.canvasWidth * this.x) | ||||
|         this.$emit('replay', { | ||||
|           startTime: `${this.form.date} ${time}`, | ||||
|           endTime: this.form.date + ` ${Number(time.substr(0, 2)) + 6 > 9 ? Number(time.substr(0, 2)) + 6 : '0' + (Number(time.substr(0, 2)) + 6)}:59:59` | ||||
|         }) | ||||
|  | ||||
|         this.isLiveing = false | ||||
|       }, | ||||
|  | ||||
|       init () { | ||||
| @@ -180,7 +196,7 @@ | ||||
|             this.canvasHeight = document.querySelector(`#${this.videoId}`).offsetHeight | ||||
|  | ||||
|             this.$nextTick(() => { | ||||
|               const el = document.querySelector(`#canvas`) | ||||
|               const el = document.querySelector(`#synergr-canvas`) | ||||
|               this.ctx = el.getContext('2d') | ||||
|               this.ctx.width  = document.querySelector(`#${this.videoId}`).offsetWidth | ||||
|               this.ctx.height  = document.querySelector(`#${this.videoId}`).offsetHeight | ||||
| @@ -214,6 +230,19 @@ | ||||
|         ctx.stroke() | ||||
|       }, | ||||
|  | ||||
|       onClick (e) { | ||||
|         const canvasInfo = document.querySelector(`#synergr-canvas`).getBoundingClientRect() | ||||
|         this.x = e.clientX - canvasInfo.left - 4 | ||||
|         clearInterval(this.timer) | ||||
|         this.timer = null | ||||
|         const time = this.secTotime((24 * 60 * 60) / this.canvasWidth * this.x) | ||||
|         this.$emit('replay', { | ||||
|           startTime: `${this.form.date} ${time}`, | ||||
|           endTime: this.form.date + ` ${Number(time.substr(0, 2)) + 6 > 9 ? Number(time.substr(0, 2)) + 6 : '0' + (Number(time.substr(0, 2)) + 6)}:00:00` | ||||
|         }) | ||||
|         this.isLiveing = false | ||||
|       }, | ||||
|  | ||||
|       renderTimeLine () { | ||||
|         const ctx = this.ctx | ||||
|         ctx.fillStyle = 'rgba(40, 43, 58, 1)' | ||||
| @@ -253,35 +282,67 @@ | ||||
|       }, | ||||
|  | ||||
|       secTotime (s) { | ||||
|         var t = '' | ||||
|         if(s > -1){ | ||||
|           var hour = Math.floor(s / 3600) | ||||
|           var min = Math.floor(s / 60) % 60 | ||||
|           var sec = s % 60 | ||||
|           if(hour < 10) { | ||||
|             t = '0'+ hour + ":" | ||||
|           } else {  | ||||
|             t = hour + ":" | ||||
|           }  | ||||
|           if(min < 10){ | ||||
|             t += "0" | ||||
|           }  | ||||
|           t += min + ":" | ||||
|           if(sec < 10){ | ||||
|             t += "0" | ||||
|           }  | ||||
|           t += sec.toFixed(0) | ||||
|         }  | ||||
|         return t | ||||
|         let second = parseInt(s) | ||||
|         let minute = 0 | ||||
|         let hour = 0 | ||||
|         if (second > 60) { | ||||
|           minute = parseInt(second / 60) | ||||
|           second = parseInt(second % 60) | ||||
|           if (minute > 60) { | ||||
|             hour = parseInt(minute / 60) | ||||
|             minute = parseInt(minute % 60) | ||||
|           } | ||||
|         } | ||||
|  | ||||
|         hour = `${parseInt(hour) > 9 ? parseInt(hour) : '0' + parseInt(hour)}` | ||||
|         minute = `${parseInt(minute) > 9 ? parseInt(minute) : '0' + parseInt(minute)}` | ||||
|         second = `${parseInt(second) > 9 ? parseInt(second) : '0' + parseInt(second)}` | ||||
|         return `${hour}:${minute}:${second}` | ||||
|       }, | ||||
|  | ||||
|       onConfirm () { | ||||
|         this.$refs.form.validate((valid) => { | ||||
|           if (valid) { | ||||
|             this.isShowDate = false | ||||
|             this.date = this.form.date | ||||
|             this.getSlwPlaybackTime() | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       getSlwPlaybackTime () { | ||||
|         this.isLoading = true | ||||
|         this.instance.post(`/app/appzyvideoequipment/getSlwPlaybackTime`, null, { | ||||
|           params: { | ||||
|             ids: this.ids, | ||||
|             startTime: this.date + ' 00:00:00', | ||||
|             endTime: this.date + ' 23:59:59', | ||||
|           } | ||||
|         }).then(res => { | ||||
|           if (res.code == 0) { | ||||
|             if (res.data && res.data.length) { | ||||
|               this.times = res.data.map(v => { | ||||
|                 return v.times.map(item => { | ||||
|                   const startTime = (item.startTime - new Date(this.date + ' 00:00:00').getTime()) / 1000 | ||||
|                   const endTime = (item.endTime - new Date(this.date + ' 00:00:00').getTime()) / 1000 | ||||
|  | ||||
|                   return { | ||||
|                     startTime: Number(startTime.toFixed(0)), | ||||
|                     endTime: Number(endTime.toFixed(0)) | ||||
|                   } | ||||
|                 }).sort((a, b) => { | ||||
|                   return a.startTime - b.startTime | ||||
|                 }) | ||||
|               }) | ||||
|             } | ||||
|  | ||||
|             this.isLoading = false | ||||
|           } | ||||
|         }).catch(() => { | ||||
|           this.isLoading = false | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       onVolume (e) { | ||||
|         const v = (e / 100).toFixed(1) | ||||
|         const subPage = document.querySelector(`#${this.id}`).contentWindow | ||||
| @@ -356,9 +417,8 @@ | ||||
|  | ||||
|           .playback-item__timeline { | ||||
|             flex: 1; | ||||
|             height: 8px; | ||||
|             height: 12px; | ||||
|             border-radius: 6px; | ||||
|             background: linear-gradient(180deg, #00CBFF 0%, #009CFF 100%); | ||||
|           } | ||||
|  | ||||
|           span { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user