|
|
@@ -10,34 +10,18 @@
|
|
|
ref="player"
|
|
|
class="o-video__player o-simple-video"
|
|
|
muted
|
|
|
- autoplay
|
|
|
:poster="poster"
|
|
|
/>
|
|
|
- <div
|
|
|
- v-else
|
|
|
- class="o-video__offline"
|
|
|
- :style="{ zoom: zoomnum }"
|
|
|
- >
|
|
|
- 当前设备离线了
|
|
|
- </div>
|
|
|
- <div
|
|
|
- class="o-video__tip"
|
|
|
- :class="{ online }"
|
|
|
- />
|
|
|
- <div class="c-footer u-ellipsis">{{ device.name }}</div>
|
|
|
+ <slot />
|
|
|
<div
|
|
|
v-show="maskShow"
|
|
|
class="o-video__mask"
|
|
|
>
|
|
|
<div
|
|
|
- class="o-video__btn u-pointer"
|
|
|
- :style="{ zoom: zoomnum }"
|
|
|
- @click="onPlay"
|
|
|
+ class="l-flex--row center o-video__btn u-pointer"
|
|
|
+ @click="onClick"
|
|
|
>
|
|
|
- <i
|
|
|
- class="o-video__icon has-bg"
|
|
|
- :class="iconClass"
|
|
|
- />
|
|
|
+ <i :class="iconClass" />
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
@@ -46,87 +30,104 @@
|
|
|
<script>
|
|
|
import flvjs from 'flv.js'
|
|
|
import { authCode } from '@/api/camera'
|
|
|
+import { GATEWAY } from '@/constant'
|
|
|
import videoPoster from '@/assets/video-poster.png'
|
|
|
|
|
|
-const CAMERA_URL = `${location.protocol}//${process.env.VUE_APP_GATEWAY || location.host}`
|
|
|
-
|
|
|
export default {
|
|
|
- name: 'DeviceCard',
|
|
|
+ name: 'DevicePlayer',
|
|
|
props: {
|
|
|
device: {
|
|
|
type: Object,
|
|
|
required: true
|
|
|
},
|
|
|
- zoomnum: {
|
|
|
- type: String,
|
|
|
- default: null
|
|
|
+ simple: {
|
|
|
+ type: [Boolean, String],
|
|
|
+ default: false
|
|
|
+ },
|
|
|
+ autoplay: {
|
|
|
+ type: [Boolean, String],
|
|
|
+ default: false
|
|
|
}
|
|
|
},
|
|
|
data () {
|
|
|
return {
|
|
|
poster: videoPoster,
|
|
|
+ loading: false,
|
|
|
maskShow: false,
|
|
|
refreshShow: false,
|
|
|
- first: false
|
|
|
+ paused: !this.autoplay
|
|
|
}
|
|
|
},
|
|
|
computed: {
|
|
|
iconClass () {
|
|
|
+ if (this.loading) {
|
|
|
+ return 'el-icon-loading'
|
|
|
+ }
|
|
|
if (this.refreshShow) {
|
|
|
- return 'refresh'
|
|
|
+ return 'el-icon-refresh'
|
|
|
}
|
|
|
- return this.device.paused ? 'paused' : 'playing'
|
|
|
+ return this.paused ? 'el-icon-video-play' : 'el-icon-video-pause'
|
|
|
},
|
|
|
online () {
|
|
|
- return this.device.onlineStatus === 1
|
|
|
+ return this.device.activate === 2 && this.device.onlineStatus === 1
|
|
|
}
|
|
|
},
|
|
|
created () {
|
|
|
+ this.$timer = -1
|
|
|
if (this.online) {
|
|
|
- this.$timer = -1
|
|
|
this.getAuthCode()
|
|
|
}
|
|
|
},
|
|
|
beforeDestroy () {
|
|
|
if (this.$player) {
|
|
|
- clearTimeout(this.$timer)
|
|
|
this.destroyPlay()
|
|
|
}
|
|
|
+ this.$timer = null
|
|
|
},
|
|
|
methods: {
|
|
|
mouseOver () {
|
|
|
- if (this.online) {
|
|
|
- this.maskShow = true
|
|
|
- }
|
|
|
- if (this.$player && !this.$refs.player.paused) {
|
|
|
- this.device.paused = false
|
|
|
- } else {
|
|
|
- this.device.paused = true
|
|
|
+ if (!this.online) {
|
|
|
+ return
|
|
|
}
|
|
|
+ this.maskShow = true
|
|
|
},
|
|
|
mouseLeave () {
|
|
|
this.maskShow = false
|
|
|
},
|
|
|
- onPlay () {
|
|
|
- this.first = true
|
|
|
- if (this.$refs.player.paused) {
|
|
|
- this.maskShow = false
|
|
|
+ onClick () {
|
|
|
+ if (this.loading) {
|
|
|
+ return
|
|
|
}
|
|
|
- this.refreshShow = false
|
|
|
- if (this.$player && !this.$refs.player.paused) {
|
|
|
- this.device.paused = true
|
|
|
- this.$player.pause()
|
|
|
- } else {
|
|
|
+ if (this.refreshShow) {
|
|
|
if (this.$player) {
|
|
|
this.destroyPlay()
|
|
|
}
|
|
|
- this.device.paused = false
|
|
|
this.getAuthCode()
|
|
|
+ } else {
|
|
|
+ if (this.paused) {
|
|
|
+ this.$player.play()
|
|
|
+ } else {
|
|
|
+ this.$player.pause()
|
|
|
+ }
|
|
|
+ this.paused = !this.paused
|
|
|
}
|
|
|
},
|
|
|
getAuthCode () {
|
|
|
- authCode({ deviceId: this.device.id }).then(({ data }) => {
|
|
|
- this.createPlayer(data)
|
|
|
+ if (this.loading) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.loading = true
|
|
|
+ authCode({ deviceId: this.device.id }).then(
|
|
|
+ ({ data }) => {
|
|
|
+ if (this.$timer !== null) {
|
|
|
+ this.createPlayer(data)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ () => {
|
|
|
+ this.refreshShow = true
|
|
|
+ }
|
|
|
+ ).finally(() => {
|
|
|
+ this.loading = false
|
|
|
})
|
|
|
},
|
|
|
createPlayer ({ timestamp, token, expire }) {
|
|
|
@@ -136,7 +137,7 @@ export default {
|
|
|
type: 'flv',
|
|
|
isLive: true,
|
|
|
hasAudio: false,
|
|
|
- url: `${CAMERA_URL}/live/${this.device.id}.flv?authorization=${token}×tamp=${timestamp}&expire=${expire}`
|
|
|
+ url: `${GATEWAY}/live/${this.device.id}.flv?authorization=${token}×tamp=${timestamp}&expire=${expire}`
|
|
|
})
|
|
|
this.$player.on('error', () => {
|
|
|
this.refreshShow = true
|
|
|
@@ -146,7 +147,7 @@ export default {
|
|
|
message: '设备视频流出错'
|
|
|
})
|
|
|
})
|
|
|
- let decodedFrames = -1
|
|
|
+ let decodedFrames = 0
|
|
|
this.$player.on('statistics_info', res => {
|
|
|
decodedFrames = res.decodedFrames
|
|
|
})
|
|
|
@@ -167,15 +168,17 @@ export default {
|
|
|
// 开始运行加载 只要流地址正常 就可以在h5页面中播放出画面了
|
|
|
this.$player.load()
|
|
|
this.$player.play()
|
|
|
- if (!this.first) {
|
|
|
+ if (this.paused) {
|
|
|
this.$player.pause()
|
|
|
}
|
|
|
+ this.refreshShow = false
|
|
|
} catch (error) {
|
|
|
console.log('连接websocker异常', error)
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
destroyPlay () {
|
|
|
+ clearTimeout(this.$timer)
|
|
|
this.$player.pause()
|
|
|
this.$player.unload()
|
|
|
this.$player.detachMediaElement()
|
|
|
@@ -188,59 +191,6 @@ export default {
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
.o-video {
|
|
|
- position: relative;
|
|
|
- padding-top: 56.25%;
|
|
|
- border-radius: $radius--mini;
|
|
|
- overflow: hidden;
|
|
|
-
|
|
|
- &.offline {
|
|
|
- background: url("~@/assets/image_offline.svg") 0 0 / 100% 100% no-repeat;
|
|
|
- }
|
|
|
-
|
|
|
- &__player {
|
|
|
- position: absolute;
|
|
|
- top: 0;
|
|
|
- left: 0;
|
|
|
- width: 100%;
|
|
|
- height: 100%;
|
|
|
- }
|
|
|
-
|
|
|
- &__offline {
|
|
|
- position: absolute;
|
|
|
- top: 73%;
|
|
|
- left: 50%;
|
|
|
- color: $info;
|
|
|
- font-size: 24px;
|
|
|
- transform: translateX(-50%);
|
|
|
- }
|
|
|
-
|
|
|
- &__tip {
|
|
|
- position: absolute;
|
|
|
- top: 0;
|
|
|
- right: 0;
|
|
|
- width: 48px;
|
|
|
- height: 24px;
|
|
|
- color: #fff;
|
|
|
- font-size: 14px;
|
|
|
- line-height: 24px;
|
|
|
- text-align: center;
|
|
|
- border-radius: 0 0 0 $radius--mini;
|
|
|
- background-color: $error--dark;
|
|
|
- z-index: 9;
|
|
|
-
|
|
|
- &::after {
|
|
|
- content: "离线";
|
|
|
- }
|
|
|
-
|
|
|
- &.online {
|
|
|
- background-color: $success--dark;
|
|
|
-
|
|
|
- &::after {
|
|
|
- content: "在线";
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
&__mask {
|
|
|
position: absolute;
|
|
|
top: 0;
|
|
|
@@ -255,38 +205,13 @@ export default {
|
|
|
position: absolute;
|
|
|
left: 50%;
|
|
|
top: 50%;
|
|
|
- width: 128px;
|
|
|
- padding-top: 128px;
|
|
|
+ width: 64px;
|
|
|
+ height: 64px;
|
|
|
+ color: #fff;
|
|
|
+ font-size: 48px;
|
|
|
border-radius: 50%;
|
|
|
- background-color: rgba(#f4f7fb, 0.5);
|
|
|
- transform: translate(-50%, -50%);
|
|
|
- }
|
|
|
-
|
|
|
- &__icon {
|
|
|
- position: absolute;
|
|
|
- top: 50%;
|
|
|
- left: 50%;
|
|
|
+ background-color: rgba(#000, 0.5);
|
|
|
transform: translate(-50%, -50%);
|
|
|
-
|
|
|
- &.playing {
|
|
|
- border-top: 22px solid transparent;
|
|
|
- border-left: 37px solid #fff;
|
|
|
- border-bottom: 22px solid transparent;
|
|
|
- transform: translate(-15px, -50%);
|
|
|
- }
|
|
|
-
|
|
|
- &.paused {
|
|
|
- width: 40%;
|
|
|
- height: 60%;
|
|
|
- border-left: 10px solid #fff;
|
|
|
- border-right: 10px solid #fff;
|
|
|
- }
|
|
|
-
|
|
|
- &.refresh {
|
|
|
- width: 60%;
|
|
|
- height: 60%;
|
|
|
- background-image: url("~@/assets/icon_refresh.png");
|
|
|
- }
|
|
|
}
|
|
|
}
|
|
|
</style>
|