huangyan 7 months ago
parent
commit
6ac3bb1ba4

+ 2 - 0
index.html

@@ -30,4 +30,6 @@
 </body>
 <script type="text/javascript" src="/public/jessibuca/jessibuca.js"></script>
 <script type="text/javascript" src="/src/H5player/bin/h5player.min.js"></script>
+<script type="text/javascript" src="/src/webrtc/webrtcstreamer.js"></script>
+<script type="text/javascript" src="/src/webrtc/adapter.min.js"></script>
 </html>

+ 2 - 1
src/api/api.ts

@@ -7,6 +7,7 @@ import UtilVar from "../config/UtilVar";
 import { ElMessage } from "element-plus";
 import router from "@/router";
 let baseUrl = UtilVar.baseUrl;
+// let baseUrl = "/api";
 const CancelToken = axios.CancelToken;
 
 export { baseUrl };
@@ -63,7 +64,7 @@ axios.interceptors.response.use(
     return Promise.resolve(response);
   },
   (error: any) => {
-    console.log("error", error);
+    console.log("=====================================================================================", error);
     let err = {
       success: false,
       msg: "未知异常,请联系管理员!",

+ 13 - 0
src/api/modules/External_interfaces.ts

@@ -0,0 +1,13 @@
+import { GET, POST, PUT } from "../api";
+
+// 定义登录URLs
+const archivesUrl = {
+    'archives': '/archives', 
+};
+
+
+export const GetArchives = (param: any = {}) => {
+    return GET(archivesUrl.archives,param);
+};
+
+export { archivesUrl };

BIN
src/assets/img/test.gif


+ 1 - 1
src/config/UtilVar.ts

@@ -7,7 +7,7 @@ interface UtilVarType {
 
 const UtilVar:UtilVarType = {
     baseUrl:"",
-    code:1002 | 1001, //登陆过期
+    code:1002, //登陆过期
     noContentCode:204, //请求成功但没有内容
     ENC:false,
 

+ 0 - 23
src/utils/External_interfaces.ts

@@ -1,23 +0,0 @@
-
-import axios from 'axios';
-import { ElMessage } from "element-plus";
-
-const statistics = () => {
-    const appId = '1686846386279535435';
-    const secret = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDDvv8hgUuIzp7WdTS5zHQPt9bOytMNRY+s1MBCbLp6C2sz9kg+agQ/cMqztYgwjlYqETyUTiu/uuF0y71VHtfazip6eYI++EHqBCNgmgGBkdyV5EyiSBC+RsJ0tX+oCFFtIIlYzIwgserkZyVKrSF61OieQj+C2rqbJBZq5svXlwIDAQAB';
-    
-    return axios.post('http://45.251.93.106:8082/api/statistics', { appId, secret })
-      .then((response) => {
-        if (response.data.code === 200) {
-            // console.log("测试:",response.data.result);
-            return response.data.result;
-        } else {
-          ElMessage.error(response.data.message);
-        }
-      })
-      .catch((error) => {
-        ElMessage.error(error);
-      });
-      
-};
-export default statistics;

+ 1 - 1
src/views/index/archives.vue

@@ -1,7 +1,7 @@
 <template>
       <n-button strong secondary type="info" size="large" @click="$router.push('/')" class="back-home-btn">返回首页</n-button>
     <ItemWrap class="adduser-items" title="档案管理">
-        <iframe src="http://45.251.93.106:8082/index.html" id="mobsf"></iframe>
+        <iframe src="http://127.0.0.1:8082/docm-boot/index.html" id="mobsf"></iframe>
     </ItemWrap>
 </template>
  

+ 33 - 1
src/views/index/index.vue

@@ -21,7 +21,14 @@
     <div class="contetn_centerbottom">
       <ItemWrap class="contetn_center-bottom contetn_lr-item" title="视频监控">
         <!-- <CenterBottom /> -->
-         <Monitor></Monitor>
+<!--         <Monitor></Monitor>-->
+        <!-- <webrtc class="monitor" :streamurl="stream_url"></webrtc> -->
+        <!-- <webrtc class="monitor" style="width: 400px;height: 950px;" :streamurl="stream_url"></webrtc> -->
+         <div class="monitor-container">
+        <div class="monitor"  v-for="(stream, index) in stream_url">
+          <webrtc :key="stream.id" :streamurl="stream.url" :videoId="'video-' + index"></webrtc>
+        </div>
+      </div>
       </ItemWrap>
     </div>
     <div class="contetn_bottom" id="contetn_bottom">
@@ -154,13 +161,27 @@ import LeftBottom from "./left-bottom.vue";
 import RightTop from "./right-top.vue";
 import RightCenter from "./right-center.vue";
 import RightBottom from "./right-bottom.vue";
+import webrtc from './webrtc.vue';
 import { NIcon } from "naive-ui";
 import Iot3d from "./iot3d.vue";
 import { onBeforeRouteLeave } from 'vue-router';
 import WebH5 from './webH5.vue';
 import Monitor from './monitor.vue';
+import { id } from 'element-plus/es/locale';
 const shouldShowComponent = ref(true);
 
+let stream_url = ref([
+  {id:1,url:'rtsp://admin:jxzs12345@192.168.1.3:554/h264/ch1/main/av_stream'},
+  {id:2,url:'rtsp://admin:jxzs12345@192.168.1.7:554/h264/ch1/main/av_stream'},
+  {id:3,url:'rtsp://admin:jxzs12345@192.168.1.7:554/h264/ch1/main/av_stream'},
+  {id:4,url:'rtsp://admin:jxzs12345@192.168.1.7:554/h264/ch1/main/av_stream'},
+  {id:5,url:'rtsp://admin:jxzs12345@192.168.1.7:554/h264/ch1/main/av_stream'},
+  {id:6,url:'rtsp://admin:jxzs12345@192.168.1.7:554/h264/ch1/main/av_stream'},
+  {id:7,url:'rtsp://admin:jxzs12345@192.168.1.7:554/h264/ch1/main/av_stream'},
+  {id:8,url:'rtsp://admin:jxzs12345@192.168.1.7:554/h264/ch1/main/av_stream'},
+]);
+
+
 
 onBeforeRouteLeave((to, from, next) => {
   shouldShowComponent.value = false;
@@ -252,4 +273,15 @@ onBeforeRouteLeave((to, from, next) => {
 .index-box{
   z-index: 1000000 !important;
 }
+.monitor{
+  margin-left: 10px;
+  width: 50% !important;
+  height: 100% !important;
+  // border: #ffea00 solid 1px;
+}
+.monitor-container{
+  width: 100% !important;
+  height: 100% !important;
+  display: flex;
+}
 </style>

+ 21 - 34
src/views/index/left-center.vue

@@ -3,8 +3,7 @@ import { ref, reactive } from "vue";
 import { graphic } from "echarts/core";
 import { countUserNum } from "@/api";
 import { ElMessage } from "element-plus"
-import axios from 'axios';
-import statistics from "@/utils/External_interfaces";
+import { GetArchives } from "@/api/modules/External_interfaces";
 let colors = ["#0BFC7F", "#A0A0A0", "#F48C02", "#F4023C"];
 const option = ref({});
 const state = reactive({
@@ -15,7 +14,7 @@ const state = reactive({
   totalNum: 0,
 });
 
-const states = reactive({
+let states = reactive({
   qzCount: 0, //全宗数
   qsCount: 0,//卷数
   jsCount: 0,//件数
@@ -32,44 +31,31 @@ const echartsGraphic = (colors: string[]) => {
     { offset: 1, color: colors[1] },
   ]);
 };
-const getData = () => {
-  countUserNum().then((res) => {
-    console.log("左中--用户总览", res);
-    if (res.success) {
-      state.lockNum = res.data.lockNum;
-      state.offlineNum = res.data.offlineNum;
-      state.onlineNum = res.data.onlineNum;
-      state.totalNum = res.data.totalNum;
-      state.alarmNum = res.data.alarmNum;
-      setOption();
-    } else {
-      ElMessage.error(res.msg)
+function getData(){
+  GetArchives().then(res => {
+    console.log('左上--设备总览', res);
+    if (res.code === 200) {
+    states.qzCount = res.data.ckNum;
+    states.qsCount = res.data.ckNum;
+    states.jsCount = res.data.ckNum;
+    states.dzdaCount = res.data.ckNum;
+    states.yjCount = res.data.ckNum;
+    states.cqqsCount = res.data.ckNum;
+    states.cqjsCount = res.data.ckNum;
+    states.queryCount = res.data.ckNum;
+    states.fileCount = res.data.ckNum;
     }
-  }).catch(err => {
-    ElMessage.error(err)
-  });
-};
-// getData();
-
-statistics().then(res => {
-  console.log('左中--设备总览', res);
-    states.qzCount = res.data.result.qzCount;
-    states.qsCount = res.data.result.qsCount;
-    states.jsCount = res.data.result.jsCount;
-    states.dzdaCount = res.data.result.dzdaCount;
-    states.yjCount = res.data.result.yjCount;
-    states.cqqsCount = res.data.result.cqqsCount;
-    states.cqjsCount = res.data.result.cqjsCount;
-    states.queryCount = res.data.result.queryCount;
-    states.fileCount = res.data.result.fileCount;
-})
+    
+  })
+}
+getData()
 
 const setOption = () => {
   option.value = {
     title: {
       top: "center",
       left: "center",
-      text: [`{value|${states.fileCount}}`, "{name|总数}"].join("\n"),
+      text: [`{value|${states.qzCount}}`, "{name|总数}"].join("\n"),
       textStyle: {
         rich: {
           value: {
@@ -176,6 +162,7 @@ const setOption = () => {
     ],
   };
 };
+setOption();
 </script>
 
 <template>

+ 14 - 9
src/views/index/left-top.vue

@@ -4,8 +4,7 @@ import { countDeviceNum } from "@/api";
 import CountUp from "@/components/count-up";
 import {ElMessage} from "element-plus"
 import axios from 'axios';
-import statistics from "@/utils/External_interfaces";
-
+import { GetArchives } from "@/api/modules/External_interfaces";
 const duration = ref(2);
 const state = reactive({
   alarmNum: 0,
@@ -31,14 +30,20 @@ const state = reactive({
 //   });;
 // };
 // getData();
-
-statistics().then(res => {
+function getData(){
+  GetArchives().then(res => {
     console.log('左上--设备总览', res);
-    state.alarmNum = res.ckNum;
-    state.offlineNum = res.ckNum;
-    state.onlineNum = res.drkNum;
-    state.totalNum = res.dckNum;
-})
+    if (res.code === 200) {
+      state.alarmNum = res.data.ckNum;
+      state.offlineNum = res.data.ckNum;
+      state.onlineNum = res.data.drkNum;
+      state.totalNum = res.data.dckNum;
+    }
+    
+  })
+}
+getData()
+
 
 </script>
 

+ 17 - 106
src/views/index/monitor.vue

@@ -1,111 +1,22 @@
 <template>
-  <div>
-    <div :id="preId" ref="playerContainer"></div>
+  <div class="video-container">
+    <webrtc v-for="n in 8" :key="n" style="width: 50%; height: 50%; border: 5px; scro" :streamurl="stream_url"></webrtc>
   </div>
 </template>
 
 <script setup>
-import { ref, onMounted, nextTick } from 'vue';
-
-const props = defineProps({
-  preUrl: {
-    type: String,
-    required: true,
-  },
-  preId: {
-    type: String,
-    required: true,
-  },
-});
-
-const playerContainer = ref(null);
-const player = ref(null);
-
-onMounted(() => {
-  nextTick(() => {
-    initPlayer();
-  });
-});
-
-/**
- * 初始化播放器
- */
-const initPlayer = () => {
-  player.value = new window.JSPlugin({
-    // 需要英文字母开头 必填
-    szId: props.preId,
-    // 必填,引用H5player.min.js的js相对路径
-    szBasePath: './dist/h5player.min.js', // 路径需要根据实际情况调整
-    // 分屏播放,默认最大分屏4*4
-    iMaxSplit: 4,
-    iCurrentSplit: 1,
-  });
-
-  initPlugin();
-};
-
-/**
- * 事件初始化
- */
-const initPlugin = () => {
-  player.value.JS_SetWindowControl(playerContainer.value);
-
-  player.value.JS_SetWindowControlCallback({
-    windowEventSelect(iWindIndex) {
-      // 插件选中窗口回调
-      console.log('windowSelect callback: ', iWindIndex);
-    },
-    pluginErrorHandler(iWindIndex, iErrorCode, oError) {
-      // 插件错误回调
-      console.error(`window-${iWindIndex}, errorCode: ${iErrorCode}`, oError);
-    },
-    windowEventOver(iWindIndex) {
-      // 鼠标移过回调
-      console.log('鼠标移过回调', iWindIndex);
-    },
-    windowEventOut(iWindIndex) {
-      // 鼠标移出回调
-      console.log('鼠标移出回调', iWindIndex);
-    },
-    windowFullCreenChange(bFull) {
-      // 全屏切换回调
-      console.log('全屏切换回调', bFull);
-    },
-    firstFrameDisplay(iWndIndex, iWidth, iHeight) {
-      // 首帧显示回调
-      console.log('首帧显示回调', iWndIndex, iWidth, iHeight);
-    },
-    performanceLack(iWndIndex) {
-      // 性能不足回调
-      console.log('性能不足回调', iWndIndex);
-    },
-  });
-
-  play();
-};
-
-/**
- * 播放
- */
-const play = () => {
-  const preUrl = props.preUrl; // 播放地址
-  const param = {
-    playURL: preUrl,
-    // 1:高级模式  0:普通模式,高级模式支持所有
-    mode: 1,
-  };
-
-  // 当前播放窗口下标
-  let index = 0;
-
-  player.value.JS_Play(preUrl, param, index, null, null)
-    .then(() => {
-      // 播放成功回调
-      console.log('播放成功');
-    })
-    .catch((err) => {
-      console.log('播放失败');
-      console.info('JS_Play failed:', err);
-    });
-};
-</script>
+import webrtc from "@/views/index/webrtc.vue";
+import { ref } from "vue";
+
+const stream_url = ref('rtsp://admin:jxzs12345@192.168.1.4:554/h264/ch1/main/av_stream');
+</script>
+
+<style scoped>
+.video-container {
+  display: grid;
+  grid-template-columns: repeat(2, 1fr);
+  grid-template-rows: repeat(2, 1fr);
+  height: 100vh;
+  width: 100vw;
+}
+</style>

+ 18 - 18
src/views/index/right-center.vue

@@ -29,24 +29,24 @@ const config = ref({
   unit: "次",
 });
 const data = ref([]);
-const getData = () => {
-  ranking()
-    .then((res) => {
-      console.log("右中--报警排名", res);
-      if (res.success) {
-        data.value = res.data;
-      } else {
-        ElMessage({
-          message: res.msg,
-          type: "warning",
-        });
-      }
-    })
-    .catch((err) => {
-      ElMessage.error(err);
-    });
-};
-getData();
+// const getData = () => {
+//   ranking()
+//     .then((res) => {
+//       console.log("右中--报警排名", res);
+//       if (res.success) {
+//         data.value = res.data;
+//       } else {
+//         ElMessage({
+//           message: res.msg,
+//           type: "warning",
+//         });
+//       }
+//     })
+//     .catch((err) => {
+//       ElMessage.error(err);
+//     });
+// };
+// getData();
 </script>
 <style scoped lang="scss">
 .user_Overview_image {

+ 67 - 35
src/views/index/webH5.vue

@@ -1,50 +1,82 @@
 <template>
-      <n-button strong secondary type="info" size="large" @click="$router.push('/')" class="back-home-btn">返回首页</n-button>
-    <ItemWrap class="contetn_lr-item" title="实时监控">
-  <div class="video" ref="videoTest">
-    <test-web-h-5 :preId="preId1" ref="h5Player1" />
-    <test-web-h-5 :preId="preId2" ref="h5Player2" />
-    <el-button type="primary" @click="handlePlay('1')">播放视频一</el-button>
-    <el-button type="primary" @click="handlePlay('2')">播放视频二</el-button>
-  </div>
-</ItemWrap>
+  <n-button strong secondary type="info" size="large" @click="$router.push('/')" class="back-home-btn">返回首页</n-button>
+  <n-button strong secondary type="info" size="large" @click="changeLayout(1)" class="btn">1x1</n-button>
+  <n-button strong secondary type="info" size="large" @click="changeLayout(2)" class="btn">2x2</n-button>
+  <n-button strong secondary type="info" size="large" @click="changeLayout(3)" class="btn">3x3</n-button>
+  <ItemWrap class="contetn_lr-item" title="实时监控">
+    <div class="grid-container">
+
+      <div class="grid" :style="{ gridTemplateColumns: `repeat(${cols}, 1fr)` }">
+        <div v-for="n in cols * cols" :key="n"  class="cell">
+          <webrtc :streamurl="stream_url" ></webrtc>
+        </div>
+      </div>
+    </div>
+  </ItemWrap>
 </template>
 
 <script lang="ts" setup>
-import { ref ,onMounted} from 'vue';
+import { ref, onMounted } from 'vue';
 import TestWebH5 from './monitor.vue';
 import ItemWrap from '@/components/item-wrap/item-wrap.vue';
 
-const preId1 = ref('player');
-const preId2 = ref('player2');
-
-const h5Player1 = ref(null);
-const h5Player2 = ref(null);
+const cols = ref(3); // 初始为3列
+let stream_url = ref([
+  {id:1,url:'rtsp://admin:jxzs12345@192.168.1.3:554/h264/ch1/main/av_stream'},
+  {id:2,url:'rtsp://admin:jxzs12345@192.168.1.7:554/h264/ch1/main/av_stream'},
+  {id:3,url:'rtsp://admin:jxzs12345@192.168.1.7:554/h264/ch1/main/av_stream'},
+  {id:4,url:'rtsp://admin:jxzs12345@192.168.1.7:554/h264/ch1/main/av_stream'},
+  {id:5,url:'rtsp://admin:jxzs12345@192.168.1.7:554/h264/ch1/main/av_stream'},
+  {id:6,url:'rtsp://admin:jxzs12345@192.168.1.7:554/h264/ch1/main/av_stream'},
+  {id:7,url:'rtsp://admin:jxzs12345@192.168.1.7:554/h264/ch1/main/av_stream'},
+  {id:8,url:'rtsp://admin:jxzs12345@192.168.1.7:554/h264/ch1/main/av_stream'},
+  {id:9,url:'rtsp://admin:jxzs12345@192.168.1.7:554/h264/ch1/main/av_stream'},
+]);
+const changeLayout = (newCols: number) => {
+  cols.value = newCols;
+};
+</script>
 
-function handlePlay(val: string) {
-    (h5Player1.value as any).play("https://sf1-cdn-tos.huoshanstatic.com/obj/media-fe/xgplayer_doc_video/mp4/xgplayer-demo-360p.mp4");
-    (h5Player2.value as any).play("ws://视频二地址");
+<style scoped>
+.grid-container {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  /* 设置全屏 */
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
 }
-onMounted(()=>{
-  console.log(h5Player1.value);
-  
-})
-</script>
 
-<style scoped lang="scss">
-.video {
+.grid {
+  display: grid;
+  gap: 10px;
+  margin-top: 20px;
+  /* 占据全屏宽度 */
   width: 100%;
-  height: 100%;
+  /* 自适应高度 */
+  height: calc(100% - 20px);
 }
-.contetn_lr-item{
-    height: 1000px;
-    font-size: 25px;
+
+.contetn_lr-item {
+  font-size: 25px;
+  height: 900px;
 }
-.back-home-btn {
-  position: absolute;
-  margin-top: 30px;
-  top: 10px;
-  left: 10px;
+.btn{
+  align-items: center;
+  /* display: flex; */
+  justify-content: center;
+  margin-left: 10px;
+}
+.cell {
+  /* 移除固定宽度 */
+  width: auto;
+  height: 100%;
+  /* 单元格高度自适应 */
+  padding: 10px;
+  text-align: center;
+  border: 1px solid #fff700;
 }
-
 </style>

+ 51 - 8
src/views/index/webrtc.vue

@@ -1,11 +1,54 @@
-<script setup lang="ts">
-
-</script>
-
 <template>
-  $END$
+  <div>
+    <video :id="videoId" autoplay></video>
+  </div>
 </template>
 
-<style scoped lang="scss">
-
-</style>
+<script>
+export default {
+  name: 'webrtc',
+  props: {
+    streamurl: {
+      type: String,
+      required: true
+    },
+    videoId: {
+      type: String,
+      default: 'video'
+    },
+    width: {
+      type: Number,
+      default: 900
+    },
+    height: {
+      type: Number,
+      default: 1200
+    }
+  },
+  data() {
+    return {
+      webRtcServer: null
+    }
+  },
+  mounted() {
+    this.webRtcServer = new WebRtcStreamer(this.videoId, location.protocol + '//127.0.0.1:8000')
+    console.log("this.streamurl in mounted:======================================", this.streamurl); // 打印组件中的值
+    this.webRtcServer.connect(this.streamurl)
+    const videoElement = document.getElementById(this.videoId);
+    if (videoElement) {
+      videoElement.play().catch(error => {
+      console.error('Error playing video:', error);
+    });
+  }
+  },
+  beforeDestroy() {
+    this.webRtcServer.disconnect()
+    this.webRtcServer = null
+  },
+  methods: {
+    updateStreamUrl(newUrl) {
+      this.webRtcServer.connect(newUrl)
+    }
+  }
+}
+</script>

+ 1 - 1
vite.config.ts

@@ -28,7 +28,7 @@ export default defineConfig(({ command, mode }: ConfigEnv): UserConfig => {
     base: "./",
     server: {
       host: '0.0.0.0',
-      port: 8112,
+      port: 8888,
       open: false,
       strictPort: false,
       // proxy: {}