Parcourir la source

feat(camera): adjust playback page style

Casper Dai il y a 2 ans
Parent
commit
71965fbb0f

+ 108 - 67
src/views/device/detail/components/DeviceExternal/components/Record/components/components/PlayAxis.vue

@@ -1,44 +1,38 @@
 <template>
-  <div
-    class="o-video o-time-axis"
-    :class="{ offline: !online, mask: !isPlaying, controls }"
-  >
-    <template v-if="online">
-      <video
-        ref="video"
-        class="o-video__player o-simple-video"
-        :poster="poster"
-        autoplay
-        muted
-        @play="onVideoPlay"
-        @pause="onVideoPause"
-        @waiting="onVideoWaiting"
-        @playing="onVideoPlaying"
-        @error="onVideoError"
-        @ended="onVideoEnded"
-      />
-      <div class="o-video__mask">
-        <div
-          class="l-flex--row center o-video__btn u-pointer"
-          @click.stop="onPlayOrPause"
-        >
-          <i :class="statusIconClass" />
-        </div>
-      </div>
-    </template>
-    <!-- <div
-      v-if="controls"
-      class="l-flex--row c-footer"
+  <div>
+    <div
+      class="o-video o-time-axis"
+      :class="{ offline: !online, mask: !isPlaying, controls }"
     >
-      <div class="l-flex__auto c-sibling-item u-ellipsis">{{ camera.remark }}</div>
-      <slot />
-      <i
-        v-if="online && !loading"
-        class="c-sibling-item el-icon-full-screen has-active"
-        @click="onFullScreen"
-      />
-    </div> -->
+      <template v-if="online">
+        <video
+          ref="video"
+          class="o-video__player o-simple-video"
+          :poster="poster"
+          autoplay
+          muted
+          @play="onVideoPlay"
+          @pause="onVideoPause"
+          @waiting="onVideoWaiting"
+          @playing="onVideoPlaying"
+          @error="onVideoError"
+          @ended="onVideoEnded"
+        />
+        <div class="o-video__mask">
+          <div
+            class="l-flex--row center o-video__btn u-pointer"
+            @click.stop="onPlayOrPause"
+          >
+            <i :class="statusIconClass" />
+          </div>
+        </div>
+      </template>
+    </div>
     <div class="o-time-axis__bottom">
+      <div
+        class="o-time-axis__disanable"
+        :style="{width: disanableWidth + '%'}"
+      />
       <div
         class="l-flex o-time-axis__box"
         @click.stop="(e) => play(e)"
@@ -68,7 +62,12 @@
         <el-time-select
           v-model="timeValue"
           class="u-width--xs u-pointer"
-          :picker-options="timePickerOptions"
+          :picker-options="{
+            start: '00:00',
+            step: '01:00',
+            end: '23:00',
+            maxTime: end
+          }"
           :editable="false"
           :clearable="false"
           @change="onChange"
@@ -81,9 +80,9 @@
 <script>
 import { mapGetters } from 'vuex'
 import { GATEWAY_CAMERA_RECORD } from '@/constant'
+import { parseTime } from '@/utils'
 import { isOnline } from '@/api/camera'
 import playerMixin from '@/components/service/external/player'
-import { parseTime } from '@/utils'
 
 export default {
   name: 'PlayAxis',
@@ -98,20 +97,16 @@ export default {
     return {
       online: true,
       timeNum: 5,
-      // times: [],
       timeValue: parseTime(new Date(), '{h}:00'),
       datePickerOptions: {
         disabledDate (time) {
           return time.getTime() > Date.now()
         }
       },
-      timePickerOptions: {
-        start: '00:00',
-        step: '01:00',
-        end: '23:00'
-      },
       dateValue: parseTime(new Date(), '{y}-{m}-{d}'),
-      leftRate: 0
+      leftRate: 0,
+      disanableWidth: 0,
+      end: ''
     }
   },
   computed: {
@@ -127,19 +122,34 @@ export default {
         this.$playTimer = setInterval(() => {
           if (this.leftRate >= 100) {
             this.leftRate = 100
-            clearInterval(this.$playTimer)
           } else {
             this.leftRate += (100 / 3600)
           }
+          if (this.disanableWidth <= 0) {
+            this.disanableWidth = 0
+            if (this.leftRate >= 100) {
+              clearInterval(this.$playTimer)
+            }
+          } else {
+            this.disanableWidth -= (100 / 3600)
+          }
         }, 1000)
       }
     }
   },
   mounted () {
     this.createPlayer()
+    this.disanableWidth = (60 - new Date().getMinutes()) / 60 * 100
+    this.end = `${(Number(parseTime(new Date(), '{h}:00').split(':')[0]) + 1).toString().padStart(2, '0')}:00`
   },
   methods: {
     onChange () {
+      if (Date.parse(`${this.dateValue} 23:59:59`) < Date.now()) {
+        console.log(123)
+        this.end = '24:00'
+      } else {
+        this.end = `${(Number(parseTime(new Date(), '{h}:00').split(':')[0]) + 1).toString().padStart(2, '0')}:00`
+      }
       this.leftRate = 0
       this.destroyPlayer()
       this.createPlayer()
@@ -149,6 +159,14 @@ export default {
           message: '不能超过当前时间'
         })
       }
+      if (Date.parse(`${this.dateValue} ${this.timeValue.split(':')[0]}:00:00`) < Date.parse(new Date()) && Date.parse(`${this.dateValue} ${(Number(this.timeValue.split(':')[0]) + 1).toString().padStart(2, '0')}:00:00`) > Date.parse(new Date())) {
+        const min = new Date().getMinutes()
+        this.disanableWidth = (60 - min) / 60 * 100
+      } else if (Date.parse(`${this.dateValue} ${this.timeValue.split(':')[0]}:00:00`) > Date.parse(new Date())) {
+        this.disanableWidth = 100
+      } else {
+        this.disanableWidth = 0
+      }
     },
     getTimeSep () {
       const arr = []
@@ -196,6 +214,8 @@ export default {
           if (data) {
             this.$nextTick(() => {
               this.playUrl(`${GATEWAY_CAMERA_RECORD}/${this.camera.identifier}/${startTime.replace(/-|:| /g, '')}/${endTime.replace(/-|:| /g, '')}`)
+              // this.playUrl(`${GATEWAY_CAMERA_RECORD}/${this.camera.identifier}/20230307150000/20230307150010`)
+              // this.onWebsocket(`${GATEWAY_CAMERA_RECORD}/${this.camera.identifier}/20230307150000/20230307150010`)
             })
           } else {
             this.destroyPlayer()
@@ -213,21 +233,30 @@ export default {
     checkOnline (delay = 5000) {
       clearTimeout(this.$timer)
       this.$timer = setTimeout(this.createPlayer, delay + Math.random() * delay | 0)
+    },
+    onWebsocket (url) {
+      const ws = new WebSocket(url)
+      ws.onclose = () => {
+        console.log('websocket 断开!')
+      }
     }
   }
 }
 </script>
+
 <style lang="scss" scoped>
-.o-video{
+.o-video {
   overflow: unset;
   padding-top: 0;
   background-color: transparent;
 }
-.o-time-axis{
+
+.o-time-axis {
   width: 900px;
   max-height: 100%;
   max-width: 100%;
-  &__box{
+
+  &__box {
     position: relative;
     width: 100%;
     height: 3px;
@@ -235,7 +264,8 @@ export default {
     border-radius: 3px;
     cursor: pointer;
   }
-  &__drop{
+
+  &__drop {
     position: absolute;
     top: 6px;
     white-space: nowrap;
@@ -243,8 +273,9 @@ export default {
     transform: translateX(-50%);
     color: #fff;
     pointer-events: none;
-    &::after{
-      content: '';
+    z-index: 2;
+    &::after {
+      content: "";
       position: absolute;
       width: 5px;
       height: 5px;
@@ -255,7 +286,8 @@ export default {
       transform: translateX(-50%);
     }
   }
-  &__shift{
+
+  &__shift {
     position: absolute;
     top: -7px;
     width: 15px;
@@ -263,11 +295,14 @@ export default {
     border-radius: 15px;
     background-color: #fff;
     transform: translateX(-50%);
+    z-index: 2;
   }
-  &__video{
+
+  &__video {
     position: relative;
   }
-  &__loading{
+
+  &__loading {
     position: absolute;
     left: 50%;
     top: 50%;
@@ -275,19 +310,25 @@ export default {
     font-size: 20px;
     color: #fff;
   }
-  &__slecetime{
+
+  &__slecetime {
     margin-top: 20px;
   }
-  &__bottom{
+
+  &__bottom {
     position: absolute;
-    width: 100%;
+    width: 900px;
+  }
+
+  &__disanable {
+    position: absolute;
+    background-color: #c4c4c4;
+    top: 0;
+    right: 0;
+    height: 3px;
+    border-radius: 3px;
+    z-index: 2;
+    cursor: not-allowed;
   }
-}
-.o-video__player{
-  position: relative;
-  // height: auto;
-  // width: auto;
-  // max-width: 100%;
-  // max-height: 100%;
 }
 </style>