Browse Source

1.更新 cam 相关页面和接口
2.分出摄像头实时录像和历史录像两个页面

reghao 2 years ago
parent
commit
6713f88060
5 changed files with 379 additions and 200 deletions
  1. 5 0
      src/api/cam.js
  2. 7 0
      src/router/index.js
  3. 36 173
      src/views/home/LivePage.vue
  4. 313 0
      src/views/home/RecordPage.vue
  5. 18 27
      src/views/post/CamList.vue

+ 5 - 0
src/api/cam.js

@@ -7,6 +7,7 @@ const camApi = {
   camRecordByMonthApi: '/api/content/cam/record/month',
   camRecordByDayApi: '/api/content/cam/record/day',
   camRecordApi: '/api/content/cam/record/id',
+  camPushUrlApi: '/api/content/cam/push',
   camPullUrlApi: '/api/content/cam/stream/rtmp/pull'
 }
 
@@ -26,6 +27,10 @@ export function getUserCams(page) {
   return get(camApi.camApi + '?page=' + page)
 }
 
+export function getCamPushUrl(camId) {
+  return get(camApi.camPushUrlApi + '/' + camId)
+}
+
 export function getCamDetail(camId) {
   return get(camApi.camApi + '/' + camId)
 }

+ 7 - 0
src/router/index.js

@@ -12,6 +12,7 @@ const ShortVideoIndex = () => import('views/home/ShortVideo')
 const VideoPage = () => import('views/home/VideoPage')
 const VideoList = () => import('views/home/VideoList')
 const LivePage = () => import('views/home/LivePage')
+const RecordPage = () => import('views/home/RecordPage')
 const AudioIndex = () => import('views/home/Audio')
 const AudioPage = () => import('views/home/AudioPage')
 const ImageIndex = () => import('views/home/Image')
@@ -337,6 +338,12 @@ const routes = [
     component: LivePage,
     meta: { needAuth: true }
   },
+  {
+    path: '/my/cam/record/:camId',
+    name: 'RecordPage',
+    component: RecordPage,
+    meta: { needAuth: true }
+  },
   {
     path: '/my/post/edit/video/:videoId',
     name: 'PostEditVideo',

+ 36 - 173
src/views/home/LivePage.vue

@@ -1,12 +1,12 @@
 <template>
   <el-row class="movie-list">
-    <el-col :md="16">
+    <el-col v-if="camDetail !== null" :md="16">
       <el-row style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px">
         <el-card class="box-card">
           <div slot="header" class="clearfix">
-            <h3 v-html="video.title" />
+            <h3 v-html="camDetail.camName" />
           </div>
-          <div class="text item">
+          <div id="videoplayer" class="text item">
             <div id="dplayer" ref="dplayer" style="height: 480px;" />
           </div>
         </el-card>
@@ -17,7 +17,7 @@
         <el-row style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px">
           <el-card class="box-card">
             <div slot="header" class="clearfix">
-              <el-select v-model="cam" placeholder="选择摄像头" @change="onSelect">
+              <el-select v-model="camNameModel" placeholder="选择摄像头" @change="onSelect">
                 <el-option
                   v-for="item in camList"
                   :key="item.value"
@@ -25,52 +25,7 @@
                   :value="item.value"
                 />
               </el-select>
-            </div>
-            <div class="text item">
-              <el-calendar v-if="showCalender" v-model="calendarDate">
-                <div
-                  slot="dateCell"
-                  slot-scope="{ date, data }"
-                  @click="handleCellClick(date, data)"
-                >
-                  <p>{{ data.day.split("-").slice(2).join() }}</p>
-                  <p v-if="dealMyDate(data.day)" class="blue budge" />
-                </div>
-              </el-calendar>
-            </div>
-          </el-card>
-        </el-row>
-        <el-row style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px">
-          <el-card v-if="showRecordList" class="box-card">
-            <div slot="header" class="clearfix">
-              <el-row>
-                <h3>列表</h3>
-              </el-row>
-            </div>
-            <div class="text item">
-              <el-table
-                :data="recordList"
-                :show-header="false"
-                height="480"
-                style="width: 100%"
-              >
-                <el-table-column
-                  prop="title"
-                >
-                  <template slot-scope="scope">
-                    <router-link :to="`/vidlist/${scope.row.videoId}`">
-                      <span>{{ scope.row.title | ellipsis }}</span>
-                    </router-link>
-                  </template>
-                </el-table-column>
-                <el-table-column
-                  prop="duration"
-                >
-                  <template slot-scope="scope">
-                    <span>{{ scope.row.duration }}</span>
-                  </template>
-                </el-table-column>
-              </el-table>
+              <el-button style="float: right; padding: 3px 0" type="text" @click="goToCamRecord">历史录像</el-button>
             </div>
           </el-card>
         </el-row>
@@ -82,7 +37,7 @@
 <script>
 import flvjs from 'flv.js'
 import DPlayer from 'dplayer'
-import { getCamDetail, getCamList, getCamRecord, getCamRecordByMonth, getCamRecordByDay } from '@/api/cam'
+import { getCamDetail, getCamList } from '@/api/cam'
 
 export default {
   name: 'LivePage',
@@ -109,7 +64,7 @@ export default {
       dateMap: new Map(),
       showRecordList: false,
       camList: [],
-      cam: null,
+      camNameModel: null,
       camDetail: null,
       form: {},
       recordList: [],
@@ -118,26 +73,8 @@ export default {
     }
   },
   watch: {
-    calendarDate: {
-      handler(newValue, oldValue) {
-        const oldMonth = this.getYearMonth(oldValue)
-        const newMonth = this.getYearMonth(newValue)
-        if (oldMonth !== newMonth) {
-          this.showCalender = false
-          this.form.yearMonth = this.getYearMonth(newValue)
-          getCamRecordByMonth(this.form).then(resp => {
-            if (resp.code === 0) {
-              this.dateMap.clear()
-              for (const item of resp.data) {
-                const date1 = new Date(item)
-                const dayStr = this.getYearMonthDay(date1)
-                this.dateMap.set(dayStr, date1)
-              }
-            }
-            this.showCalender = true
-          })
-        }
-      }
+    $route() {
+      this.$router.go()
     }
   },
   created() {
@@ -146,29 +83,23 @@ export default {
       return
     }
 
-    this.cam = camId
-    this.form.camId = camId
-    this.form.yearMonth = this.getYearMonth(new Date())
-    getCamRecordByMonth(this.form).then(resp => {
-      if (resp.code === 0) {
-        this.dateMap.clear()
-        for (const item of resp.data) {
-          const date1 = new Date(item)
-          const dayStr = this.getYearMonthDay(date1)
-          console.log(date1)
-          console.log(dayStr)
-          this.dateMap.set(dayStr, date1)
-        }
-        this.showCalender = true
-      }
-    })
-
     getCamDetail(camId).then(resp => {
       if (resp.code === 0) {
         var camDetail = resp.data
-        // console.log(camDetail)
-        // const url = camDetail.url
-        // this.initFlvPlayer(camId, null, url)
+        this.camDetail = camDetail
+        this.camNameModel = camDetail.camName
+        document.title = camDetail.camName + '实时录像'
+
+        if (!camDetail.state) {
+          const msg = camDetail.camName + '离线'
+          console.log(msg)
+          var container = document.getElementById('videoplayer')
+          console.log(container)
+          // container.innerHTML = msg
+        } else {
+          const pullUrl = camDetail.pullUrl
+          this.initFlvPlayer(camId, null, pullUrl)
+        }
       }
     })
 
@@ -177,90 +108,15 @@ export default {
         this.camList = resp.data
       }
     })
-
-    const recordId = '857500422144'
-    getCamRecord(recordId).then(resp => {
-      if (resp.code === 0) {
-        const respData = resp.data
-        this.initMp4Player(respData.coverUrl, respData.videoUrl)
-      }
-    })
   },
   methods: {
     onSelect(value) {
-      this.form.camId = value
-      this.form.yearMonth = this.getYearMonth(this.calendarDate)
-      this.showCalender = false
-      getCamRecordByMonth(this.form).then(resp => {
-        if (resp.code === 0) {
-          for (const item of resp.data) {
-            const date1 = new Date(item)
-            const dayStr = this.getYearMonthDay(date1)
-            this.dateMap.set(dayStr, date1)
-          }
-        }
-
-        this.showCalender = true
-      })
-    },
-    handleCellClick(date, data) {
-      /* this.form.yearMonthDay = this.getYearMonthDay(date)
-      getCamRecordByDay(this.form).then(resp => {
-        if (resp.code === 0) {
-          this.showRecordList = true
-          this.recordList = resp.data
-        }
-      })*/
-    },
-    dealMyDate(val) {
-      let res = ''
-
-      /* this.potDate = [
-        { date: '2024-02-02', hasRecord: true },
-        { date: '2024-02-01', hasRecord: true }
-      ]
-      for (let i = 0; i < this.potDate.length; i++) {
-        if (this.potDate[i].date === val) {
-          res = this.potDate[i].hasRecord
-          break
-        }
-      }*/
-
-      if (this.dateMap.get(val) != null) {
-        res = true
+      const path = '/my/cam/live/' + value
+      if (this.$route.path === path) {
+        this.$router.go(0)
+        return
       }
-      return res
-    },
-    getYearMonth(date) {
-      const year = date.getFullYear().toString().padStart(4, '0')
-      const month = (date.getMonth() + 1).toString().padStart(2, '0')
-      // const day = date.getDate().toString().padStart(2, '0')
-      // const hour = date.getHours().toString().padStart(2, '0')
-      // const minute = date.getMinutes().toString().padStart(2, '0')
-      // const second = date.getSeconds().toString().padStart(2, '0')
-      // 2023-02-16 08:25:05
-      // console.log(`${year}-${month}-${day} ${hour}:${minute}:${second}`)
-      return year + '-' + month
-    },
-    getYearMonthDay(date) {
-      const year = date.getFullYear().toString().padStart(4, '0')
-      const month = (date.getMonth() + 1).toString().padStart(2, '0')
-      const day = date.getDate().toString().padStart(2, '0')
-      return year + '-' + month + '-' + day
-    },
-    initMp4Player(coverUrl, videoUrl) {
-      new DPlayer({
-        container: document.getElementById('dplayer'),
-        lang: 'zh-cn',
-        autoplay: true,
-        volume: 0.1,
-        mutex: true,
-        video: {
-          pic: coverUrl,
-          url: videoUrl,
-          hotkey: true
-        }
-      })
+      this.$router.push(path)
     },
     initFlvPlayer(videoId, coverUrl, videoUrl) {
       new DPlayer({
@@ -281,6 +137,14 @@ export default {
           }
         }
       })
+    },
+    goToCamRecord() {
+      const path = '/my/cam/record/' + this.camDetail.camId
+      if (this.$route.path === path) {
+        this.$router.go(0)
+        return
+      }
+      this.$router.push(path)
     }
   }
 }
@@ -321,5 +185,4 @@ export default {
 .blue{
   background-color: #409eff;
 }
-
 </style>

+ 313 - 0
src/views/home/RecordPage.vue

@@ -0,0 +1,313 @@
+<template>
+  <el-row class="movie-list">
+    <el-col v-if="camDetail !== null" :md="16">
+      <el-row style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px">
+        <el-card class="box-card">
+          <div slot="header" class="clearfix">
+            <h3 v-html="camDetail.camName" />
+          </div>
+          <div id="videoplayer" class="text item">
+            <div id="dplayer" ref="dplayer" style="height: 480px;" />
+          </div>
+        </el-card>
+      </el-row>
+    </el-col>
+    <el-col :md="8">
+      <el-row>
+        <el-row style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px">
+          <el-card class="box-card">
+            <div slot="header" class="clearfix">
+              <el-select v-model="cam" placeholder="选择摄像头" @change="onSelect">
+                <el-option
+                  v-for="item in camList"
+                  :key="item.value"
+                  :label="item.name"
+                  :value="item.value"
+                />
+              </el-select>
+              <el-button style="float: right; padding: 3px 0" type="text" @click="goToCamLive">实时录像</el-button>
+            </div>
+            <div class="text item">
+              <el-calendar v-if="showCalender" v-model="calendarDate">
+                <div
+                  slot="dateCell"
+                  slot-scope="{ date, data }"
+                  @click="handleCellClick(date, data)"
+                >
+                  <p>{{ data.day.split("-").slice(2).join() }}</p>
+                  <p v-if="dealMyDate(data.day)" class="blue budge" />
+                </div>
+              </el-calendar>
+            </div>
+          </el-card>
+        </el-row>
+        <el-row style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px">
+          <el-card v-if="showRecordList" class="box-card">
+            <div slot="header" class="clearfix">
+              <el-row>
+                <h3>列表</h3>
+              </el-row>
+            </div>
+            <div class="text item">
+              <el-table
+                :data="recordList"
+                :show-header="false"
+                height="480"
+                style="width: 100%"
+              >
+                <el-table-column
+                  prop="title"
+                >
+                  <template slot-scope="scope">
+                    <router-link :to="`/vidlist/${scope.row.videoId}`">
+                      <span>{{ scope.row.title | ellipsis }}</span>
+                    </router-link>
+                  </template>
+                </el-table-column>
+                <el-table-column
+                  prop="duration"
+                >
+                  <template slot-scope="scope">
+                    <span>{{ scope.row.duration }}</span>
+                  </template>
+                </el-table-column>
+              </el-table>
+            </div>
+          </el-card>
+        </el-row>
+      </el-row>
+    </el-col>
+  </el-row>
+</template>
+
+<script>
+import DPlayer from 'dplayer'
+import { getCamDetail, getCamList, getCamRecord, getCamRecordByMonth } from '@/api/cam'
+
+export default {
+  name: 'RecordPage',
+  data() {
+    return {
+      DPlayer,
+      video: {
+        videoId: 110120119,
+        title: '我的直播',
+        description: '我的直播',
+        view: 10,
+        favorite: 10
+      },
+      user: {
+        userId: 10001,
+        screenName: '浩',
+        avatarUrl: '',
+        following: 1024,
+        follower: 1024
+      },
+      calendarDate: new Date(),
+      dateList: [],
+      dateMap: new Map(),
+      showRecordList: false,
+      camList: [],
+      cam: null,
+      camDetail: null,
+      form: {},
+      recordList: [],
+      camRecord: null,
+      showCalender: false
+    }
+  },
+  watch: {
+    $route() {
+      this.$router.go()
+    },
+    calendarDate: {
+      handler(newValue, oldValue) {
+        const oldMonth = this.getYearMonth(oldValue)
+        const newMonth = this.getYearMonth(newValue)
+        if (oldMonth !== newMonth) {
+          this.showCalender = false
+          this.form.yearMonth = this.getYearMonth(newValue)
+          getCamRecordByMonth(this.form).then(resp => {
+            if (resp.code === 0) {
+              this.dateMap.clear()
+              for (const item of resp.data) {
+                const date1 = new Date(item)
+                const dayStr = this.getYearMonthDay(date1)
+                this.dateMap.set(dayStr, date1)
+              }
+            }
+            this.showCalender = true
+          })
+        }
+      }
+    }
+  },
+  created() {
+    const camId = this.$route.params.camId
+    if (camId === undefined || camId === null) {
+      return
+    }
+
+    getCamDetail(camId).then(resp => {
+      if (resp.code === 0) {
+        var camDetail = resp.data
+        this.camDetail = camDetail
+        document.title = camDetail.camName + '历史录像'
+      }
+    })
+
+    this.cam = camId
+    this.form.camId = camId
+    this.form.yearMonth = this.getYearMonth(new Date())
+    getCamRecordByMonth(this.form).then(resp => {
+      if (resp.code === 0) {
+        this.dateMap.clear()
+        for (const item of resp.data) {
+          const date1 = new Date(item)
+          const dayStr = this.getYearMonthDay(date1)
+          console.log(date1)
+          console.log(dayStr)
+          this.dateMap.set(dayStr, date1)
+        }
+        this.showCalender = true
+      }
+    })
+
+    getCamList().then(resp => {
+      if (resp.code === 0) {
+        this.camList = resp.data
+      }
+    })
+
+    const recordId = '857500422144'
+    getCamRecord(recordId).then(resp => {
+      if (resp.code === 0) {
+        const respData = resp.data
+        this.initMp4Player(respData.coverUrl, respData.videoUrl)
+      }
+    })
+  },
+  methods: {
+    onSelect(value) {
+      this.form.camId = value
+      this.form.yearMonth = this.getYearMonth(this.calendarDate)
+      this.showCalender = false
+      getCamRecordByMonth(this.form).then(resp => {
+        if (resp.code === 0) {
+          for (const item of resp.data) {
+            const date1 = new Date(item)
+            const dayStr = this.getYearMonthDay(date1)
+            this.dateMap.set(dayStr, date1)
+          }
+        }
+
+        this.showCalender = true
+      })
+    },
+    handleCellClick(date, data) {
+      /* this.form.yearMonthDay = this.getYearMonthDay(date)
+      getCamRecordByDay(this.form).then(resp => {
+        if (resp.code === 0) {
+          this.showRecordList = true
+          this.recordList = resp.data
+        }
+      })*/
+    },
+    dealMyDate(val) {
+      let res = ''
+
+      /* this.potDate = [
+        { date: '2024-02-02', hasRecord: true },
+        { date: '2024-02-01', hasRecord: true }
+      ]
+      for (let i = 0; i < this.potDate.length; i++) {
+        if (this.potDate[i].date === val) {
+          res = this.potDate[i].hasRecord
+          break
+        }
+      }*/
+
+      if (this.dateMap.get(val) != null) {
+        res = true
+      }
+      return res
+    },
+    getYearMonth(date) {
+      const year = date.getFullYear().toString().padStart(4, '0')
+      const month = (date.getMonth() + 1).toString().padStart(2, '0')
+      // const day = date.getDate().toString().padStart(2, '0')
+      // const hour = date.getHours().toString().padStart(2, '0')
+      // const minute = date.getMinutes().toString().padStart(2, '0')
+      // const second = date.getSeconds().toString().padStart(2, '0')
+      // 2023-02-16 08:25:05
+      // console.log(`${year}-${month}-${day} ${hour}:${minute}:${second}`)
+      return year + '-' + month
+    },
+    getYearMonthDay(date) {
+      const year = date.getFullYear().toString().padStart(4, '0')
+      const month = (date.getMonth() + 1).toString().padStart(2, '0')
+      const day = date.getDate().toString().padStart(2, '0')
+      return year + '-' + month + '-' + day
+    },
+    initMp4Player(coverUrl, videoUrl) {
+      new DPlayer({
+        container: document.getElementById('dplayer'),
+        lang: 'zh-cn',
+        autoplay: true,
+        volume: 0.1,
+        mutex: true,
+        video: {
+          pic: coverUrl,
+          url: videoUrl,
+          hotkey: true
+        }
+      })
+    },
+    goToCamLive() {
+      const path = '/my/cam/live/' + this.camDetail.camId
+      if (this.$route.path === path) {
+        this.$router.go(0)
+        return
+      }
+      this.$router.push(path)
+    }
+  }
+}
+</script>
+
+<style scoped>
+/*处于手机屏幕时*/
+@media screen and (max-width: 768px) {
+  .movie-list {
+    padding-top: 8px;
+    padding-left: 0.5%;
+    padding-right: 0.5%;
+  }
+}
+
+.movie-list {
+  padding-top: 15px;
+  padding-left: 5%;
+  padding-right: 5%;
+}
+
+.clearfix:before,
+.clearfix:after {
+  display: table;
+  content: "";
+}
+
+.clearfix:after {
+  clear: both;
+}
+
+.budge{
+  width: 10px;
+  height: 10px;
+  border-radius: 5px;
+  margin: 10px auto;
+}
+.blue{
+  background-color: #409eff;
+}
+</style>

+ 18 - 27
src/views/post/CamList.vue

@@ -9,11 +9,9 @@
       >添加</el-button>
       <el-table
         :data="dataList"
-        border
         style="width: 100%"
       >
         <el-table-column
-          fixed="left"
           label="No"
           type="index"
         />
@@ -38,21 +36,16 @@
           label="状态"
         >
           <template slot-scope="scope">
-            <el-tag v-if="scope.row.state === 1" :type="'warning'" disable-transitions>
-              离线
-            </el-tag>
-            <el-tag v-else-if="scope.row.state === 2" :type="'success'" disable-transitions>
+            <el-tag v-if="scope.row.state" :type="'success'" disable-transitions>
               推流中
             </el-tag>
             <el-tag v-else :type="'danger'" disable-transitions>
-              未知状态
+              离线
             </el-tag>
           </template>
         </el-table-column>
         <el-table-column
-          fixed="right"
           label="操作"
-          width="320"
         >
           <template slot-scope="scope">
             <el-button
@@ -62,7 +55,7 @@
             <el-button
               size="mini"
               @click="handleDetail(scope.$index, scope.row)"
-            >详情</el-button>
+            >推流地址</el-button>
             <el-button
               size="mini"
               type="danger"
@@ -84,8 +77,11 @@
           </div>
           <div class="text item">
             <el-form ref="form" :model="addCamForm" label-width="80px">
-              <el-form-item label="名字">
-                <el-input v-model="addCamForm.name" />
+              <el-form-item label="设备 ID">
+                <el-input v-model="addCamForm.deviceId" />
+              </el-form-item>
+              <el-form-item label="设备名字">
+                <el-input v-model="addCamForm.deviceName" />
               </el-form-item>
               <el-form-item>
                 <el-button type="primary" @click="onAddCam">立即添加</el-button>
@@ -128,17 +124,10 @@
       >
         <el-card class="box-card">
           <div slot="header" class="clearfix">
-            <h3>摄像头详情</h3>
+            <h3>推流地址</h3>
           </div>
           <div class="text item">
-            <el-form v-if="camDetail" :model="camDetail" label-width="100px">
-              <el-form-item label="摄像头名字">
-                <span>{{ camDetail.camName }}</span>
-              </el-form-item>
-              <el-form-item label="推流地址">
-                <span>{{ camDetail.camName }}</span>
-              </el-form-item>
-            </el-form>
+            <h3>{{ pushUrl }}</h3>
           </div>
         </el-card>
       </el-dialog>
@@ -163,7 +152,7 @@
 import {
   getVideoResource
 } from '@/api/video'
-import { addCam, deleteCam, getCamDetail, getUserCams, updateCamName } from '@/api/cam'
+import { addCam, deleteCam, getCamPushUrl, getUserCams, updateCamName } from '@/api/cam'
 
 export default {
   name: 'CamList',
@@ -181,13 +170,14 @@ export default {
       showDetailDialog: false,
       videoResources: [],
       addCamForm: {
-        name: null
+        deviceId: null,
+        deviceName: null
       },
       updateNameForm: {
         camId: null,
         newName: null
       },
-      camDetail: null
+      pushUrl: null
     }
   },
   created() {
@@ -240,9 +230,9 @@ export default {
       this.showUpdateDialog = true
     },
     handleDetail(index, row) {
-      getCamDetail(row.camId).then(resp => {
+      getCamPushUrl(row.camId).then(resp => {
         if (resp.code === 0) {
-          this.camDetail = resp.data
+          this.pushUrl = resp.data
           this.showDetailDialog = true
         }
       })
@@ -276,7 +266,8 @@ export default {
       addCam(this.addCamForm).then(resp => {
         if (resp.code === 0) {
           this.addCamForm = {
-            name: null
+            deviceId: null,
+            deviceName: null
           }
           this.$notify({
             title: '提示',