Files
dvcp_v2_webapp/packages/device/IntelligentSecurity/components/AiSlwVideo.vue

566 lines
15 KiB
Vue
Raw Normal View History

2022-04-13 18:57:48 +08:00
<template>
2022-04-19 17:59:16 +08:00
<div class="slw" :id="videoId" v-loading="isLoading" element-loading-background="rgba(0, 0, 0, 0.6)">
2022-04-13 18:57:48 +08:00
<div class="slw-title">
<h2>{{ name }}</h2>
<div class="slw-title__close" @click="removeMonitor">
<i class="el-icon-circle-close"></i>
<span>关闭视频</span>
</div>
</div>
2022-04-28 10:30:52 +08:00
<iframe v-if="isShow" :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}`">
2022-04-13 18:57:48 +08:00
</iframe>
2022-04-15 14:41:07 +08:00
<div class="slw-bottom" v-if="isShowBar">
2022-04-19 17:59:16 +08:00
<Timeline class="Timeline" v-if="times.length" :times="times" @replay="onReplay" :isLiveing="isLiveing" :width="width" ref="timeline" :style="{width: width}"></Timeline>
2022-04-15 14:03:59 +08:00
<div class="action-bar">
<div class="left">
<div class="left-btns">
<el-tooltip effect="dark" :content="isPause ? '播放' : '暂停'" placement="top">
2022-04-28 10:30:52 +08:00
<img :src="isPause ? 'https://cdn.cunwuyun.cn/slw2.0/images/play.png' : 'https://cdn.cunwuyun.cn/slw2.0/images/pause.png'" @click="changePlayStatus">
2022-04-15 14:03:59 +08:00
</el-tooltip>
</div>
2022-04-28 10:30:52 +08:00
<div class="volume" @mouseleave.stop="isShowVolume = false">
<img @mouseenter.stop="isShowVolume = true" src="https://cdn.cunwuyun.cn/slw2.0/images/sound.png">
2022-04-15 14:03:59 +08:00
<div class="volume-slider" :class="[isShowVolume ? 'active' : '']">
2022-04-28 10:30:52 +08:00
<el-slider input-size="mini" v-model="volume" vertical @change="onVolume" height="80px">
2022-04-15 14:03:59 +08:00
</el-slider>
</div>
</div>
<div class="play-status">
2022-04-24 09:53:32 +08:00
<div class="live">
<span class="label" v-if="isLiveing"></span>
<i v-if="isLiveing">直播中</i>
2022-04-20 16:36:55 +08:00
<em>{{ date }}</em>
2022-04-15 14:03:59 +08:00
</div>
2022-04-24 09:53:32 +08:00
<div v-if="!isLiveing" class="back-btn" @click="backLiveing">回到直播</div>
2022-04-13 18:57:48 +08:00
</div>
</div>
2022-04-15 14:03:59 +08:00
<div class="right">
<el-tooltip effect="dark" content="选择日期" placement="top">
<img src="https://cdn.cunwuyun.cn/slw2.0/images/date.png" @click="isShowDate = true">
</el-tooltip>
<el-tooltip effect="dark" content="截屏" placement="top">
<img src="https://cdn.cunwuyun.cn/slw2.0/images/screenshots.png" @click="screenshots">
</el-tooltip>
<el-tooltip effect="dark" :content="isFullscreen ? '退出全屏' : '全屏'" placement="top">
<img src="https://cdn.cunwuyun.cn/slw2.0/images/full-screen.png" @click="fullscreen">
</el-tooltip>
</div>
2022-04-13 18:57:48 +08:00
</div>
</div>
2022-04-28 10:30:52 +08:00
<ai-dialog title="选择日期" :visible.sync="isShowDate" width="520px" @onConfirm="onConfirm">
2022-04-13 18:57:48 +08:00
<el-form class="ai-form" ref="form" :model="form" label-width="80px" size="small">
<el-form-item label="选择日期" prop="date" :rules="[{ required: true, message: '请选择日期', trigger: 'change' }]">
2022-04-28 10:30:52 +08:00
<el-date-picker value-format="yyyy-MM-dd" v-model="form.date" type="date" :picker-options="pickerOptions" placeholder="选择日期">
2022-04-13 18:57:48 +08:00
</el-date-picker>
</el-form-item>
</el-form>
</ai-dialog>
</div>
</template>
<script>
2022-04-15 14:03:59 +08:00
import Timeline from './Timeline'
2022-04-13 18:57:48 +08:00
export default {
2022-04-20 16:36:55 +08:00
props: ['name', 'isShowBar', 'instance', 'id', 'playbackUrls'],
2022-04-13 18:57:48 +08:00
name: 'slwVideo',
2022-04-15 14:03:59 +08:00
components: {
Timeline
},
2022-04-13 18:57:48 +08:00
data () {
return {
2022-04-22 16:14:29 +08:00
pickerOptions: {
disabledDate(time) {
return time.getTime() > Date.now();
}
},
2022-04-13 18:57:48 +08:00
currIndex: 0,
isShowDate: false,
isShowPlayBtn: false,
isShow: true,
isShowVolume: false,
2022-04-15 14:03:59 +08:00
isLiveing: true,
2022-04-13 18:57:48 +08:00
form: {
date: ''
},
2022-04-19 17:59:16 +08:00
isLoading: false,
times: [],
2022-04-15 14:03:59 +08:00
date: '',
isPause: false,
width: '',
2022-04-13 18:57:48 +08:00
volume: 100,
videoId: `slwvideo-${new Date().getTime()}`,
2022-04-19 17:59:16 +08:00
iframeId: `video-${new Date().getTime()}`,
isFullscreen: false,
2022-04-20 16:36:55 +08:00
replayUrl: '',
liveingUrl: ''
}
},
computed: {
src () {
if (this.playbackUrls.length) {
2022-04-28 10:30:52 +08:00
const arr = this.playbackUrls.filter(v => v.id === this.id)
return arr.length ? arr[0].playbackUrl : []
2022-04-20 16:36:55 +08:00
}
if (this.isLiveing) {
return this.liveingUrl
}
return this.replayUrl
2022-04-13 18:57:48 +08:00
}
},
watch: {
src: {
handler (val) {
if (val) {
this.isShow = false
this.$nextTick(() => {
this.isShow = true
})
}
2022-04-20 16:36:55 +08:00
}
2022-04-13 18:57:48 +08:00
}
},
mounted () {
2022-04-24 09:53:32 +08:00
this.date = this.$moment(new Date()).format('YYYY-MM-DD')
2022-04-15 14:03:59 +08:00
this.form.date = this.$moment(new Date()).format('YYYY-MM-DD')
this.$nextTick(() => {
this.width = document.querySelector(`#${this.videoId}`).offsetWidth + 'px'
2022-04-18 17:36:30 +08:00
document.addEventListener('fullscreenchange', this.fullScreenChange)
2022-04-15 14:03:59 +08:00
})
2022-04-19 17:59:16 +08:00
this.getSlwPlaybackTime()
if (this.id) {
this.getLiveingUrl()
}
2022-04-13 18:57:48 +08:00
},
methods: {
2022-04-18 17:36:30 +08:00
destroyed () {
document.removeEventListener('fullscreenchange', this.fullScreenChange)
},
2022-04-19 17:59:16 +08:00
2022-04-20 16:36:55 +08:00
backLiveing () {
2022-04-21 15:04:17 +08:00
this.form.date = this.$moment(new Date()).format('YYYY-MM-DD')
this.date = this.$moment(new Date()).format('YYYY-MM-DD')
2022-04-19 17:59:16 +08:00
this.getLiveingUrl()
2022-04-21 15:04:17 +08:00
this.getSlwPlaybackTime()
2022-04-19 17:59:16 +08:00
},
getLiveingUrl () {
this.isLoading = true
this.instance.post(`/app/appzyvideoequipment/getWebSdkUrl?deviceId=${this.id}`).then(res => {
if (res.data) {
2022-04-20 16:36:55 +08:00
this.liveingUrl = res.data
2022-04-19 17:59:16 +08:00
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}`,
2022-04-20 16:36:55 +08:00
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`,
2022-04-19 17:59:16 +08:00
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,
2022-04-24 09:53:32 +08:00
startTime: this.date + ' 00:00:00',
endTime: this.date + ' 23:59:59',
2022-04-19 17:59:16 +08:00
}
}).then(res => {
if (res.code == 0) {
if (res.data && res.data.length) {
const times = res.data[0].times
this.times = times.map(item => {
2022-04-24 09:53:32 +08:00
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
2022-04-19 17:59:16 +08:00
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
})
},
2022-04-18 17:36:30 +08:00
fullScreenChange () {
if (document.fullscreenElement) {
2022-04-28 15:18:31 +08:00
this.reset()
2022-04-18 17:36:30 +08:00
} else {
this.reset()
}
},
2022-04-13 18:57:48 +08:00
exitFullscreen () {
if (document.exitFullscreen) {
document.exitFullscreen()
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen()
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen()
2022-04-18 17:36:30 +08:00
} else if (document.msExitFullscreen) {
window.top.document.msExitFullscreen()
2022-04-13 18:57:48 +08:00
}
},
2022-04-15 14:03:59 +08:00
changePlayStatus () {
2022-04-28 14:01:59 +08:00
const subPage = document.querySelector(`#${this.iframeId}`).contentWindow
2022-04-15 14:03:59 +08:00
subPage.postMessage({
type: 'play',
value: this.isPause
}, '*')
this.isPause = !this.isPause
},
2022-04-13 18:57:48 +08:00
onConfirm () {
this.$refs.form.validate((valid) => {
if (valid) {
2022-04-20 16:36:55 +08:00
this.date = this.form.date
2022-04-19 17:59:16 +08:00
this.isShowDate = false
this.getSlwPlaybackTime()
2022-04-13 18:57:48 +08:00
}
})
},
onVolume (e) {
const v = (e / 100).toFixed(1)
2022-04-19 17:59:16 +08:00
const subPage = document.querySelector(`#${this.iframeId}`).contentWindow
2022-04-13 18:57:48 +08:00
subPage.postMessage({
type: 'volume',
value: Number(v)
}, '*')
},
fullscreen () {
if (this.isFullscreen) {
this.exitFullscreen()
} else {
this.requestFullScreen(document.querySelector(`#${this.videoId}`))
}
this.isFullscreen = !this.isFullscreen
2022-04-15 14:03:59 +08:00
this.reset()
},
reset () {
setTimeout(() => {
this.width = document.querySelector(`#${this.videoId}`).offsetWidth + 'px'
this.$nextTick(() => {
2022-04-15 16:01:15 +08:00
this.$refs.timeline && this.$refs.timeline.init()
2022-04-15 14:03:59 +08:00
})
2022-04-28 15:18:31 +08:00
}, 100)
2022-04-13 18:57:48 +08:00
},
screenshots () {
2022-04-19 17:59:16 +08:00
const subPage = document.querySelector(`#${this.iframeId}`).contentWindow
2022-04-13 18:57:48 +08:00
subPage.postMessage({
type: 'screenshot'
}, '*')
},
removeMonitor () {
this.$emit('close')
},
2022-04-18 17:36:30 +08:00
requestFullScreen (elem) {
if (elem.requestFullscreen) {
elem.requestFullscreen()
} else if (elem.mozRequestFullScreen) {
elem.mozRequestFullScreen()
} else if (elem.webkitRequestFullscreen) {
elem.webkitRequestFullscreen()
} else if (elem.msRequestFullscreen) {
elem = window.top.document.body
elem.msRequestFullscreen()
2022-04-13 18:57:48 +08:00
}
}
}
}
</script>
<style lang="scss" scoped>
.slw {
position: relative;
width: 100%;
height: 100%;
2022-04-15 14:03:59 +08:00
overflow: hidden;
2022-04-13 18:57:48 +08:00
iframe {
border: none;
}
2022-04-15 14:03:59 +08:00
.slw-bottom {
position: absolute;
bottom: 0;
left: 0;
z-index: 1;
width: 100%;
transition: all ease-in-out 0.5s;
2022-04-22 14:13:01 +08:00
transform: translateY(100%);
2022-04-15 14:03:59 +08:00
}
&:hover {
.slw-title {
transform: translateY(0%);
}
.slw-bottom {
transform: translateY(0%);
}
}
2022-04-13 18:57:48 +08:00
.slw-title {
display: flex;
position: absolute;
align-items: center;
justify-content: space-between;
top: 0;
left: 0;
z-index: 1;
width: 100%;
height: 40px;
line-height: 40px;
padding: 0 16px;
background: rgba(0, 0, 0, 0.8);
2022-04-15 14:03:59 +08:00
transition: all ease 0.5s;
transform: translateY(-100%);
2022-04-13 18:57:48 +08:00
h2 {
2022-04-15 14:03:59 +08:00
max-width: 70%;
2022-04-13 18:57:48 +08:00
font-size: 16px;
color: #fff;
font-weight: normal;
2022-04-15 14:03:59 +08:00
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
2022-04-13 18:57:48 +08:00
}
.slw-title__close {
display: flex;
align-items: center;
justify-content: center;
width: 84px;
height: 32px;
background: linear-gradient(180deg, #2E3447 0%, #151825 100%);
border-radius: 2px;
cursor: pointer;
font-size: 12px;
color: #fff;
&:hover {
opacity: 0.9;
}
span {
margin-left: 4px;
}
i {
position: relative;
font-size: 16px;
}
}
}
.action-bar {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
height: 40px;
padding: 0 16px;
background: rgba(0, 0, 0, 0.8);
.left {
2022-04-15 14:03:59 +08:00
display: flex;
align-items: center;
.play-status {
display: flex;
align-items: center;
margin-left: 12px;
em {
margin-left: 12px;
font-style: normal;
color: #fff;
font-size: 12px;
}
.back-btn {
padding: 4px 10px;
border-radius: 6px;
color: #ddd;
font-size: 12px;
cursor: pointer;
background: #343747;
&:hover {
opacity: 0.6;
}
}
.live {
display: flex;
align-items: center;
2022-04-24 09:53:32 +08:00
line-height: 1;
2022-04-15 14:03:59 +08:00
padding: 2px 5px;
color: rgba(0,255,0,.8);
i {
font-size: 12px;
font-style: normal;
}
.label {
width: 6px;
height: 6px;
margin-right: 12px;
background: rgba(0,255,0,.8);
border-radius: 50%;
position: relative;
&:after {
content: "";
width: 12px;
height: 12px;
position: absolute;
left: 50%;
top: 50%;
-webkit-transform: translate(-50%,-50%);
transform: translate(-50%,-50%);
border-radius: 50%;
border: 4px solid rgba(0,255,0,.2);
}
}
}
}
2022-04-13 18:57:48 +08:00
.volume {
2022-04-15 14:03:59 +08:00
display: flex;
align-items: center;
2022-04-13 18:57:48 +08:00
position: relative;
height: 100%;
.volume-slider {
display: none;
position: absolute;
2022-04-18 17:36:30 +08:00
bottom: 15px;
2022-04-13 18:57:48 +08:00
left: 50%;
z-index: -1;
opacity: 0;
padding: 20px 0 10px;
background-color: rgba(0, 0,0,.8);
transform: translate(-50%, 0);
transition: all ease 0.3s;
&.active {
display: block;
z-index: 1;
opacity: 1;
}
}
}
img {
cursor: pointer;
}
.left-btns {
display: flex;
align-items: center;
margin-right: 10px;
span {
flex: 1;
height: 100%;
line-height: 24px;
background: #222838;
color: #c9c9c9;
font-size: 12px;
cursor: pointer;
&.active {
color: #fff;
background: linear-gradient(180deg, #28B2EB 0%, #193D91 100%);
}
}
}
}
.right {
color: #c9c9c9;
font-size: 12px;
span {
margin-right: 32px;
cursor: pointer;
&:hover {
opacity: 0.6;
}
}
img {
margin-right: 16px;
cursor: pointer;
&:last-child {
margin-right: 0;
}
&:hover {
opacity: 0.6;
}
}
}
& > div {
display: flex;
align-items: center;
}
}
}
</style>