From 7542bd196bce01c59bf4899988dbfe0657860b85 Mon Sep 17 00:00:00 2001 From: cwchen <1048842385@qq.com> Date: Wed, 4 Feb 2026 16:19:44 +0800 Subject: [PATCH] =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E6=96=87=E4=BB=B6=E8=B7=AF?= =?UTF-8?q?=E5=BE=84=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.production | 5 +- src/router/index.js | 8 +- .../ExportProgress.vue | 0 .../config.js | 0 .../index.vue | 0 .../ExportProgress.vue | 0 .../index.vue | 0 src/views/device/video/index.vue | 99 ++++++++++++++++--- vue.config.js | 2 +- 9 files changed, 93 insertions(+), 21 deletions(-) rename src/views/device/{data-recognition => dataRecognition}/ExportProgress.vue (100%) rename src/views/device/{data-recognition => dataRecognition}/config.js (100%) rename src/views/device/{data-recognition => dataRecognition}/index.vue (100%) rename src/views/device/{image-recognition => imageRecognition}/ExportProgress.vue (100%) rename src/views/device/{image-recognition => imageRecognition}/index.vue (100%) diff --git a/.env.production b/.env.production index 8d7ad00..2ff3901 100644 --- a/.env.production +++ b/.env.production @@ -6,7 +6,10 @@ ENV = 'production' VUE_APP_ENV = 'production' VUE_APP_ONLYOFFICE_URL = 'http://36.33.26.201:19840' # 图片预览路径 -VUE_APP_FILE_URL = 'http://192.168.0.108:8099/smartCar/profile' +VUE_APP_FILE_URL = 'http://36.33.26.201:18088/profile' + +#视频流路径 +VUE_APP_VIDEO_URL = 'http://36.33.26.201:18088/processed' # 车辆道路监测系统/生产环境 VUE_APP_BASE_API = '/smart-car-api' diff --git a/src/router/index.js b/src/router/index.js index 1600cca..25f8a64 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -89,13 +89,13 @@ export const constantRoutes = [ ] }, { - path: '/device/image-recognition/export-progress', - component: () => import('@/views/device/image-recognition/ExportProgress'), + path: '/device/imageRecognition/export-progress', + component: () => import('@/views/device/imageRecognition/ExportProgress'), hidden: true }, { - path: '/device/data-recognition/export-progress', - component: () => import('@/views/device/data-recognition/ExportProgress'), + path: '/device/dataRecognition/export-progress', + component: () => import('@/views/device/dataRecognition/ExportProgress'), hidden: true } ] diff --git a/src/views/device/data-recognition/ExportProgress.vue b/src/views/device/dataRecognition/ExportProgress.vue similarity index 100% rename from src/views/device/data-recognition/ExportProgress.vue rename to src/views/device/dataRecognition/ExportProgress.vue diff --git a/src/views/device/data-recognition/config.js b/src/views/device/dataRecognition/config.js similarity index 100% rename from src/views/device/data-recognition/config.js rename to src/views/device/dataRecognition/config.js diff --git a/src/views/device/data-recognition/index.vue b/src/views/device/dataRecognition/index.vue similarity index 100% rename from src/views/device/data-recognition/index.vue rename to src/views/device/dataRecognition/index.vue diff --git a/src/views/device/image-recognition/ExportProgress.vue b/src/views/device/imageRecognition/ExportProgress.vue similarity index 100% rename from src/views/device/image-recognition/ExportProgress.vue rename to src/views/device/imageRecognition/ExportProgress.vue diff --git a/src/views/device/image-recognition/index.vue b/src/views/device/imageRecognition/index.vue similarity index 100% rename from src/views/device/image-recognition/index.vue rename to src/views/device/imageRecognition/index.vue diff --git a/src/views/device/video/index.vue b/src/views/device/video/index.vue index 658f403..7a64338 100644 --- a/src/views/device/video/index.vue +++ b/src/views/device/video/index.vue @@ -77,7 +77,7 @@
- @@ -201,6 +201,50 @@ export default { document.removeEventListener('MSFullscreenChange', this.onFullscreenChange) }, methods: { + async startWhelpPlay() { + // 1. 创建 PeerConnection + const pc = new RTCPeerConnection({ + iceServers: [{ urls: 'stun:stun.l.google.com:19302' }] // 公网 STUN 服务器 + }); + + // 2. 拿到流就放到 video 标签里 + pc.ontrack = (event) => { + document.getElementById('myVideo').srcObject = event.streams[0]; + }; + + // 3. 这里的 addTransceiver 是告诉浏览器“我要接收视频和音频” + pc.addTransceiver('video', { direction: 'recvonly' }); + pc.addTransceiver('audio', { direction: 'recvonly' }); + + // 4. 创建 Offer + const offer = await pc.createOffer(); + await pc.setLocalDescription(offer); + + // 5. 【关键】向您的那个地址发送请求 + // 注意:这里是 POST 请求,内容是 SDP + + const response = await fetch(`${process.env.VUE_APP_VIDEO_URL}/whep`, { + method: 'POST', + headers: { + 'Content-Type': 'application/sdp' + }, + body: offer.sdp + }); + + if (response.status !== 201) { + console.error("连接失败"); + return; + } + + // 6. 拿到 Answer 并设置 + const answerSdp = await response.text(); + await pc.setRemoteDescription(new RTCSessionDescription({ + type: 'answer', + sdp: answerSdp + })); + + console.log("WHEP 握手成功,等待视频流..."); + }, /** 初始化 ResizeObserver */ initResizeObserver() { const container = this.$refs.videoContainer @@ -604,16 +648,19 @@ export default { async loadVideoStream() { try { - const res = await getVideoStreamAPI() + const res = await getVideoStreamAPI() if (res.code === 200 && res.data && res.data.streamUrl) { this.videoErrorShown = false this.videoUrl = res.data.streamUrl } + /*this.startWhelpPlay();*/ } catch (error) { console.error('获取视频流失败:', error) } }, + + /** 位置锁定 */ async handleLockPosition() { this.$confirm('确定要锁定设备位置吗?', '位置锁定', { @@ -1048,33 +1095,41 @@ video::-internal-media-controls-download-button { .status-indicator { display: inline-flex; align-items: center; - padding: 6px 14px; /* 稍微加宽一点 */ + padding: 6px 14px; + /* 稍微加宽一点 */ border-radius: 20px; font-size: 14px; font-weight: 600; line-height: 1; transition: all 0.3s ease; - + /* 核心修改:圆点变大,不再依赖文字颜色 */ &::before { content: ''; display: inline-block; - width: 10px; /* 增大尺寸 */ - height: 10px; /* 增大尺寸 */ + width: 10px; + /* 增大尺寸 */ + height: 10px; + /* 增大尺寸 */ border-radius: 50%; margin-right: 8px; - flex-shrink: 0; /* 防止圆点被挤压 */ + flex-shrink: 0; + /* 防止圆点被挤压 */ } /* 在线:高亮绿 + 强力扩散动画 */ &.online { - background-color: #e1f3d8; /* 浅绿背景 */ - color: #67c23a; /* 绿色文字 */ + background-color: #e1f3d8; + /* 浅绿背景 */ + color: #67c23a; + /* 绿色文字 */ border: 1px solid #c2e7b0; &::before { - background-color: #529b2e; /* 圆点颜色比文字更深,更实 */ - box-shadow: 0 0 0 0 rgba(82, 155, 46, 0.7); /* 初始阴影 */ + background-color: #529b2e; + /* 圆点颜色比文字更深,更实 */ + box-shadow: 0 0 0 0 rgba(82, 155, 46, 0.7); + /* 初始阴影 */ animation: deep-pulse 1.5s infinite cubic-bezier(0.66, 0, 0, 1); } } @@ -1095,7 +1150,10 @@ video::-internal-media-controls-download-button { background-color: #fdf6ec; color: #e6a23c; border: 1px solid #f5dab1; - &::before { background-color: #e6a23c; } + + &::before { + background-color: #e6a23c; + } } /* 升级中 */ @@ -1103,6 +1161,7 @@ video::-internal-media-controls-download-button { background-color: #ecf5ff; color: #409eff; border: 1px solid #d9ecff; + &::before { background-color: #409eff; animation: blink 1s infinite; @@ -1115,16 +1174,26 @@ video::-internal-media-controls-download-button { 0% { box-shadow: 0 0 0 0 rgba(82, 155, 46, 0.7); } + 70% { - box-shadow: 0 0 0 8px rgba(82, 155, 46, 0); /* 扩散范围更大 */ + box-shadow: 0 0 0 8px rgba(82, 155, 46, 0); + /* 扩散范围更大 */ } + 100% { box-shadow: 0 0 0 0 rgba(82, 155, 46, 0); } } @keyframes blink { - 0%, 100% { opacity: 1; } - 50% { opacity: 0.5; } + + 0%, + 100% { + opacity: 1; + } + + 50% { + opacity: 0.5; + } } \ No newline at end of file diff --git a/vue.config.js b/vue.config.js index 617417e..8202222 100644 --- a/vue.config.js +++ b/vue.config.js @@ -11,7 +11,7 @@ const CopyWebpackPlugin = require('copy-webpack-plugin') const name = process.env.VUE_APP_TITLE || '车辆道路监测系统' // 网页标题 // const baseUrl = 'http://localhost:8080' // 后端接口 -const baseUrl = 'http://192.168.0.39:8080' +const baseUrl = 'http://192.168.0.108:8099' // const baseUrl = 'http://192.168.31.169:8080' const port = process.env.port || process.env.npm_config_port || 80 // 端口