视频回放

This commit is contained in:
yanran200730
2022-04-19 17:59:16 +08:00
parent 4ec129a695
commit e36ebca88c
3 changed files with 164 additions and 54 deletions

View File

@@ -21,7 +21,7 @@
v-for="(m, i) in monitors" v-for="(m, i) in monitors"
:key="m.id" :key="m.id"
:style="currentSplitStyle"> :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>
</div> </div>
<Synergy ref="Synergy" v-if="!isShowBar && monitors.length" style="width: 100%; height: 68px;"></Synergy> <Synergy ref="Synergy" v-if="!isShowBar && monitors.length" style="width: 100%; height: 68px;"></Synergy>

View File

@@ -1,5 +1,5 @@
<template> <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"> <div class="slw-title">
<h2>{{ name }}</h2> <h2>{{ name }}</h2>
<div class="slw-title__close" @click="removeMonitor"> <div class="slw-title__close" @click="removeMonitor">
@@ -9,13 +9,13 @@
</div> </div>
<iframe <iframe
v-if="isShow" v-if="isShow"
:id="id" :id="iframeId"
allow="autoplay *; microphone *; fullscreen *" allowfullscreen allowtransparency key="" allowusermedia frameBorder="no" allow="autoplay *; microphone *; fullscreen *" allowfullscreen allowtransparency key="" allowusermedia frameBorder="no"
style="width: 100%; height: 100%;" 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> </iframe>
<div class="slw-bottom" v-if="isShowBar"> <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="action-bar">
<div class="left"> <div class="left">
<div class="left-btns"> <div class="left-btns">
@@ -47,7 +47,7 @@
<i>直播中</i> <i>直播中</i>
<em>{{ form.date }}</em> <em>{{ form.date }}</em>
</div> </div>
<div v-else class="back-btn" @click="isLiveing = true">回到直播</div> <div v-else class="back-btn" @click="backLiving">回到直播</div>
</div> </div>
</div> </div>
<div class="right"> <div class="right">
@@ -86,7 +86,7 @@
import Timeline from './Timeline' import Timeline from './Timeline'
export default { export default {
props: ['src', 'name', 'isShowBar'], props: ['name', 'isShowBar', 'instance', 'id', 'deviceId'],
name: 'slwVideo', name: 'slwVideo',
@@ -105,13 +105,17 @@
form: { form: {
date: '' date: ''
}, },
src: '',
isLoading: false,
times: [],
date: '', date: '',
isPause: false, isPause: false,
width: '', width: '',
volume: 100, volume: 100,
videoId: `slwvideo-${new Date().getTime()}`, videoId: `slwvideo-${new Date().getTime()}`,
id: `video-${new Date().getTime()}`, iframeId: `video-${new Date().getTime()}`,
isFullscreen: false isFullscreen: false,
replayUrl: ''
} }
}, },
@@ -138,12 +142,92 @@
document.addEventListener('fullscreenchange', this.fullScreenChange) document.addEventListener('fullscreenchange', this.fullScreenChange)
}) })
this.getSlwPlaybackTime()
if (this.id) {
this.getLiveingUrl()
}
}, },
methods: { methods: {
destroyed () { destroyed () {
document.removeEventListener('fullscreenchange', this.fullScreenChange) 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 () { fullScreenChange () {
if (document.fullscreenElement) { if (document.fullscreenElement) {
} else { } else {
@@ -175,13 +259,15 @@
onConfirm () { onConfirm () {
this.$refs.form.validate((valid) => { this.$refs.form.validate((valid) => {
if (valid) { if (valid) {
this.isShowDate = false
this.getSlwPlaybackTime()
} }
}) })
}, },
onVolume (e) { onVolume (e) {
const v = (e / 100).toFixed(1) const v = (e / 100).toFixed(1)
const subPage = document.querySelector(`#${this.id}`).contentWindow const subPage = document.querySelector(`#${this.iframeId}`).contentWindow
subPage.postMessage({ subPage.postMessage({
type: 'volume', type: 'volume',
value: Number(v) value: Number(v)
@@ -209,7 +295,7 @@
}, },
screenshots () { screenshots () {
const subPage = document.querySelector(`#${this.id}`).contentWindow const subPage = document.querySelector(`#${this.iframeId}`).contentWindow
subPage.postMessage({ subPage.postMessage({
type: 'screenshot' type: 'screenshot'
}, '*') }, '*')

View File

@@ -1,5 +1,5 @@
<template> <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 <canvas
:id="id" :id="id"
:style="{height: '52px'}" :style="{height: '52px'}"
@@ -21,7 +21,7 @@
<script> <script>
export default { export default {
props: ['isLiveing'], props: ['isLiveing', 'times'],
data () { data () {
return { return {
@@ -43,9 +43,16 @@
}, },
watch: { watch: {
isLiveing (v) { isLiveing () {
if (v) { this.countdown()
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) { onMousemove (e) {
const canvasInfo = document.querySelector(`#${this.id}`).getBoundingClientRect() const canvasInfo = document.querySelector(`#${this.id}`).getBoundingClientRect()
const seconds = 24 * 60 * 60 const seconds = 24 * 60 * 60
@@ -77,38 +87,49 @@
} }
}, },
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 () { onDragDown () {
this.$emit('pause')
clearInterval(this.timer)
this.timer = null
this.isChoose = true this.isChoose = true
}, },
onMouseUp () { onMouseUp () {
if (!this.isChoose) return
clearInterval(this.timer)
this.timer = null
this.isChoose = false this.isChoose = false
const time = this.secTotime((24 * 60 * 60) / this.canvasWidth * this.x)
this.$emit('replay', time)
}, },
secTotime (s) { secTotime (s) {
var t = '' let second = parseInt(s)
if(s > -1){ let minute = 0
var hour = Math.ceil(s / 3600) let hour = 0
var min = Math.ceil(s / 60) % 60 if (second > 60) {
var sec = s % 60 minute = parseInt(second / 60)
if(hour < 10) { second = parseInt(second % 60)
t = '0'+ hour + ":" if (minute > 60) {
} else { hour = parseInt(minute / 60)
t = hour + ":" minute = parseInt(minute % 60)
} }
if(min < 10){ }
t += "0"
} hour = `${parseInt(hour) > 9 ? parseInt(hour) : '0' + parseInt(hour)}`
t += min + ":" minute = `${parseInt(minute) > 9 ? parseInt(minute) : '0' + parseInt(minute)}`
if(sec < 10){ second = `${parseInt(second) > 9 ? parseInt(second) : '0' + parseInt(second)}`
t += "0" return `${hour}:${minute}:${second}`
}
t += sec.toFixed(0)
}
return t
}, },
init () { init () {
@@ -141,7 +162,11 @@
countdown () { countdown () {
this.timer = setInterval(() => { this.timer = setInterval(() => {
this.initNowTime() if (this.isLiveing) {
this.initNowTime()
} else {
this.x = this.x + this.canvasWidth / (24 * 60 * 60)
}
}, 1000) }, 1000)
}, },
@@ -149,7 +174,7 @@
const date = new Date() const date = new Date()
const seconds = date.getHours() * 3600 + date.getMinutes() * 60 + date.getSeconds() 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) { drawLine(ctx, options) {
@@ -164,18 +189,17 @@
renderPlayback () { renderPlayback () {
const ctx = this.ctx const ctx = this.ctx
for (let i = 0; i < 24 * 60 * 60; i ++) { const unit = this.canvasWidth / (24 * 60 * 60)
if ((i + 1) % 3 !== 0) { this.times.forEach(item => {
this.drawLine(ctx, { this.drawLine(ctx, {
beginX: i, beginX: item.startTime * unit,
beginY: 28, beginY: 28,
endX: i, endX: item.startTime * unit,
endY: 0, endY: 0,
lineColor: 'rgba(0, 156, 255, 1)', lineColor: 'rgba(0, 156, 255, 1)',
lineWidth: 1 lineWidth: item.endTime * unit - item.startTime * unit
}) })
} })
}
}, },
renderTimeLine () { renderTimeLine () {