Bladeren bron

refactor: video component

Casper Dai 3 jaren geleden
bovenliggende
commit
0204a6d264

+ 0 - 10
src/assets/icon_four_hover.svg

@@ -1,10 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" style='fill:#1c5cb0' width="34" height="22" viewBox="0 0 34 22">
-  <defs>
-    <style>
-      .cls-1 {
-        fill-rule: evenodd;
-      }
-    </style>
-  </defs>
-  <path id="icon_four_normal" class="cls-1" d="M2,0H16V10H0V2A2,2,0,0,1,2,0ZM0,12H16V22H2a2,2,0,0,1-2-2V12ZM18,0H32a2,2,0,0,1,2,2v8H18V0Zm0,12H34v8a2,2,0,0,1-2,2H18V12Z"/>
-</svg>

BIN
src/assets/icon_four_normal.png


BIN
src/assets/icon_nine_focus.png


+ 0 - 10
src/assets/icon_nine_hover.svg

@@ -1,10 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" style='fill:#1c5cb0' width="34" height="22" viewBox="0 0 34 22">
-  <defs>
-    <style>
-      .cls-1 {
-        fill-rule: evenodd;
-      }
-    </style>
-  </defs>
-  <path id="icon_nine" class="cls-1" d="M2,0h8V6H0V2A2,2,0,0,1,2,0ZM0,8H10v6H0V8Zm0,8H10v6H2a2,2,0,0,1-2-2V16ZM12,0H22V6H12V0Zm0,8H22v6H12V8Zm0,8H22v6H12V16ZM24,0h8a2,2,0,0,1,2,2V6H24V0Zm0,8H34v6H24V8Zm0,8H34v4a2,2,0,0,1-2,2H24V16Z"/>
-</svg>

+ 0 - 3
src/assets/icon_one_hover.svg

@@ -1,3 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" style='fill:#1c5cb0' width="34" height="22" viewBox="0 0 34 22">
-  <rect id="icon_one" width="34" height="22" rx="2" ry="2"/>
-</svg>

BIN
src/assets/icon_one_normal.png


+ 1 - 1
src/assets/image_no_program.svg

@@ -1,4 +1,4 @@
-<svg id="image_no_program" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="920" height="521" viewBox="0 0 920 521">
+<svg id="image_no_program" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="920" height="521" viewBox="0 0 920 521" preserveAspectRatio="none meet">
   <defs>
     <style>
       .cls-1 {

+ 1 - 1
src/assets/image_offline.svg

@@ -1,4 +1,4 @@
-<svg id="image_offline" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="920" height="521" viewBox="0 0 920 521">
+<svg id="image_offline" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="920" height="521" viewBox="0 0 920 521" preserveAspectRatio="none meet">
   <defs>
     <style>
       .cls-1 {

+ 0 - 0
src/assets/video-post.png → src/assets/video-poster.png


+ 0 - 0
src/assets/icon_four.svg → src/icons/svg/menu-four.svg


+ 0 - 0
src/assets/icon_nine.svg → src/icons/svg/menu-nine.svg


+ 0 - 0
src/assets/icon_one.svg → src/icons/svg/menu-one.svg


+ 154 - 184
src/views/device/back/components/Video.vue

@@ -1,75 +1,56 @@
 <template>
   <div
-    class="return_item"
+    class="o-video"
+    :class="{ offline: !online }"
     @mouseenter.stop="mouseOver"
     @mouseleave.stop="mouseLeave"
   >
     <video
+      v-if="online"
       ref="player"
-      class="video"
+      class="o-video__player"
       muted
       autoplay
       controls
-      :style="{ height: returnheight }"
-      :poster="require('@/assets//video-post.png')"
+      :poster="poster"
     />
     <div
-      class="onlinetip"
-      :style="{ 'background-color': device.onlineStatus === 1 ? '#04A681' : '#E51414' }"
+      v-else
+      class="o-video__offline"
+      :style="{ zoom: zoomnum }"
     >
-      {{ device.onlineStatus === 1 ? '在线' : '离线' }}
+      当前设备离线了
     </div>
-    <div class="mask1" />
     <div
-      v-if="device.onlineStatus !== 1"
-      class="offline"
-    >
-      <img
-        :src="require('@/assets/image_offline.svg')"
-        alt=""
-      >
-      <div
-        class="offlinetext"
-        :style="{ zoom:zoomnum }"
-      >
-        当前设备离线了
-      </div>
-    </div>
+      class="o-video__tip"
+      :class="{ online }"
+    />
+    <div class="o-video__name u-ellipsis">{{ device.name }}</div>
     <div
-      :style="{ display:maskshow }"
-      class="mask"
+      v-show="maskShow"
+      class="o-video__mask"
     >
       <div
-        class="playbtn"
-        :style="{ zoom:zoomnum }"
-        @click="videoplay"
+        class="o-video__btn u-pointer"
+        :style="{ zoom: zoomnum }"
+        @click="onPlay"
       >
-        <div
-          :class="{ playing:device.paused, paused:!device.paused }"
-          :style="{ display: refreshshow ? 'none' : 'block' }"
+        <i
+          class="o-video__icon has-bg"
+          :class="iconClass"
         />
-        <img
-          :src="require('@/assets/icon_refresh.png')"
-          :style="{ display: refreshshow ? 'block' : 'none' }"
-          class="refresh"
-          alt=""
-        >
       </div>
     </div>
-    <div class="o-video_buttom l-flex--row">
-      <div class="l-flex__auto">{{ device.name }}</div>
-    </div>
   </div>
 </template>
 
 <script>
 import flvjs from 'flv.js'
-import {
-  authCode,
-  detail
-} from '@/api/camera'
+import { authCode } from '@/api/camera'
+import videoPoster from '@/assets/video-poster.png'
 
 const CAMERA_URL = `${location.protocol}//${process.env.VUE_APP_GATEWAY || location.host}`
+
 export default {
   name: 'DeviceCard',
   props: {
@@ -80,57 +61,64 @@ export default {
     zoomnum: {
       type: String,
       default: null
-    },
-    returnheight: {
-      type: String,
-      default: null
     }
   },
   data () {
     return {
-      player: null,
-      maskshow: 'none',
-      refreshshow: false,
+      poster: videoPoster,
+      maskShow: false,
+      refreshShow: false,
       first: false
     }
   },
+  computed: {
+    iconClass () {
+      if (this.refreshShow) {
+        return 'refresh'
+      }
+      return this.device.paused ? 'paused' : 'playing'
+    },
+    online () {
+      return this.device.onlineStatus === 1
+    }
+  },
   created () {
-    if (this.device.onlineStatus === 1) {
+    if (this.online) {
       this.$timer = -1
       this.getAuthCode()
     }
   },
   beforeDestroy () {
-    if (this.player) {
+    if (this.$player) {
       clearTimeout(this.$timer)
       this.destroyPlay()
     }
   },
   methods: {
     mouseOver () {
-      if (this.device.onlineStatus === 1) {
-        this.maskshow = 'block'
+      if (this.online) {
+        this.maskShow = true
       }
-      if (this.player && !this.$refs.player.paused) {
+      if (this.$player && !this.$refs.player.paused) {
         this.device.paused = false
       } else {
         this.device.paused = true
       }
     },
     mouseLeave () {
-      this.maskshow = 'none'
+      this.maskShow = false
     },
-    videoplay () {
+    onPlay () {
       this.first = true
       if (this.$refs.player.paused) {
-        this.maskshow = 'none'
+        this.maskShow = false
       }
-      this.refreshshow = false
-      if (this.player && !this.$refs.player.paused) {
+      this.refreshShow = false
+      if (this.$player && !this.$refs.player.paused) {
         this.device.paused = true
-        this.player.pause()
+        this.$player.pause()
       } else {
-        if (this.player) {
+        if (this.$player) {
           this.destroyPlay()
         }
         this.device.paused = false
@@ -138,30 +126,20 @@ export default {
       }
     },
     getAuthCode () {
-      authCode({
-        deviceId: this.device.id
-      }).then(({ data }) => {
-        const { token, expire, timestamp } = data
-        this.getflv(timestamp, token, expire)
-      })
+      authCode({ deviceId: this.device.id }).then(this.createPlayer)
     },
-    getDetail () {
-      detail(this.device.id).then(({ data }) => {
-        console.log(data)
-      })
-    },
-    getflv (timestamp, token, expire) {
+    createPlayer ({ timestamp, token, expire }) {
       if (flvjs.isSupported()) {
         // 创建一个flvjs实例
         const url = `${CAMERA_URL}/live/${this.device.id}.flv?authorization=${token}&timestamp=${timestamp}&expire=${expire}`
-        this.player = flvjs.createPlayer({
+        this.$player = flvjs.createPlayer({
           type: 'flv',
           isLive: true,
           hasAudio: false,
           url
         })
-        this.player.on('error', () => {
-          this.refreshshow = true
+        this.$player.on('error', () => {
+          this.refreshShow = true
           this.destroyPlay()
           this.$message({
             type: 'warning',
@@ -169,7 +147,7 @@ export default {
           })
         })
         let decodedFrames = -1
-        this.player.on('statistics_info', res => {
+        this.$player.on('statistics_info', res => {
           decodedFrames = res.decodedFrames
         })
         this.$timer = setTimeout(() => {
@@ -179,18 +157,18 @@ export default {
               type: 'warning',
               message: `${this.device.name}设备没有视频流`
             })
-            this.refreshshow = true
+            this.refreshShow = true
           }
         }, 10000)
         // 将实例挂载到video元素上面
-        this.player.attachMediaElement(this.$refs.player)
+        this.$player.attachMediaElement(this.$refs.player)
 
         try {
           // 开始运行加载 只要流地址正常 就可以在h5页面中播放出画面了
-          this.player.load()
-          this.player.play()
+          this.$player.load()
+          this.$player.play()
           if (!this.first) {
-            this.player.pause()
+            this.$player.pause()
           }
         } catch (error) {
           console.log('连接websocker异常', error)
@@ -198,145 +176,137 @@ export default {
       }
     },
     destroyPlay () {
-      this.player.pause()
-      this.player.unload()
-      this.player.detachMediaElement()
-      this.player.destroy()
-      this.player = null
+      this.$player.pause()
+      this.$player.unload()
+      this.$player.detachMediaElement()
+      this.$player.destroy()
+      this.$player = null
     }
   }
 }
 </script>
 
 <style lang="scss" scoped>
-//所有控件
-video::-webkit-media-controls-enclosure {
+video::-webkit-media-controls-fullscreen-button {
   display: none;
 }
-.video {
-  width: 100%;
-  height: 100%;
-  background-color: #000;
-  object-fit: cover;
+
+video::-webkit-media-controls-enclosure {
+  display: none;
 }
-.return_item {
-  height: 100%;
+
+.o-video {
   position: relative;
-  // &:hover .mask{
-  //   display: block;
-  // }
-  .onlinetip {
+  padding-top: 56.25%;
+  overflow: hidden;
+
+  &.offline {
+    background: url("~@/assets/image_offline.svg") 0 0 / 100% 100% no-repeat;
+  }
+
+  &__player {
     position: absolute;
     top: 0;
-    right: 0;
-    font-size: 14px;
-    text-align: center;
-    color: #fff;
-    width: 48px;
-    height: 24px;
-    line-height: 24px;
-    background-color: #04a681;
-    border-radius: 0px 4px 0px 4px;
-    z-index: 2;
-  }
-  .mask1 {
+    left: 0;
     width: 100%;
     height: 100%;
+  }
+
+  &__offline {
     position: absolute;
-    left: 0;
-    top: 0;
+    top: 73%;
+    left: 50%;
+    color: $info;
+    font-size: 24px;
+    transform: translateX(-50%);
   }
-  .offline {
-    width: 100%;
-    height: 100%;
+
+  &__tip {
     position: absolute;
-    left: 0;
     top: 0;
-    img {
-      width: 100%;
-      height: 100%;
-      object-fit: cover;
-      border-radius: 4px;
+    right: 0;
+    width: 48px;
+    height: 24px;
+    color: #fff;
+    font-size: 14px;
+    line-height: 24px;
+    text-align: center;
+    border-radius: 0 0 0 4px;
+    background-color: $error--dark;
+    z-index: 9;
+
+    &::after {
+      content: "离线";
     }
-    .offlinetext {
-      font-size: 24px;
-      color: #fff;
-      position: absolute;
-      top: 72%;
-      left: 50%;
-      transform: translateX(-50%);
+
+    &.online {
+      background-color: $success--dark;
+
+      &::after {
+        content: "在线";
+      }
     }
   }
-  .mask {
+
+  &__name {
+    position: absolute;
     width: 100%;
-    height: 100%;
+    bottom: 0;
+    padding: 24px 16px 16px;
+    color: #fff;
+    background-image: linear-gradient(
+      to bottom,
+      rgba(#000, 0) 0%,
+      rgba(#000, 0.6) 100%
+    );
+  }
+
+  &__mask {
     position: absolute;
-    left: 0;
     top: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
     background-color: rgba(0, 0, 0, 0.3);
-    display: none;
     z-index: 2;
   }
-  .playbtn {
+
+  &__btn {
     position: absolute;
     left: 50%;
     top: 50%;
-    transform: translate(-50%, -50%);
-    width: 110px;
-    height: 110px;
-    background-color: rgba(244, 247, 251, 0.5);
+    width: 128px;
+    padding-top: 128px;
     border-radius: 50%;
-    cursor: pointer;
-    .playing {
-      width: 0;
-      height: 0;
+    background-color: rgba(#f4f7fb, 0.5);
+    transform: translate(-50%, -50%);
+  }
+
+  &__icon {
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    transform: translate(-50%, -50%);
+
+    &.playing {
       border-top: 22px solid transparent;
       border-left: 37px solid #fff;
       border-bottom: 22px solid transparent;
-      border-right: 37px solid transparent;
-      position: absolute;
-      left: 50%;
-      top: 50%;
       transform: translate(-15px, -50%);
     }
-    .paused::before {
-      content: "";
-      width: 4px;
-      height: 37px;
-      background-color: #fff;
-      position: absolute;
-      left: 45px;
-      top: 50%;
-      transform: translateY(-50%);
-    }
-    .paused::after {
-      content: "";
-      width: 4px;
-      height: 37px;
-      background-color: #fff;
-      position: absolute;
-      right: 45px;
-      top: 50%;
-      transform: translateY(-50%);
+
+    &.paused {
+      width: 40%;
+      height: 60%;
+      border-left: 10px solid #fff;
+      border-right: 10px solid #fff;
     }
-    .refresh {
-      width: 40px;
-      height: 40px;
-      position: absolute;
-      left: 50%;
-      top: 50%;
-      transform: translate(-50%, -50%);
+
+    &.refresh {
+      width: 60%;
+      height: 60%;
+      background-image: url("~@/assets/icon_refresh.png");
     }
   }
-  .o-video_buttom {
-    position: absolute;
-    bottom: 0px;
-    width: 100%;
-    height: 58px;
-    background-image: linear-gradient(0deg, rgba(6, 11, 18, 0.9), transparent);
-    border-radius: 0px 0px 4px 4px;
-    color: #fff;
-    padding: 0 16px;
-  }
 }
 </style>

+ 93 - 87
src/views/device/back/index.vue

@@ -2,64 +2,48 @@
   <wrapper
     fill
     margin
+    padding
     background
   >
     <div
       v-loading="options.loading"
-      class="has-padding"
+      class="l-flex__auto l-flex--col"
     >
-      <div class="l-flex--row c-table__header">
-        <div class="l-flex__auto c-sibling-item">
-          <!-- <el-checkbox-group v-model="checkList" @change="chechChange">
-            <el-checkbox label="视频回采" />
-            <el-checkbox label="模拟终端" />
-          </el-checkbox-group> -->
-        </div>
+      <div class="l-flex__none l-flex--row has-bottom-padding">
+        <div class="l-flex__auto c-sibling-item" />
         <div class="l-flex__none c-sibling-item">
-          <img
-            class="c-sibling-item imghover"
-            :src="svgIcon.icon_one"
-            alt=""
-            @click="rowChange(24)"
-          >
-          <img
-            class="c-sibling-item imghover"
-            :src="svgIcon.icon_four"
-            alt=""
-            @click="rowChange(12)"
-          >
-          <img
-            class="c-sibling-item imghover"
-            :src="svgIcon.icon_nine"
-            alt=""
-            @click="rowChange(8)"
-          >
+          <svg-icon
+            class="c-sibling-item o-menu-icon u-pointer"
+            :class="{ active: gridClass === 'one' }"
+            icon-class="menu-one"
+            @click="onChange(1)"
+          />
+          <svg-icon
+            class="c-sibling-item o-menu-icon u-pointer"
+            :class="{ active: gridClass === 'four' }"
+            icon-class="menu-four"
+            @click="onChange(4)"
+          />
+          <svg-icon
+            class="c-sibling-item o-menu-icon u-pointer"
+            :class="{ active: gridClass === 'nine' }"
+            icon-class="menu-nine"
+            @click="onChange(9)"
+          />
         </div>
       </div>
-      <div>
-        <el-row
-          :gutter="16"
-          class="rowheight"
+      <div class="l-flex__auto u-overflow-y--auto">
+        <div
+          class="c-back-grid"
+          :class="gridClass"
         >
-          <el-col
-            v-for="(item, index) in options.list"
-            :key="index"
-            :span="rowNum"
-            class="cameraRow"
-          >
-            <div
-              ref="returnB"
-              class="bg-purple"
-              :style="{ height: returnheight }"
-            >
-              <c-video
-                :device="item"
-                :zoomnum="zoomnum"
-                :returnheight="returnheight"
-              />
-            </div>
-          </el-col>
-        </el-row>
+          <c-video
+            v-for="item in options.list"
+            :key="item.identifier"
+            :device="item"
+            :zoomnum="zoomnum"
+          />
+        </div>
         <pagination
           :total="options.totalCount"
           :page.sync="options.params.pageNum"
@@ -67,8 +51,9 @@
           @pagination="getDevices"
         />
       </div>
-      <warning
-        v-if="options.error"
+      <status-wrapper
+        v-if="isAbnormal"
+        :error="options.error"
         @click="getDevices"
       />
     </div>
@@ -87,22 +72,33 @@ export default {
   },
   data () {
     return {
-      options: createListOptions({ activate: 2 }),
-      checkList: [],
-      returnheight: '0px',
-      rowNum: 12
+      options: createListOptions({ activate: 2, pageSize: 4 })
     }
   },
   computed: {
-    svgIcon () {
-      return {
-        icon_one: this.rowNum === 24 ? require('@/assets/icon_one_hover.svg') : require('@/assets/icon_one.svg'),
-        icon_four: this.rowNum === 12 ? require('@/assets/icon_four_hover.svg') : require('@/assets/icon_four.svg'),
-        icon_nine: this.rowNum === 8 ? require('@/assets/icon_nine_hover.svg') : require('@/assets/icon_nine.svg')
+    gridClass () {
+      switch (this.options.params.pageSize) {
+        case 4:
+          return 'four'
+        case 9:
+          return 'nine'
+        default:
+          return 'one'
       }
     },
     zoomnum () {
-      return this.rowNum === 24 ? '1' : this.rowNum === 12 ? '.6' : '.4'
+      switch (this.options.params.pageSize) {
+        case 4:
+          return '.6'
+        case 9:
+          return '.4'
+        default:
+          return '1'
+      }
+    },
+    isAbnormal () {
+      const options = this.options
+      return options.error || !options.loading && options.list.length === 0
     }
   },
   created () {
@@ -113,17 +109,14 @@ export default {
       const options = this.options
       options.error = false
       options.loading = true
-      options.params.pageSize = this.rowNum === 24 ? 1 : this.rowNum === 12 ? 4 : 9
+      options.list = []
       getDevices(options.params).then(
         ({ data, totalCount }) => {
-          for (let i = 0; i < data.length; i++) {
-            data[i].paused = true
-          }
+          data.forEach(item => {
+            item.paused = true
+          })
           options.totalCount = totalCount
           options.list = data
-          options.totalCount && this.$nextTick(() => {
-            this.returnheight = `${this.$refs.returnB[0].clientWidth * 9 / 16}px`
-          })
         },
         () => {
           options.error = true
@@ -134,34 +127,47 @@ export default {
         options.loading = false
       })
     },
-    rowChange (num) {
-      if (num === this.rowNum) {
+    onChange (num) {
+      const params = this.options.params
+      if (num === params.pageSize) {
         return
       }
-      this.options.params.pageNum = 1
-      this.rowNum = num
+      params.pageSize = num
+      params.pageNum = 1
       this.getDevices()
-    },
-    chechChange (val) {
-      console.log(val)
     }
   }
 }
 </script>
 
 <style lang="scss" scoped>
-.imghover {
-  cursor: pointer;
-}
-.has-padding {
-  height: 100%;
-  overflow: auto;
-  padding: 16px 76px;
-}
-.rowheight {
-  overflow: auto;
+.o-menu-icon {
+  color: #d5d9e4;
+  font-size: 32px;
+
+  &.active {
+    color: $blue;
+  }
 }
-.cameraRow {
-  margin-bottom: 16px;
+
+.c-back-grid {
+  display: grid;
+  grid-template-rows: max-content;
+  grid-row-gap: $spacing;
+  grid-column-gap: $spacing;
+  min-height: 0;
+  min-width: 0;
+
+  &.one {
+    grid-template-columns: 1fr;
+  }
+
+  &.four {
+    grid-template-columns: 1fr 1fr;
+  }
+
+  &.nine {
+    grid-template-columns: 1fr 1fr 1fr;
+  }
 }
 </style>

+ 30 - 23
src/views/external/camera/components/CameraPlayer.vue

@@ -1,20 +1,17 @@
 <template>
-  <div class="o-video has-bg">
+  <div
+    class="o-video"
+    :class="{ offline: !online }"
+  >
     <video
-      v-if="onlineStatus"
+      v-if="online"
       ref="video"
       class="o-video__player"
       muted
       autoplay
       controls
-      :poster="require('@/assets/video-post.png')"
+      :poster="poster"
     />
-    <div
-      v-else
-      class="o-video__offline"
-    >
-      设备离线
-    </div>
     <slot />
   </div>
 </template>
@@ -22,6 +19,7 @@
 <script>
 import { mapGetters } from 'vuex'
 import flvjs from 'flv.js'
+import videoPoster from '@/assets/video-poster.png'
 
 const CAMERA_URL = `${location.protocol === 'https:' ? 'wss' : 'ws'}://${process.env.VUE_APP_GATEWAY || location.host}${process.env.VUE_APP_CAMERA_PROXY}`
 
@@ -33,14 +31,19 @@ export default {
       required: true
     }
   },
+  data () {
+    return {
+      poster: videoPoster
+    }
+  },
   computed: {
     ...mapGetters(['token']),
-    onlineStatus () {
-      return this.camera.onlineStatus
+    online () {
+      return this.camera.onlineStatus === 1
     }
   },
   watch: {
-    onlineStatus (val) {
+    online (val) {
       if (val) {
         this.$nextTick(this.createPlayer)
       } else {
@@ -49,7 +52,7 @@ export default {
     }
   },
   mounted () {
-    this.onlineStatus && this.createPlayer()
+    this.online && this.createPlayer()
   },
   beforeDestroy () {
     this.destroyPlayer()
@@ -109,9 +112,22 @@ video::-webkit-media-controls-enclosure {
 .o-video {
   position: relative;
   padding-top: 56.25%;
-  background-image: url("~@/assets/video-post.png");
   overflow: hidden;
 
+  &.offline {
+    background: url("~@/assets/image_offline.svg") 0 0 / 100% 100% no-repeat;
+
+    &::before {
+      content: "当前设备离线了";
+      position: absolute;
+      top: 73%;
+      left: 50%;
+      color: $info;
+      font-size: 12px;
+      transform: translateX(-50%);
+    }
+  }
+
   &__player {
     position: absolute;
     top: 0;
@@ -119,14 +135,5 @@ video::-webkit-media-controls-enclosure {
     width: 100%;
     height: 100%;
   }
-
-  &__offline {
-    position: absolute;
-    left: 50%;
-    top: 50%;
-    color: $error--dark;
-    font-size: 16px;
-    transform: translate(-50%, -50%);
-  }
 }
 </style>

+ 75 - 56
src/views/external/camera/components/Detail.vue

@@ -7,10 +7,7 @@
       class="el-icon-close closeDetail"
       @click="close"
     />
-    <div
-      v-if="camera.cameraType===2"
-      class="detail-top"
-    >
+    <div class="detail-top">
       <div class="detail_text">
         {{ camera.name }}人流量监测
       </div>
@@ -18,16 +15,12 @@
     </div>
     <video
       ref="player"
-      style="width: 100%"
       class="video"
       muted
       autoplay
-      :poster="require('@/assets/video-post.png')"
+      :poster="poster"
     />
-    <div
-      v-if="camera.cameraType===2"
-      class="detail-buttom"
-    >
+    <div class="detail-buttom">
       <el-row :gutter="16">
         <el-col :span="24">
           <div class="video-controls l-flex--row">
@@ -66,22 +59,20 @@
               </div>
             </div>
             <div class="l-flex__auto">
-              <img
-                :src="imgUrl.stop"
-                class="stop"
-                @click="stopbtn"
-              >
+              <i
+                class="status u-pointer"
+                :class="{ stop: !playing }"
+                @click="onPlayOrPause"
+              />
             </div>
-            <img
-              :src="imgUrl.setting"
-              class="setting"
-              @click="settingShow"
-            >
-            <img
-              :src="imgUrl.refresh"
-              class="refresh"
-              @click="refresh"
-            >
+            <i
+              class="setting u-pointer"
+              @click="onSettings"
+            />
+            <i
+              class="refresh u-pointer"
+              @click="onRefresh"
+            />
           </div>
         </el-col>
         <el-col :span="8">
@@ -143,6 +134,7 @@ import {
   getAvailableParam,
   setCamera
 } from '@/api/camera'
+import videoPoster from '@/assets/video-poster.png'
 
 const CAMERA_URL = `${location.protocol === 'https:' ? 'wss' : 'ws'}://${process.env.VUE_APP_GATEWAY || location.host}${process.env.VUE_APP_CAMERA_PROXY}`
 
@@ -156,14 +148,10 @@ export default {
   },
   data () {
     return {
+      poster: videoPoster,
       datevalue: new Date(),
       active: 'hour', // hour是小时,day是天
-      imgUrl: {
-        setting: require('@/assets/icon_setting.png'),
-        stop: require('@/assets/icon_stop.png'),
-        start: require('@/assets/icon_start.png'),
-        refresh: require('@/assets/icon_refresh.png')
-      },
+      playing: true,
       settingActive: 0,
       setData: ['分辨率', '帧率', '码流'],
       settingData: [[], [], []],
@@ -187,7 +175,6 @@ export default {
       this.getStarttime(new Date())
     )
   },
-
   methods: {
     close () {
       this.destroyPlayer()
@@ -306,12 +293,12 @@ export default {
       this.player.destroy()
       this.player = null
     },
-    stopbtn () {
+    onPlayOrPause () {
       if (this.$refs.player.paused) {
-        this.imgUrl.stop = require('@/assets/icon_stop.png')
+        this.playing = true
         this.player.play()
       } else {
-        this.imgUrl.stop = this.imgUrl.start
+        this.playing = false
         this.player.pause()
       }
     },
@@ -348,12 +335,11 @@ export default {
       if (!(arr === JSON.stringify(this.infoData))) {
         this.setCamera()
       }
-      // console.log(this.infoData)
     },
-    settingShow () {
+    onSettings () {
       this.settingBshow = !this.settingBshow
     },
-    refresh () {
+    onRefresh () {
       this.destroyPlayer()
       this.getflv()
     },
@@ -507,26 +493,30 @@ export default {
   height: 100%;
   position: relative;
   overflow: hidden;
+
   .closeDetail {
     position: absolute;
-    right: 20px;
     top: 5px;
-    cursor: pointer;
-    z-index: 3;
-    font-size: 42px;
+    right: 20px;
     color: #000;
+    font-size: 42px;
+    z-index: 3;
+    cursor: pointer;
   }
+
   .video {
     width: 100%;
     height: 100vh;
     object-fit: contain;
   }
+
   .detail-buttom {
     position: absolute;
+    left: 0;
     bottom: 0;
     width: 100%;
-    left: 0;
     padding: 16px;
+
     .o-detail {
       padding: 24px 24px 70px;
       background-color: rgba(0, 62, 144, 0.8);
@@ -535,11 +525,13 @@ export default {
       height: 238px;
       position: relative;
       border-radius: 4px;
+
       &_title {
         width: 72px;
         display: inline-block;
         border-radius: 4px;
       }
+
       .choosedate {
         position: absolute;
         right: 20px;
@@ -562,30 +554,49 @@ export default {
             width: 50px;
             text-align: center;
           }
+
           .active {
             background: #0096ff;
           }
         }
       }
     }
+
     .video-controls {
       background-color: rgba(0, 6, 13, 0.75);
       height: 48px;
       border-radius: 4px;
       margin-bottom: 16px;
       position: relative;
-      img {
-        cursor: pointer;
-      }
-      .stop {
+
+      .status {
+        display: inline-block;
+        width: 30px;
+        height: 30px;
         margin-left: 12px;
+        background-image: url("~@/assets/icon_stop.png");
+
+        &.stop {
+          background-image: url("~@/assets/icon_start.png");
+        }
       }
+
       .setting {
+        display: inline-block;
+        width: 30px;
+        height: 30px;
         margin-right: 50px;
+        background-image: url("~@/assets/icon_setting.png");
       }
+
       .refresh {
+        display: inline-block;
+        width: 30px;
+        height: 30px;
         margin-right: 38px;
+        background-image: url("~@/assets/icon_refresh.png");
       }
+
       .settingB {
         position: absolute;
         padding: 10px 0px;
@@ -594,26 +605,31 @@ export default {
         transform: translateX(50%);
         bottom: 48px;
         color: #fff;
+
         .settingT {
+          position: relative;
           padding: 0px 16px;
+          width: 180px;
           height: 40px;
           line-height: 40px;
-          width: 180px;
           cursor: pointer;
-          position: relative;
+
           &:hover {
             background-color: rgba(69, 69, 69, 0.85);
           }
+
           i {
             position: absolute;
-            right: 16px;
             top: 13px;
+            right: 16px;
           }
         }
+
         .settingHeight {
           max-height: 250px;
           overflow: auto;
         }
+
         .settingsub {
           width: 140px;
           padding-left: 42px;
@@ -625,36 +641,39 @@ export default {
       }
     }
   }
+
   .detail-top {
     position: absolute;
     top: 0;
-    width: 100%;
     left: 0;
+    width: 100%;
     padding-top: 16px;
+    color: #fff;
     font-size: 24px;
     text-align: center;
     background-color: rgba(0, 62, 144, 0.8);
-    color: #fff;
     z-index: 2;
+
     .detail {
       &_border {
         position: absolute;
         left: 50%;
-        transform: translateX(-50%);
         width: 700px;
         height: 0;
         border-top: 16px solid rgba(0, 62, 144, 0.8);
         border-right: 16px solid transparent;
         border-bottom: 16px solid transparent;
         border-left: 16px solid transparent;
+        transform: translateX(-50%);
       }
+
       &_text {
+        height: 32px;
         width: 600px;
         margin: auto;
-        overflow: hidden;
-        text-overflow: ellipsis;
         white-space: nowrap;
-        height: 32px;
+        text-overflow: ellipsis;
+        overflow: hidden;
       }
     }
   }