视频回放
This commit is contained in:
		| @@ -21,7 +21,7 @@ | ||||
|           v-for="(m, i) in monitors" | ||||
|           :key="m.id" | ||||
|           :style="currentSplitStyle"> | ||||
|           <AiMonitor :isShowBar="isShowBar" :src="m.url" type="slw" :name="m.name" @close="removeMonitor(i)" ref="AiMonitor"></AiMonitor> | ||||
|           <AiMonitor :instance="instance" :deviceId="m.deviceId" :isShowBar="isShowBar" :id="m.id" type="slw" :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> | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| <template> | ||||
|   <div class="slw" :id="videoId"> | ||||
|   <div class="slw" :id="videoId" v-loading="isLoading" element-loading-background="rgba(0, 0, 0, 0.6)"> | ||||
|     <div class="slw-title"> | ||||
|       <h2>{{ name }}</h2> | ||||
|       <div class="slw-title__close" @click="removeMonitor"> | ||||
| @@ -9,13 +9,13 @@ | ||||
|     </div> | ||||
|     <iframe | ||||
|       v-if="isShow" | ||||
|       :id="id" | ||||
|       :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=${src}`"> | ||||
|       :src="`https://cdn.cunwuyun.cn/slw2.0/index.html?url=${isLiveing ? src : replayUrl}`"> | ||||
|     </iframe> | ||||
|     <div class="slw-bottom" v-if="isShowBar"> | ||||
|       <Timeline class="Timeline" @pause="isLiveing = false" :isLiveing="isLiveing" :width="width" ref="timeline" :style="{width: width}"></Timeline> | ||||
|       <Timeline class="Timeline" v-if="times.length" :times="times" @replay="onReplay" :isLiveing="isLiveing" :width="width" ref="timeline" :style="{width: width}"></Timeline> | ||||
|       <div class="action-bar"> | ||||
|         <div class="left"> | ||||
|           <div class="left-btns"> | ||||
| @@ -47,7 +47,7 @@ | ||||
|               <i>直播中</i> | ||||
|               <em>{{ form.date }}</em> | ||||
|             </div> | ||||
|             <div v-else class="back-btn" @click="isLiveing = true">回到直播</div> | ||||
|             <div v-else class="back-btn" @click="backLiving">回到直播</div> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div class="right"> | ||||
| @@ -86,7 +86,7 @@ | ||||
|   import Timeline from './Timeline' | ||||
|  | ||||
|   export default { | ||||
|     props: ['src', 'name', 'isShowBar'], | ||||
|     props: ['name', 'isShowBar', 'instance', 'id', 'deviceId'], | ||||
|  | ||||
|     name: 'slwVideo', | ||||
|  | ||||
| @@ -105,13 +105,17 @@ | ||||
|         form: { | ||||
|           date: '' | ||||
|         }, | ||||
|         src: '', | ||||
|         isLoading: false, | ||||
|         times: [], | ||||
|         date: '', | ||||
|         isPause: false, | ||||
|         width: '', | ||||
|         volume: 100, | ||||
|         videoId: `slwvideo-${new Date().getTime()}`, | ||||
|         id: `video-${new Date().getTime()}`, | ||||
|         isFullscreen: false | ||||
|         iframeId: `video-${new Date().getTime()}`, | ||||
|         isFullscreen: false, | ||||
|         replayUrl: '' | ||||
|       } | ||||
|     }, | ||||
|  | ||||
| @@ -138,12 +142,92 @@ | ||||
|  | ||||
|         document.addEventListener('fullscreenchange', this.fullScreenChange) | ||||
|       }) | ||||
|  | ||||
|       this.getSlwPlaybackTime() | ||||
|  | ||||
|       if (this.id) { | ||||
|         this.getLiveingUrl() | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     methods: { | ||||
|       destroyed () { | ||||
|         document.removeEventListener('fullscreenchange', this.fullScreenChange) | ||||
|       }, | ||||
|  | ||||
|       backLiving () { | ||||
|         this.getLiveingUrl() | ||||
|       }, | ||||
|  | ||||
|       getLiveingUrl () { | ||||
|         this.isLoading = true | ||||
|         this.instance.post(`/app/appzyvideoequipment/getWebSdkUrl?deviceId=${this.id}`).then(res => { | ||||
|           if (res.data) { | ||||
|             this.src = res.data | ||||
|             this.isLiveing = true | ||||
|           } | ||||
|  | ||||
|           this.isLoading = false | ||||
|         }).catch(() => { | ||||
|           this.isLoading = false | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       onReplay (e) { | ||||
|         this.isLoading = true | ||||
|         this.instance.post(`/app/appzyvideoequipment/getSlwPlaybackUrl`, null, { | ||||
|           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`, | ||||
|             nvrCodes: '' | ||||
|           } | ||||
|         }).then(res => { | ||||
|           if (res.code == 0) { | ||||
|             if (res.data && res.data.length) { | ||||
|               this.replayUrl = res.data[0].playbackUrl | ||||
|               this.isLiveing = false | ||||
|             } | ||||
|             this.isLoading = false | ||||
|           } | ||||
|         }).catch(() => { | ||||
|           this.isLoading = false | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       getSlwPlaybackTime () { | ||||
|         this.isLoading = true | ||||
|         this.instance.post(`/app/appzyvideoequipment/getSlwPlaybackTime`, null, { | ||||
|           params: { | ||||
|             ids: this.id, | ||||
|             startTime: this.form.date + ' 00:00:00', | ||||
|             endTime: this.form.date + ' 23:59:59', | ||||
|           } | ||||
|         }).then(res => { | ||||
|           if (res.code == 0) { | ||||
|             if (res.data && res.data.length) { | ||||
|               const times = res.data[0].times | ||||
|  | ||||
|               this.times = times.map(item => { | ||||
|                 const startTime = (item.startTime - new Date(this.form.date + ' 00:00:00').getTime()) / 1000 | ||||
|                 const endTime = (item.endTime - new Date(this.form.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 | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       fullScreenChange () { | ||||
|         if (document.fullscreenElement) { | ||||
|         } else { | ||||
| @@ -175,13 +259,15 @@ | ||||
|       onConfirm () { | ||||
|         this.$refs.form.validate((valid) => { | ||||
|           if (valid) { | ||||
|             this.isShowDate = false | ||||
|             this.getSlwPlaybackTime() | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       onVolume (e) { | ||||
|         const v = (e / 100).toFixed(1) | ||||
|         const subPage = document.querySelector(`#${this.id}`).contentWindow | ||||
|         const subPage = document.querySelector(`#${this.iframeId}`).contentWindow | ||||
|         subPage.postMessage({ | ||||
|           type: 'volume', | ||||
|           value: Number(v) | ||||
| @@ -209,7 +295,7 @@ | ||||
|       }, | ||||
|  | ||||
|       screenshots () { | ||||
|         const subPage = document.querySelector(`#${this.id}`).contentWindow | ||||
|         const subPage = document.querySelector(`#${this.iframeId}`).contentWindow | ||||
|         subPage.postMessage({ | ||||
|           type: 'screenshot' | ||||
|         }, '*') | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| <template> | ||||
|   <div :class="wrapper" class="canvas" @mousemove.stop="onMousemove" @mouseup="onMouseUp" @mouseleave="isHide = true" v-if="isInit"> | ||||
|   <div :class="wrapper" class="canvas" @click="onClick"  @mousemove.stop="onMousemove" @mouseup="onMouseUp" @mouseleave="isHide = true" v-if="isInit"> | ||||
|     <canvas | ||||
|       :id="id" | ||||
|       :style="{height: '52px'}" | ||||
| @@ -21,7 +21,7 @@ | ||||
|  | ||||
| <script> | ||||
|   export default { | ||||
|     props: ['isLiveing'], | ||||
|     props: ['isLiveing', 'times'], | ||||
|  | ||||
|     data () { | ||||
|       return { | ||||
| @@ -43,9 +43,16 @@ | ||||
|     }, | ||||
|  | ||||
|     watch: { | ||||
|       isLiveing (v) { | ||||
|         if (v) { | ||||
|       isLiveing () { | ||||
|         this.countdown() | ||||
|       }, | ||||
|  | ||||
|       times: { | ||||
|         deep: true, | ||||
|         handler (v) { | ||||
|           if (v.length && this.ctx) { | ||||
|             this.init() | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
| @@ -56,8 +63,11 @@ | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     methods: { | ||||
|     destroyed () { | ||||
|       clearInterval(this.timer) | ||||
|     }, | ||||
|  | ||||
|     methods: { | ||||
|       onMousemove (e) { | ||||
|         const canvasInfo = document.querySelector(`#${this.id}`).getBoundingClientRect() | ||||
|         const seconds = 24 * 60 * 60 | ||||
| @@ -77,38 +87,49 @@ | ||||
|         } | ||||
|       }, | ||||
|  | ||||
|       onDragDown () { | ||||
|         this.$emit('pause') | ||||
|       onClick (e) { | ||||
|         const canvasInfo = document.querySelector(`#${this.id}`).getBoundingClientRect() | ||||
|  | ||||
|         if (e.clientY - canvasInfo.top < 29) { | ||||
|           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', time) | ||||
|         } | ||||
|       }, | ||||
|  | ||||
|       onDragDown () { | ||||
|         this.isChoose = true | ||||
|       }, | ||||
|  | ||||
|       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', time) | ||||
|       }, | ||||
|  | ||||
|       secTotime (s) { | ||||
|         var t = '' | ||||
|         if(s > -1){ | ||||
|           var hour = Math.ceil(s / 3600) | ||||
|           var min = Math.ceil(s / 60) % 60 | ||||
|           var sec = s % 60 | ||||
|           if(hour < 10) { | ||||
|             t = '0'+ hour + ":" | ||||
|           } else {  | ||||
|             t = hour + ":" | ||||
|         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) | ||||
|           } | ||||
|           if(min < 10){ | ||||
|             t += "0" | ||||
|         } | ||||
|           t += min + ":" | ||||
|           if(sec < 10){ | ||||
|             t += "0" | ||||
|           }  | ||||
|           t += sec.toFixed(0) | ||||
|         }  | ||||
|         return t | ||||
|  | ||||
|         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}` | ||||
|       }, | ||||
|  | ||||
|       init () { | ||||
| @@ -141,7 +162,11 @@ | ||||
|  | ||||
|       countdown () { | ||||
|         this.timer = setInterval(() => { | ||||
|           if (this.isLiveing) { | ||||
|             this.initNowTime() | ||||
|           } else { | ||||
|             this.x = this.x + this.canvasWidth / (24 * 60 * 60) | ||||
|           } | ||||
|         }, 1000) | ||||
|       }, | ||||
|  | ||||
| @@ -149,7 +174,7 @@ | ||||
|         const date = new Date() | ||||
|         const seconds = date.getHours() * 3600 + date.getMinutes() * 60 + date.getSeconds() | ||||
|  | ||||
|         this.x = seconds / (24 * 60 * 60) * this.canvasWidth | ||||
|         this.x = this.canvasWidth / (24 * 60 * 60) * seconds | ||||
|       }, | ||||
|  | ||||
|       drawLine(ctx, options) { | ||||
| @@ -164,18 +189,17 @@ | ||||
|  | ||||
|       renderPlayback () { | ||||
|         const ctx = this.ctx | ||||
|         for (let i = 0; i < 24 * 60 * 60; i ++) { | ||||
|           if ((i + 1) % 3 !== 0) { | ||||
|         const unit = this.canvasWidth / (24 * 60 * 60) | ||||
|         this.times.forEach(item => { | ||||
|           this.drawLine(ctx, { | ||||
|               beginX: i, | ||||
|             beginX: item.startTime * unit, | ||||
|             beginY: 28, | ||||
|               endX: i, | ||||
|             endX: item.startTime * unit, | ||||
|             endY: 0, | ||||
|             lineColor: 'rgba(0, 156, 255, 1)', | ||||
|               lineWidth: 1 | ||||
|             lineWidth: item.endTime * unit - item.startTime * unit | ||||
|           }) | ||||
|         }) | ||||
|           } | ||||
|         } | ||||
|       }, | ||||
|  | ||||
|       renderTimeLine () { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user