xiaoxin 2 лет назад
Родитель
Сommit
24a093606f

+ 4 - 1
.env.development

@@ -2,4 +2,7 @@
 NODE_ENV = 'development'
 # VITE_APP_TITLE = '硅谷甄选运营平台'
 VITE_APP_BASE_API = '/smartApi'
-VITE_SERVE="https://www.campussmartlife.com/smartApi"
+VITE_APP_BASE_API_VIDEO = '/wzszlocalvideo'
+
+VITE_SERVE="https://www.campussmartlife.com/smartApi"
+VITE_SERVE_VIDEO="https://www.campussmartlife.com/wzszlocalvideo"

+ 4 - 1
.env.production

@@ -2,4 +2,7 @@
 NODE_ENV = 'production'
 # VITE_APP_TITLE = '硅谷甄选运营平台'
 VITE_APP_BASE_API = '/smartApi'
-VITE_SERVE="https://www.campussmartlife.com/smartApi"
+VITE_APP_BASE_API_VIDEO = '/wzszlocalvideo'
+
+VITE_SERVE="https://www.campussmartlife.com/smartApi"
+VITE_SERVE_VIDEO="https://www.campussmartlife.com/wzszlocalvideo"

+ 11 - 0
package-lock.json

@@ -14,6 +14,7 @@
         "crypto-js": "^4.2.0",
         "echarts": "^5.4.3",
         "element-plus": "^2.4.4",
+        "nprogress": "^0.2.0",
         "sass": "^1.69.6",
         "vue": "^3.4.21",
         "vue-router": "^4.2.5"
@@ -1603,6 +1604,11 @@
         "npm": ">= 8"
       }
     },
+    "node_modules/nprogress": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmmirror.com/nprogress/-/nprogress-0.2.0.tgz",
+      "integrity": "sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA=="
+    },
     "node_modules/parse-json": {
       "version": "7.1.1",
       "resolved": "https://registry.npmmirror.com/parse-json/-/parse-json-7.1.1.tgz",
@@ -3136,6 +3142,11 @@
         "shell-quote": "^1.7.3"
       }
     },
+    "nprogress": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmmirror.com/nprogress/-/nprogress-0.2.0.tgz",
+      "integrity": "sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA=="
+    },
     "parse-json": {
       "version": "7.1.1",
       "resolved": "https://registry.npmmirror.com/parse-json/-/parse-json-7.1.1.tgz",

+ 1 - 0
package.json

@@ -17,6 +17,7 @@
     "crypto-js": "^4.2.0",
     "echarts": "^5.4.3",
     "element-plus": "^2.4.4",
+    "nprogress": "^0.2.0",
     "sass": "^1.69.6",
     "vue": "^3.4.21",
     "vue-router": "^4.2.5"

+ 17 - 6
src/api/video/index.ts

@@ -5,22 +5,24 @@ enum API {
   VIDEOLOGIN_URL = "/av_ja/videoAdmin/login",
 
   // 获取监控列表数组
-  VIDEOLIST_URL = "/av_ja/videoSpot/list",
+  VIDEOLIST_URL = "/av_ja/camera/queryCameraRelationship",
 
   // 监控拉流
   VIDEOPULL_URL = "/av_ja/stream/addStreamSource",
+
+  // 监控关流
+  VIDEOSTOP_URL = "/av_ja/stream/delStreamSource",
 }
 
 //登录获取监控权限
 export const reqVideoLogin = (data: any) =>
-  request.post(API.VIDEOLOGIN_URL, data, { headers: { type: "local" } });
+  request.post(API.VIDEOLOGIN_URL, data, { headers: { type: "video" } });
 
 //获取监控列表数组
-export const reqVideoList = (params: any) =>
+export const reqVideoList = () =>
   request.get(API.VIDEOLIST_URL, {
-    params,
     headers: {
-      type: "local",
+      type: "video",
       admin_token: localStorage.getItem("admin_token"),
     },
   });
@@ -29,7 +31,16 @@ export const reqVideoList = (params: any) =>
 export const reqVideoPull = (data: any) =>
   request.post(API.VIDEOPULL_URL, data, {
     headers: {
-      type: "local",
+      type: "video",
+      admin_token: localStorage.getItem("admin_token"),
+    },
+  });
+
+//监控关流
+export const reqVideoStop = (data: any) =>
+  request.post(API.VIDEOSTOP_URL, data, {
+    headers: {
+      type: "video",
       admin_token: localStorage.getItem("admin_token"),
     },
   });

Разница между файлами не показана из-за своего большого размера
+ 1 - 1
src/components/school/schoolLeft.vue


+ 42 - 98
src/components/school/schoolRight.vue

@@ -80,12 +80,13 @@
       </div>
       <div class="video">
         <div class="video_box" v-for="(item, index) in videoList" :key="index">
-          <div class="box_mask">无信号</div>
-          <div
-            v-show="item.isShow"
+          <video
+            :src="item.url"
+            controls
+            muted
+            autoplay
             class="box_video"
-            :id="index + 'Watch'"
-          ></div>
+          ></video>
           <div class="box_name">{{ item.title }}</div>
         </div>
       </div>
@@ -99,10 +100,7 @@ import { useRouter } from "vue-router";
 import { countUpNum } from "@/utils/countUpNum";
 import { reqGetSmartWarning } from "@/api/school/index";
 // @ts-ignore
-import { reqVideoLogin } from "@/api/video/index";
-// @ts-ignore
-import WasmPlayer from "@easydarwin/easywasmplayer";
-import axios from "axios";
+import { reqVideoLogin, reqVideoPull, reqVideoStop } from "@/api/video/index";
 
 // 监控摄像头数据
 const deviceNum = ref(150);
@@ -121,7 +119,7 @@ const deviceDom3 = ref();
 const tableData = ref([]);
 
 // 路由器实例
-const router = useRouter();
+const $router = useRouter();
 
 // 当前页
 const currentPage = ref(1);
@@ -131,37 +129,27 @@ const pageCount = ref(10);
 // 监控列表
 const videoList = ref<any>([
   {
-    show: false,
     title: "大门口1",
-    url: "ws://172.16.7.203:8081/1ive/c70_1.1ive.flv",
-    timer: null,
+    url: "https://www.campussmartlife.com/wzszlocalvideozlm/live/c70_1.live.mp4",
+    d: "D70",
   },
   {
-    show: false,
     title: "大门口2",
-    url: "ws://172.16.7.203:8081/1ive/c68_1.1ive.flv",
-    timer: null,
+    url: "https://www.campussmartlife.com/wzszlocalvideozlm/live/c68_1.live.mp4",
+    d: "D68",
   },
   {
-    show: false,
     title: "前操场1",
-    url: "ws://172.16.7.203:8081/1ive/c118_1.1ive.flv",
-    timer: null,
+    url: "https://www.campussmartlife.com/wzszlocalvideozlm/live/c118_1.live.mp4",
+    d: "D118",
   },
   {
-    show: false,
     title: "前操场2",
-    url: "ws://172.16.7.203:8081/1ive/c120_1.1ive.flv",
-    timer: null,
+    url: "https://www.campussmartlife.com/wzszlocalvideozlm/live/c120_1.live.mp4",
+    d: "D120",
   },
 ]);
 
-// 延时器实例数组
-const timerList = ref<any>([]);
-
-// 监控实例数组
-const playerList = ref<any>([]);
-
 onMounted(() => {
   // 让数字动起来
   getCountUpNum();
@@ -170,17 +158,15 @@ onMounted(() => {
   getSmartWarning();
 
   // 登录获取监控权限
-  // getVideoLogin();
+  getVideoLogin();
 
-  // 初始化监控
+  // 拉流
   initVideo();
 });
 
 onUnmounted(() => {
-  // 销毁WasmPlayer实例
-  destroyVideos();
-  // 销毁延时器实例
-  destroyTimers();
+  // 关流
+  stopVideo();
 });
 
 // 获取预警推送信息
@@ -197,69 +183,40 @@ const getSmartWarning = async () => {
 
 // 登录获取监控权限
 const getVideoLogin = async () => {
-  console.log(111);
-
-  // const res = await reqVideoLogin({
-  //   username: "admin",
-  //   password: "admin.123456",
-  // });
-  // console.log(res);
-
-  // const res = await axios({
-  //   url: "http://172.16.7.203:8083/av_ja/videoAdmin/login",
-  //   method: "post",
-  //   data: {
-  //     username: "admin",
-  //     password: "admin.123456",
-  //   },
-  // });
+  const res = await reqVideoLogin({
+    username: "admin",
+    password: "admin.123456",
+  });
   // console.log(res);
+  localStorage.setItem("admin_token", res.data.token);
 };
 
+// 拉流
 const initVideo = () => {
-  videoList.value.forEach((ele: any, index: number) => {
-    let player = new WasmPlayer(null, index + "Watch", (a: any) => {
-      // a表示当前播放的状态
-      if (a === "videoTimestamp") {
-        ele.isShow = true;
-      } else {
-        // 开启一个延时10秒的延时器
-        if (!ele.timer) {
-          (ele.timer as any) = setTimeout(() => {
-            //  如果isShow为false表示播放失败,此时断开连接节约性能
-            if (!ele.isShow) {
-              player.destroy();
-            }
-
-            // 收集延时器实例方便后面销毁
-            timerList.value.push(ele.timer);
-          }, 10000);
-        }
-      }
+  videoList.value.forEach(async (ele: any) => {
+    await reqVideoPull({
+      d: ele.d,
+      nowLine: "1",
+      isNvr: "1",
     });
-    player.play(ele.url, 1);
-
-    // 收集监控实例方便后面销毁
-    playerList.value.push(player);
   });
 };
 
 // 查看更多按钮回调
 const handleCheckMore = () => {
-  router.push("/more");
-};
+  // 关流
+  stopVideo();
 
-// 销毁WasmPlayer实例
-const destroyVideos = () => {
-  playerList.value.forEach((ele: any) => {
-    ele.destroy();
-  });
+  $router.push("/more");
 };
 
-// 销毁延时器实例
-const destroyTimers = () => {
-  timerList.value.forEach((ele: any) => {
-    clearTimeout(ele);
+// 关流
+const stopVideo = () => {
+  videoList.value.forEach(async (ele: any) => {
+    await reqVideoStop({
+      d: ele.d,
+      nowLine: "1",
+    });
   });
 };
 
@@ -388,22 +345,9 @@ const getCountUpNum = () => {
         height: 134px;
         border-radius: 5px;
 
-        .box_mask {
-          position: absolute;
-          top: 0;
-          width: 100%;
-          height: 100%;
-          display: flex;
-          justify-content: center;
-          align-items: center;
-          font-size: 16px;
-          background-color: #000;
-        }
-
         .box_video {
           width: 198px;
           height: 134px;
-          background-color: rgba($color: #000000, $alpha: 0.3);
         }
 
         .box_name {
@@ -414,7 +358,7 @@ const getCountUpNum = () => {
           width: 100%;
           height: 30px;
           font-size: 16px;
-          background-color: rgba($color: #fff, $alpha: 0.1);
+          background-color: rgba($color: #000, $alpha: 0.5);
         }
       }
     }

+ 16 - 1
src/utils/request.ts

@@ -1,16 +1,30 @@
 import axios from "axios";
 import { ElMessage } from "element-plus";
+
+// @ts-ignore 进度条
+import NProgress from "nprogress";
+import "nprogress/nprogress.css";
+
 //引入用户相关的仓库
 // import useUserStore from '@/store/modules/user'
 
 //创建axios实例
 let request = axios.create({
-  baseURL: import.meta.env.VITE_APP_BASE_API,
+  // baseURL: import.meta.env.VITE_APP_BASE_API,
   timeout: 15000,
 });
 
 //请求拦截器
 request.interceptors.request.use((config) => {
+  NProgress.start();
+
+  // 判断接口公共路径
+  if (config.headers.type === "video") {
+    config.baseURL = import.meta.env.VITE_APP_BASE_API_VIDEO;
+  } else {
+    config.baseURL = import.meta.env.VITE_APP_BASE_API;
+  }
+
   let token = sessionStorage.getItem("WANZAI-TOKEN");
   if (token) {
     config.headers.token = token;
@@ -30,6 +44,7 @@ request.interceptors.request.use((config) => {
 //响应拦截器
 request.interceptors.response.use(
   (response) => {
+    NProgress.done();
     return response.data;
   },
   (error) => {

+ 103 - 62
src/views/more.vue

@@ -9,27 +9,35 @@
       <div class="content_left">
         <el-tree
           :data="dataSource"
-          node-key="id"
+          node-key="spotName"
           highlight-current
           accordion
+          :props="treeProps"
           @node-click="handleNodeClick"
         >
           <template #default="{ node, data }">
             <div class="left_tree">
-              <component
+              <!-- <component
                 :is="node.level === 1 ? 'FolderOpened' : ''"
                 style="width: 20px; height: 20px; color: #70b7fa"
-              />
-              <div class="tree_text">{{ node.label }}</div>
+              /> -->
+              <div class="tree_text">
+                {{ data.spotName || data.installationSite || "未知" }}
+              </div>
             </div>
           </template>
         </el-tree>
       </div>
       <!-- 监控展示区域 -->
       <div class="content_right">
-        <img
-          src="https://materials.cdn.bcebos.com/images/107505592/68889f5dbf4bd8d8ef0cd11f98b5adea.jpeg"
-        />
+        <div class="right_monitor">暂无监控</div>
+        <video
+          v-if="currentUrl"
+          controls
+          autoplay
+          muted
+          :src="currentUrl"
+        ></video>
       </div>
     </div>
 
@@ -39,64 +47,75 @@
 </template>
 
 <script setup lang="ts">
-import { ref } from "vue";
+import { ref, onMounted, onUnmounted } from "vue";
 import { useRouter } from "vue-router";
+import { reqVideoList, reqVideoPull, reqVideoStop } from "@/api/video/index";
 
+// 路由器实例
 const router = useRouter();
 
+// 当前监控地址
+const currentUrl = ref("");
+
+// 当前监控通道
+const currentD = ref("");
+
+const treeProps = {
+  label: "spotName",
+  children: "items",
+};
+
 // 树状结构数据
-const dataSource = ref([
-  {
-    id: 1,
-    label: "七年级",
-    icon: "FolderOpened",
-    children: [
-      {
-        id: 11,
-        label: "1班",
-      },
-      {
-        id: "1-2",
-        label: "2班",
-      },
-      {
-        id: "1-3",
-        label: "3班",
-      },
-      {
-        id: "1-4",
-        label: "4班",
-      },
-    ],
-  },
-  {
-    id: 2,
-    label: "八年级",
-    icon: "FolderOpened",
-    children: [
-      {
-        id: "2-1",
-        label: "1班",
-      },
-      {
-        id: "2-2",
-        label: "2班",
-      },
-      {
-        id: "2-3",
-        label: "3班",
-      },
-      {
-        id: "2-4",
-        label: "4班",
-      },
-    ],
-  },
-]);
+const dataSource = ref([]);
+
+onMounted(() => {
+  // 获取列表数据
+  getVideoList();
+});
+
+onUnmounted(() => {
+  if (currentD.value) {
+    // 关流请求
+    stopVideo();
+  }
+});
+
+// 获取列表数据
+const getVideoList = async () => {
+  const res = await reqVideoList();
+  // console.log(res);
+  dataSource.value = res.data;
+};
 
 // 点击树状结构每一个节点触发的回调
-const handleNodeClick = (data: any) => {
-  console.log(data);
+const handleNodeClick = async (data: any) => {
+  if (currentD.value) {
+    // 关流请求
+    stopVideo();
+  }
+  // console.log(data);
+  if (data.d) {
+    currentD.value = data.d;
+    // 监控拉流
+    const res = await reqVideoPull({
+      d: currentD.value,
+      nowLine: "1",
+      isNvr: "1",
+    });
+    // console.log(res);
+
+    currentUrl.value = res.data.mp4;
+  } else {
+    currentUrl.value = "";
+  }
+};
+
+// 关流请求
+const stopVideo = async () => {
+  await reqVideoStop({
+    d: currentD.value,
+    nowLine: "1",
+  });
 };
 
 // 点击关闭按钮回调
@@ -130,7 +149,7 @@ const handleClose = () => {
     height: 824px;
 
     .content_left {
-      width: 108px;
+      width: 200px;
       height: 100%;
 
       .left_tree {
@@ -150,13 +169,35 @@ const handleClose = () => {
     }
 
     .content_right {
-      width: 1689px;
+      position: relative;
+      width: 1597px;
       height: 100%;
 
-      img {
+      .right_monitor {
+        position: absolute;
+        top: 0;
+        width: 100%;
+        height: 100%;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        color: #fff;
+        font-size: 40px;
+        background-color: rgba($color: #000000, $alpha: 1);
+      }
+
+      .monitor_box {
+        position: absolute;
+        top: 0;
+        width: 100%;
+        height: 100%;
+      }
+
+      video {
+        position: absolute;
+        top: 0;
         width: 100%;
         height: 100%;
-        object-fit: cover;
       }
     }
   }

+ 8 - 0
vite.config.ts

@@ -26,6 +26,14 @@ export default defineConfig(({ mode }) => {
           //路径重写
           rewrite: (path) => path.replace(/^\/smartApi/, ""),
         },
+        [env.VITE_APP_BASE_API_VIDEO]: {
+          //获取数据的服务器地址设置
+          target: env.VITE_SERVE_VIDEO,
+          //需要代理跨域
+          changeOrigin: true,
+          //路径重写
+          rewrite: (path) => path.replace(/^\/wzszlocalvideo/, ""),
+        },
       },
     },
   };